/** 通讯线平时空闲时处于低电平,由一个100MS的高电平作为引导码来唤醒从机。然后发送一个字节串行数据。完毕后通讯线恢复到空闲状态的低电平。 对于从机来说,接受完8位数据,或检测到一个连续5t的低电平(结束码)即可认为通讯结束。 在引导码之后,数据码之前,增加一位波特率校准位。该校准位由一个低电平和高电平构成,低电平和高电平分别 =1t。在从机被唤醒后,检测到引导码结束后,先 对校准位进行时间测量。为后续数据码的识别提供标准时间(“t”值)。 数据码共8位(低位bit0先发);每位数据码由一个低电平和一个高电平组成;低电平时间固定=1t;高电平时间=1t代表逻辑‘0’,=3t代表逻辑‘1’; 结束码为一个持续时间 >= 5t的低电平。检测到结束码后通讯结束。 */ /*Includes ----------------------------------------------*/ #include "tool.h" #include "bsp_pwm.h" #include "fml_single_line_simplex.h" /*Private macro ------------------------------------------------*/ #define FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_OUTPUT do \ { \ nrfx_gpiote_out_uninit(FML_SINGLE_LINE_SIMPLEX_PIN); \ nrfx_gpiote_in_uninit(FML_SINGLE_LINE_SIMPLEX_PIN); \ nrfx_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(0); \ APP_ERROR_CHECK(nrfx_gpiote_out_init(FML_SINGLE_LINE_SIMPLEX_PIN, &out_config)); \ nrf_gpio_cfg_watcher(FML_SINGLE_LINE_SIMPLEX_PIN); \ }while(0) //配置引脚为输出,且初始化为低电平 #define FML_SINGLE_LINE_SIMPLEX_SET_PIN nrfx_gpiote_out_set(FML_SINGLE_LINE_SIMPLEX_PIN) //设置IO引脚高电平 #define FML_SINGLE_LINE_SIMPLEX_CLEAR_PIN nrfx_gpiote_out_clear(FML_SINGLE_LINE_SIMPLEX_PIN) //设置IO引脚低电平 #define FML_SINGLE_LINE_SIMPLEX_GET_PIN(X) do \ { \ if(nrfx_gpiote_in_is_set(FML_SINGLE_LINE_SIMPLEX_PIN)) \ X = 1; \ else \ X = 0; \ }while(0) //读取IO引脚高低电平 #define FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_H_PULL 0 //主机中断接收上下拉配置 #define FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_S_PULL 1 //从机中断接收上下拉配置 #define FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT(HANDLER,X) do \ { \ nrfx_gpiote_out_uninit(FML_SINGLE_LINE_SIMPLEX_PIN); \ nrfx_gpiote_in_uninit(FML_SINGLE_LINE_SIMPLEX_PIN); \ nrfx_gpiote_in_config_t in_config; \ in_config.sense = NRF_GPIOTE_POLARITY_TOGGLE; \ if(X == 0)in_config.pull = NRF_GPIO_PIN_NOPULL; \ if(X == 1)in_config.pull = NRF_GPIO_PIN_PULLUP; \ if(X == 2)in_config.pull = NRF_GPIO_PIN_PULLDOWN; \ in_config.is_watcher = false; \ in_config.hi_accuracy = true; \ in_config.skip_gpio_setup = false; \ APP_ERROR_CHECK(nrfx_gpiote_in_init(FML_SINGLE_LINE_SIMPLEX_PIN, &in_config, HANDLER)); \ nrfx_gpiote_in_event_enable(FML_SINGLE_LINE_SIMPLEX_PIN, true); \ }while(0) //设置IO引脚为输入高低电平中断 #define FML_SINGLE_LINE_SIMPLEX_RECEIVE_MAX_LEN 1024 //接收缓存的最大字节长度 #define FML_SINGLE_LINE_SIMPLEX_APPROX_EQUAL_TO(A,B,ERROR,BOOL) do \ { \ uint32_t error; \ if(A > B){error = A - B;if(error <= ERROR)BOOL = true;else BOOL = false;} \ else {error = B - A;if(error <= ERROR)BOOL = true;else BOOL = false;} \ }while(0) //判断俩个数是否约等于 #define FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(US) do \ { \ uint32_t tim1; \ uint32_t tim2; \ uint32_t distance; \ tim1 = NRF_RTC0->COUNTER; \ do \ { \ tim2 = NRF_RTC0->COUNTER; \ if(tim2 < tim1)tim2 += 16777216; \ distance = (tim2 - tim1)/32.768 * 1000; \ }while(distance < US); \ }while(0) //等待时间 单位:us #define FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT(X) do \ { \ FML_SINGLE_LINE_SIMPLEX_CLEAR_PIN; \ FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T); \ if(X == 1) \ FML_SINGLE_LINE_SIMPLEX_SET_PIN; \ else \ FML_SINGLE_LINE_SIMPLEX_CLEAR_PIN; \ }while(0) //发送一个位 #define FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(X) X = NRF_RTC0->COUNTER //获取时间戳 #define FML_SINGLE_LINE_SIMPLEX_GET_DISTANCE_FOR_TIMESTAMP(TIMESTAMP,US) do \ { \ uint32_t tim = NRF_RTC0->COUNTER; \ if(tim < TIMESTAMP) tim += 16777216; \ US = (tim - TIMESTAMP)/32.768 * 1000; \ }while(0) //获取与时间戳的差 单位:us #define FML_SINGLE_LINE_SIMPLEX_PWM_SEND_ONE_BIT_TIEMS (FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS/8) //PWM发送一位的时间 单位:us 1 -> 8us 125 -> 1ms 3750 -> 30ms #define FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN ((FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T + FML_SINGLE_LINE_SIMPLEX_BOOT_CODE_T + \ 2*FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T + \ 8*FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T + 8*FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T + \ FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T + FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T + \ FML_SINGLE_LINE_SIMPLEX_END_CODE_T*2) / FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS \ ) //PWM发送一个字节的序列大小,END_CODE*2是为了余量。 #define FML_SINGLE_LINE_SIMPLEX_PWM_LEVEL_HIGHT 0 //PWM高电平 #define FML_SINGLE_LINE_SIMPLEX_PWM_LEVEL_LOW 0x8000 //PWM低电平 #define FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(SEQ_VALUES,INDEX,COUNT,X) do \ { \ uint16_t level; \ if(X==1)level = FML_SINGLE_LINE_SIMPLEX_PWM_LEVEL_HIGHT;else level = FML_SINGLE_LINE_SIMPLEX_PWM_LEVEL_LOW; \ for(int i = 0; i < COUNT; i++)SEQ_VALUES[INDEX++] =level; \ }while(0) //PWM等待时间转为序列 单位:us /*STRUCTION -----------------------------------------------------*/ typedef struct _fml_single_line_simplex { FML_SINGLE_LINE_SIMPLEX_ROLE_e role; //角色 bool start_receive; //开始接收标志位 uint8_t receive_bit_num; //接收到的字节当前位 volatile unsigned char* RxW; //接收缓存区写指针 volatile unsigned char* RxR; //接收缓存区读指针 uint8_t receive_buff[FML_SINGLE_LINE_SIMPLEX_RECEIVE_MAX_LEN]; //接收缓存区 fml_single_line_half_duplex_receive_cb receive_cb; //接收回调 uint32_t pwm_pin_channel[4]; //PWM通道引脚,每个PWM模块只支持4个通道 uint16_t pwm_cycle_time; //PWM周期时间 uint32_t pwm_mode; //PWM模式 pwm_values_common_t fml_single_line_simplex_pwm_seq_values[FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN]; //PWM序列值 nrf_pwm_sequence_t *fml_single_line_simplex_pwm_seq; //PWM序列指针 bool pwm_transfer_is_done; //PWM传输是否完成标志 } Fml_Single_Line_Simplex_t; /*Local Variable ----------------------------------------------*/ static Fml_Single_Line_Simplex_t ob_fml_single_line_simplex; /*Local Functions ----------------------------------------------*/ static void fml_single_line_receive_buff_push(uint8_t *p, int len) { volatile unsigned char *W=ob_fml_single_line_simplex.RxW; //这里要与上面指针相同 if(len<=0) return; for(int i=0;i=ob_fml_single_line_simplex.receive_buff+FML_SINGLE_LINE_SIMPLEX_RECEIVE_MAX_LEN) W=ob_fml_single_line_simplex.receive_buff; //取下一位置(到顶转到底) if(W!=ob_fml_single_line_simplex.RxR){*ob_fml_single_line_simplex.RxW=*(p+i); ob_fml_single_line_simplex.RxW=W;} else break; } } static unsigned int fml_single_line_receive_CheckLen(void) //检查RX接收了多少数据 { unsigned int Len; //short volatile unsigned char *W=ob_fml_single_line_simplex.RxW; volatile unsigned char *R=ob_fml_single_line_simplex.RxR; if(W>=R)Len=W-R;else Len=(W+FML_SINGLE_LINE_SIMPLEX_RECEIVE_MAX_LEN)-R; //这样正确(中途中断改变也变不了结果) return Len; } static uint8_t fml_single_line_receive_buff_pop(void) { unsigned char R=*ob_fml_single_line_simplex.RxR; //读数 if(ob_fml_single_line_simplex.RxR!=ob_fml_single_line_simplex.RxW) { if(ob_fml_single_line_simplex.RxR+1>=(ob_fml_single_line_simplex.receive_buff+FML_SINGLE_LINE_SIMPLEX_RECEIVE_MAX_LEN)) ob_fml_single_line_simplex.RxR = ob_fml_single_line_simplex.receive_buff; else ob_fml_single_line_simplex.RxR++; }//下标 return R; } static void fml_single_line_in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { static uint8_t receive_byte = 0; static uint8_t flow = 0; static uint32_t timestamp,last_timestamp; static uint32_t distance; static uint32_t calibration_compensate = FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T / 2; //若线太长,拉高拉低时间过长,导致校验码时间与设定好的校验码时间不一致,初始设定能接受的延迟为校准码的一半 static int Parity_Check; uint32_t level; bool condition; FML_SINGLE_LINE_SIMPLEX_GET_PIN(level); // //test----------------- // JS_RTT_Print(level,0,0); // return; // //test----------------- // SEGGER_RTT_printf(0,"level:%d\n",level); switch(flow) { case 0: //接收引导码阶段 if(level == 1) { //这样子读取减少误差产生----------> last_timestamp = timestamp; FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); FML_SINGLE_LINE_SIMPLEX_GET_DISTANCE_FOR_TIMESTAMP(last_timestamp,distance); //<----------这样子读取减少误差产生 if(timestamp !=0 && last_timestamp != 0) { if(distance >= FML_SINGLE_LINE_SIMPLEX_END_CODE_T) //结束码错误 { flow = 1; } else { flow = 0; } } else { flow = 1; //第一次运行 } ob_fml_single_line_simplex.start_receive = false; ob_fml_single_line_simplex.receive_bit_num = 0; receive_byte = 0; } break; case 1: //接收校准码阶段 if(level == 0) { //这样子读取减少误差产生----------> last_timestamp = timestamp; FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); FML_SINGLE_LINE_SIMPLEX_GET_DISTANCE_FOR_TIMESTAMP(last_timestamp,distance); //<----------这样子读取减少误差产生 FML_SINGLE_LINE_SIMPLEX_APPROX_EQUAL_TO(distance,FML_SINGLE_LINE_SIMPLEX_BOOT_CODE_T,calibration_compensate,condition); if(!condition) { flow = 0; //引导码错误 } } else { FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); flow = 2; } break; case 2: //接收数据码阶段 if(level == 0) { //这样子读取减少误差产生----------> last_timestamp = timestamp; FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); FML_SINGLE_LINE_SIMPLEX_GET_DISTANCE_FOR_TIMESTAMP(last_timestamp,distance); //<----------这样子读取减少误差产生 if(ob_fml_single_line_simplex.start_receive == false) { FML_SINGLE_LINE_SIMPLEX_APPROX_EQUAL_TO(distance,FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T,calibration_compensate,condition); if(condition) { ob_fml_single_line_simplex.start_receive = true; //校准码无误 Parity_Check = 0; } else { flow = 0; } } else { FML_SINGLE_LINE_SIMPLEX_APPROX_EQUAL_TO(distance,FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T,calibration_compensate,condition); if(condition){receive_byte |= (0x01 << ob_fml_single_line_simplex.receive_bit_num);Parity_Check++;} else receive_byte &= ~(0x01 << ob_fml_single_line_simplex.receive_bit_num); ob_fml_single_line_simplex.receive_bit_num++; if(ob_fml_single_line_simplex.receive_bit_num == 8) { flow = 3; } } } else { FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); } break; case 3: //接收奇偶校验码阶段 if(level == 1) { FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); } else { //这样子读取减少误差产生----------> last_timestamp = timestamp; FML_SINGLE_LINE_SIMPLEX_GET_TIMESTAMP(timestamp); FML_SINGLE_LINE_SIMPLEX_GET_DISTANCE_FOR_TIMESTAMP(last_timestamp,distance); //<----------这样子读取减少误差产生 if(ob_fml_single_line_simplex.start_receive == true && ob_fml_single_line_simplex.receive_bit_num == 8) //接收结束码阶段 { FML_SINGLE_LINE_SIMPLEX_APPROX_EQUAL_TO(distance,FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T,calibration_compensate,condition); if(condition) { if((Parity_Check % 2) != 0) //奇校验通过 { //接收字节 fml_single_line_receive_buff_push(&receive_byte, 1); //接收回调 if(ob_fml_single_line_simplex.receive_cb != NULL)ob_fml_single_line_simplex.receive_cb(); } } else { if((Parity_Check % 2) == 0) //偶校验通过 { //接收字节 fml_single_line_receive_buff_push(&receive_byte, 1); //接收回调 if(ob_fml_single_line_simplex.receive_cb != NULL)ob_fml_single_line_simplex.receive_cb(); } } } flow = 0; } break; } } static int fml_single_line_transfer_one_byte(uint8_t value) { uint8_t bit; int Parity_Check; //发送引导码 FML_SINGLE_LINE_SIMPLEX_CLEAR_PIN; FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T); FML_SINGLE_LINE_SIMPLEX_SET_PIN; FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_BOOT_CODE_T); //发送校准码 FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT(1); FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T); //发送数据码 Parity_Check = 0; for(int i=0; i<8;i++) { bit = ((value >> i)&0x01); FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT(1); if(bit == 1){FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T);Parity_Check++;} else FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_LOW_LEVEL_T); } //发送奇偶校验码 FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT(1); if(Parity_Check % 2 == 0)FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_LOW_LEVEL_T); else FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T); //发送结束码 FML_SINGLE_LINE_SIMPLEX_CLEAR_PIN; FML_SINGLE_LINE_SIMPLEX_WAIT_TIMES(FML_SINGLE_LINE_SIMPLEX_END_CODE_T); return 0; } static int fml_single_line_pwm_transfer_one_byte(uint8_t value) { uint8_t bit; int Parity_Check; int index; //清空序列值 for(int i=0; i> i)&0x01); FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 0); if(bit == 1) { FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 1); Parity_Check++; } else { FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_LOW_LEVEL_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 1); } } //发送奇偶校验码 FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_CALIBRATION_CODE_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 0); if(Parity_Check % 2 == 0) { FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_LOW_LEVEL_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 1); } else { FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_HIGHT_LEVEL_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 1); } //发送结束码 FML_SINGLE_LINE_SIMPLEX_PWM_WAIT_TIMES(ob_fml_single_line_simplex.fml_single_line_simplex_pwm_seq_values, \ index, \ (FML_SINGLE_LINE_SIMPLEX_END_CODE_T/FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS), \ 0); return index; } static void fml_single_line_pwm_transfer_callback(nrfx_pwm_evt_type_t event_type) { uint32_t err_code; switch(event_type) { case NRFX_PWM_EVT_FINISHED: //Sequence playback finished. //取消pwm Pwm1_UnInitialize(); //重新GPIOTE 驱动初始化: err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); //配置接收中断 if(ob_fml_single_line_simplex.role == FML_SINGLE_LINE_SIMPLEX_ROLE_HOST) FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT(fml_single_line_in_pin_handler,FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_H_PULL); else FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT(fml_single_line_in_pin_handler,FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_S_PULL); //修改状态 ob_fml_single_line_simplex.pwm_transfer_is_done = true; break; default: break; } } /*API ----------------------------------------------*/ /** @brief 初始化单线单工驱动 @param role - [in] 角色 @return 错误代码 - [out] -1失败,0成功 */ int fml_single_line_simplex_Init(FML_SINGLE_LINE_SIMPLEX_ROLE_e role) { uint32_t err_code; // GPIOTE 驱动初始化: err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); //重置 memset(&ob_fml_single_line_simplex,0,sizeof(ob_fml_single_line_simplex)); //初始化结构体 ob_fml_single_line_simplex.start_receive = false; ob_fml_single_line_simplex.RxW = ob_fml_single_line_simplex.receive_buff; ob_fml_single_line_simplex.RxR = ob_fml_single_line_simplex.receive_buff; ob_fml_single_line_simplex.pwm_pin_channel[0] = FML_SINGLE_LINE_SIMPLEX_PIN; ob_fml_single_line_simplex.pwm_pin_channel[1] = NRF_DRV_PWM_PIN_NOT_USED; ob_fml_single_line_simplex.pwm_pin_channel[2] = NRF_DRV_PWM_PIN_NOT_USED; ob_fml_single_line_simplex.pwm_pin_channel[3] = NRF_DRV_PWM_PIN_NOT_USED; ob_fml_single_line_simplex.pwm_cycle_time = FML_SINGLE_LINE_SIMPLEX_PWM_SEND_ONE_BIT_TIEMS; ob_fml_single_line_simplex.pwm_mode = PWM_FLAG_STOP; ob_fml_single_line_simplex.pwm_transfer_is_done = true; ob_fml_single_line_simplex.role = role; //配置接收中断 if(ob_fml_single_line_simplex.role == FML_SINGLE_LINE_SIMPLEX_ROLE_HOST) FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT(fml_single_line_in_pin_handler,FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_H_PULL); else FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT(fml_single_line_in_pin_handler,FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_INPUT_INTERRUPT_S_PULL); return 0; } /** @brief 取消初始化单线单工驱动 @param 无 @return 错误代码 - [out] -1失败,0成功 */ int fml_single_line_simplex_UnInit(void) { //取消pwm Pwm1_UnInitialize(); //取消gpiote nrf_drv_gpiote_uninit(); return 0; } /** @brief 单线单工传输 —— 发送 @param p_send - [in] 需要发送数据的指向地址 @param len - [in] 数据长度 @return 错误代码 - [out] -1失败,0成功 */ int fml_single_line_simplex_transfer(char *p_send, int len) { uint32_t err_code; if(p_send == NULL)return -1; if(len < 0)return -1; //取消pwm Pwm1_UnInitialize(); //取消gpiote nrf_drv_gpiote_uninit(); //重新GPIOTE 驱动初始化: err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); //配置发送 FML_SINGLE_LINE_SIMPLEX_CONFIG_PIN_OUTPUT; for(int i=0; i= len)read_len = len; for(int i=0; i