diff --git a/Source/SIF.c b/Source/SIF.c index 618d6f3..14e4e97 100644 --- a/Source/SIF.c +++ b/Source/SIF.c @@ -2,7 +2,7 @@ #include "common.h" -#define DATA_REV_PIN gpio_get(SIF_REV_PIN) +#define DATA_REV_PIN gpio_get(SIF_REV_PIN) #ifdef _SIF_DEBUG_ char log_str[128] = { 0 }; @@ -17,131 +17,116 @@ typedef enum { RESTART_REV_STATE = 5 // 接收过程出错重新接收状态 } REV_STATE_e; // 接收数据状态枚举 -unsigned char receive_state = 0; //接收数据状态 -unsigned char receive_bit_num = 0; //接收的bit位个数 -unsigned char receive_data_num = 0; //接收的数据个数 +unsigned char receive_state = 0; // 接收数据状态 +unsigned char receive_bit_num = 0; // 接收的bit位个数 +unsigned char receive_data_num = 0; // 接收的数据个数 -unsigned char sif_receive_data_buf[REV_DATA_NUM] = { 0 }; //接收数据缓存数组如果一帧数据有多个数据打开注释 +unsigned char sif_receive_data_buf[REV_DATA_NUM] = { 0 }; // 接收数据缓存数组如果一帧数据有多个数据打开注释 unsigned char sif_receive_data[REV_DATA_NUM] = { 0 }; -unsigned int H_L_Level_time_cnt = 0; //高低电平时间计数 +unsigned int H_L_Level_time_cnt = 0; // 高低电平时间计数 -unsigned int Tosc = TOSC; //波形时基单元,一般带波特率自适应的,不会说明高低电平的时间,会用一个Tosc时基描述 -//如上面的波形图,要求 32Tosc = 0.5ms = 500us -//所以:一个Tosc = 500us/32 ≈ 15us,而定时器0单次定时时间为5us,所以实际一个Tosc = 15us/5us = 3 次 -//可以理解为 5us 是人为设置的一个定时器单次定时时间,再这个定时时间的基础上又产生了一个实际时基Tosc,用在波形上,波形基于这个Tosc时基单元 -//可以动态的调整高低电平的时间,只要Tosc改变,992Tosc和32Tosc以及64Tosc对应的时间也会随之改变;然后我们反过来思考,再不知道波特率的情况下, -//去读取同步信号高电平的时间,将读到的时间计数H_L_Level_time_cnt * 15us是高电平的真实维持时间 = 32 * Tosc * 5us = SHORT_TIME_NUM * Tosc * 5us -//Tosc = H_L_Level_time_cnt / SHORT_TIME_NUM -//在本案例中,一帧数据 = 992Tosc+32Tosc+(64+32)*8*12Tosc = 10240*Tosc 次 -//1秒钟 = 1000000us,单次定时 5us,则1s / 5us = 200000 次 -//则1秒钟可以接收 200000 / (10240 * Tosc) = 200000/10240/Tosc = 19/Tosc 帧数据 +unsigned int Tosc = TOSC; // 波形时基单元,一般带波特率自适应的,不会说明高低电平的时间,会用一个Tosc时基描述 -uint8_t start_H_L_Level_timming_flag = 0; //开始高低电平计时标记 -uint8_t has_read_bit = 0; //1-已经读取一个bit位 -uint8_t read_success = 0; //一帧数据是否读取成功,0-不成功,1-成功 -uint8_t is_end_bit = 0; // 结束帧判定 0-未结束,1-结束标志 +uint8_t start_H_L_Level_timming_flag = 0; // 开始高低电平计时标记 +uint8_t has_read_bit = 0; // 1-已经读取一个bit位 +uint8_t read_success = 0; // 一帧数据是否读取成功,0-不成功,1-成功 +uint8_t is_end_bit = 0; // 结束帧判定 0-未结束,1-结束标志 -void GPIO_SIF_Init(void) -{ +void GPIO_SIF_Init(void) { + // 初始化 GPIO gpio_init(SIF_REV_PIN); - gpio_set_dir(SIF_REV_PIN, GPIO_OUT); + + // 将 GPIO 设置为输入模式 + gpio_set_dir(SIF_REV_PIN, GPIO_IN); + + // 启用下拉模式 + gpio_pull_down(SIF_REV_PIN); } + void TIMER_SIF_IRQHandler(void) { if (start_H_L_Level_timming_flag == 1) { - H_L_Level_time_cnt++; //高低电平维持时间计数变量 + H_L_Level_time_cnt++; // 高低电平维持时间计数变量 } - Receive_SIF_Data_Handle(); //接收数据处理,波特率自适应 + Receive_SIF_Data_Handle(); // 接收数据处理,波特率自适应 } void Receive_SIF_Data_Handle(void) { - switch (receive_state) //检测当前接收数据状态 + switch (receive_state) // 检测当前接收数据状态 { - case INITIAL_STATE: //初始状态,未接收到同步信息,进行同步判断 - if (DATA_REV_PIN == LOW) //判断接收引脚的电平状态,当读到低电平时,开始计时 + case INITIAL_STATE: // 初始状态,未接收到同步信息,进行同步判断 + if (DATA_REV_PIN == LOW) // 判断接收引脚的电平状态,当读到低电平时,开始计时 { - receive_bit_num = REV_BIT_NUM; //重置bit位计数器 - receive_data_num = 0; //重置接收数据个数 - H_L_Level_time_cnt = 0; //高低电平计时变量清0 - read_success = 0; //结束位置低电平判定清零 - start_H_L_Level_timming_flag = 1; //开始高低电平计时 + receive_bit_num = REV_BIT_NUM; // 重置bit位计数器 + receive_data_num = 0; // 重置接收数据个数 + H_L_Level_time_cnt = 0; // 高低电平计时变量清0 + read_success = 0; // 结束位置低电平判定清零 + start_H_L_Level_timming_flag = 1; // 开始高低电平计时 is_end_bit = 0; - receive_state = SYNC_L_STATE; //进入读取同步低电平信号状态 + receive_state = SYNC_L_STATE; // 进入读取同步低电平信号状态 memset(sif_receive_data_buf, 0, 16); } break; - case SYNC_L_STATE: //在读取同步低电平信号期间 - if (H_L_Level_time_cnt > SYNC_TIME_NUM * Tosc) //如果低电平时间 > SYNC_TIME_NUM*Tosc=992*3*5us - { //同步状态空闲时间大于15ms - if (DATA_REV_PIN == HIGH) //判断接收引脚的电平状态,当读到高电平时 + case SYNC_L_STATE: // 在读取同步低电平信号期间 + if (H_L_Level_time_cnt > SYNC_TIME_NUM * Tosc) // 如果低电平时间 > SYNC_TIME_NUM*Tosc=992*3*5us + { // 同步状态空闲时间大于15ms + if (DATA_REV_PIN == HIGH) // 判断接收引脚的电平状态,当读到高电平时 { - H_L_Level_time_cnt = 0; //高低电平计时变量清0 - receive_state = SYNC_H_STATE; //进入读取同步信号高电平状态 + H_L_Level_time_cnt = 0; // 高低电平计时变量清0 + receive_state = SYNC_H_STATE; // 进入读取同步信号高电平状态 } } else { - if (DATA_REV_PIN == HIGH) //同步信号低电平检测期间读到高电平重新计时 + if (DATA_REV_PIN == HIGH) // 同步信号低电平检测期间读到高电平重新计时 { - receive_state = RESTART_REV_STATE; //进入重新接收状态 + receive_state = RESTART_REV_STATE; // 进入重新接收状态 } } break; - case SYNC_H_STATE: //在读取同步高电平信号期间 - if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM * Tosc) //如果高电平时间超过了(32+64=96)个Tosc,则认为超时 + case SYNC_H_STATE: // 在读取同步高电平信号期间 + if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM * Tosc) // 如果高电平时间超过了(32+64=96)个Tosc,则认为超时 { - receive_state = RESTART_REV_STATE; //进入重新接收状态 + receive_state = RESTART_REV_STATE; // 进入重新接收状态 } else { - if (DATA_REV_PIN == LOW) //同步信号高电平检测期间读到低电平 + if (DATA_REV_PIN == LOW) // 同步信号高电平检测期间读到低电平 { - //在同步信号高电平检测期间读到低电平可能有如下状态: - //1、高电平时间短,不满32Tosc - //2、高电平时间正好=32Tosc - //3、高电平时间长,超过32Tosc - //不管何种状态,都要 调整 Tosc 的值达到波特率自适应 - //H_L_Level_time_cnt * 5us 要求是 SHORT_TIME_NUM * Tosc * 5us, - //即 H_L_Level_time_cnt = SHORT_TIME_NUM * Tosc - Tosc = H_L_Level_time_cnt / SHORT_TIME_NUM; //调整 Tosc 的值 - H_L_Level_time_cnt = 0; //高低电平计时变量清0 - receive_state = DATA_REV_STATE; //进入读取数据码低电平状态 + Tosc = H_L_Level_time_cnt / SHORT_TIME_NUM; // 调整 Tosc 的值 + H_L_Level_time_cnt = 0; // 高低电平计时变量清0 + receive_state = DATA_REV_STATE; // 进入读取数据码低电平状态 } } break; - case DATA_REV_STATE: //在读取数据码电平期间 - //逻辑"0"为 64Tosc低电平 + 32Tosc高电平 - //逻辑"1"为 32Tosc低电平 + 64Tosc高电平 - //不管是逻辑"0"还是逻辑"1",周期一样,都是32Tosc + 64Tosc = 96Tosc - //可以取中间时间点进行判断,96Tosc / 2 = 48Tosc,当计数>=48Tosc时读取引脚电平 - //如果还没有读取一个bit位,且时间计数已经>=48Tosc + case DATA_REV_STATE: // 在读取数据码电平期间 if ((has_read_bit == 0) && (H_L_Level_time_cnt >= (HALF_LOGIC_CYCLE * Tosc))) { sif_receive_data_buf[receive_data_num] |= DATA_REV_PIN; has_read_bit = 1; } - //如果已经读取一个bit位,且时间计数已经>=96Tosc,说明一个逻辑周期过去了 + // 如果已经读取一个bit位,且时间计数已经>=96Tosc,说明一个逻辑周期过去了 if ((has_read_bit == 1) && (H_L_Level_time_cnt >= (LOGIC_CYCLE_NUM * Tosc))) { - H_L_Level_time_cnt = 0; //高低电平计时变量清0 - has_read_bit = 0; //清0,读取下一个bit位 - receive_bit_num--; //接收的bit数-- - if (receive_bit_num == 0) //如果一个字节8个bit位接收完成 + H_L_Level_time_cnt = 0; // 高低电平计时变量清0 + has_read_bit = 0; // 清0,读取下一个bit位 + receive_bit_num--; // 接收的bit数-- + if (receive_bit_num == 0) // 如果一个字节8个bit位接收完成 { - receive_data_num++; //接收的数据个数++ - receive_bit_num = REV_BIT_NUM; //重置接收bit位个数 + receive_data_num++; // 接收的数据个数++ + receive_bit_num = REV_BIT_NUM; // 重置接收bit位个数 - if (receive_data_num >= REV_DATA_NUM) //如果数据采集完毕 超出了最大值 + if (receive_data_num >= REV_DATA_NUM) // 如果数据采集完毕 超出了最大值 { - start_H_L_Level_timming_flag = 0; //停止高低电平计时 - H_L_Level_time_cnt = 0; //定时器计数值清0 - receive_state = INITIAL_STATE; //接收状态清0 + start_H_L_Level_timming_flag = 0; // 停止高低电平计时 + H_L_Level_time_cnt = 0; // 定时器计数值清0 + receive_state = INITIAL_STATE; // 接收状态清0 } - } else //如果一个字节8个bit位还没有接收完成 + } else // 如果一个字节8个bit位还没有接收完成 { - //将接收数据缓存左移一位,数据从高bit位开始接收 + // 将接收数据缓存左移一位,数据从高bit位开始接收 sif_receive_data_buf[receive_data_num] = sif_receive_data_buf[receive_data_num] << 1; } @@ -150,52 +135,52 @@ void Receive_SIF_Data_Handle(void) if (H_L_Level_time_cnt == (END_SIGNAL_FLAG_NUM * Tosc) && (DATA_REV_PIN == LOW)) { is_end_bit = 1; has_read_bit = 0; - read_success = 1; //一帧数据读取成功 + read_success = 1; // 一帧数据读取成功 #ifdef _SIF_DEBUG_ sprintf(log_str, "rn:%d,%s.", receive_data_num, sif_receive_data_buf); #endif Check_Sum_Handle(); - start_H_L_Level_timming_flag = 0; //停止高低电平计时 - H_L_Level_time_cnt = 0; //定时器计数值清0 - receive_state = INITIAL_STATE; //接收状态清0 + start_H_L_Level_timming_flag = 0; // 停止高低电平计时 + H_L_Level_time_cnt = 0; // 定时器计数值清0 + receive_state = INITIAL_STATE; // 接收状态清0 } break; - case END_SIGNAL_STATE: //在接收结束信号低电平期间 + case END_SIGNAL_STATE: // 在接收结束信号低电平期间 if (DATA_REV_PIN == LOW) { - if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM * Tosc) //如果读到低电平时间>=5ms + if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM * Tosc) // 如果读到低电平时间>=5ms { - read_success = 1; //一帧数据读取成功 + read_success = 1; // 一帧数据读取成功 Check_Sum_Handle(); - start_H_L_Level_timming_flag = 0; //停止高低电平计时 - H_L_Level_time_cnt = 0; //定时器计数值清0 - receive_state = INITIAL_STATE; //接收状态清0 + start_H_L_Level_timming_flag = 0; // 停止高低电平计时 + H_L_Level_time_cnt = 0; // 定时器计数值清0 + receive_state = INITIAL_STATE; // 接收状态清0 } - } else //结束信号低电平检测期间一直为低 + } else // 结束信号低电平检测期间一直为低 { - //if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM) //如果读到低电平时间>=10ms,认为超时 - { //一帧数据发送完成后需要间隔50ms才发送第二帧数据,期间肯定会被拉高 - receive_state = RESTART_REV_STATE; //进入重新接收状态 + //if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM) // 如果读到低电平时间>=10ms,认为超时 + { // 一帧数据发送完成后需要间隔50ms才发送第二帧数据,期间肯定会被拉高 + receive_state = RESTART_REV_STATE; // 进入重新接收状态 } } break; - case RESTART_REV_STATE: //重新接收数据状态 - start_H_L_Level_timming_flag = 0; //停止高低电平计时 - H_L_Level_time_cnt = 0; //定时器计数值清0 + case RESTART_REV_STATE: // 重新接收数据状态 + start_H_L_Level_timming_flag = 0; // 停止高低电平计时 + H_L_Level_time_cnt = 0; // 定时器计数值清0 is_end_bit = 0; - receive_state = INITIAL_STATE; //接收状态清0 + receive_state = INITIAL_STATE; // 接收状态清0 break; } } -unsigned char *pGetSIFData(void) //获取SIF数据 +unsigned char *pGetSIFData(void) // 获取SIF数据 { return sif_receive_data; } #ifdef _SIF_DEBUG_ -char *pGetLogStr(void) //获取SIF数据 +char *pGetLogStr(void) // 获取SIF数据 { return log_str; } @@ -203,10 +188,10 @@ char *pGetLogStr(void) //获取SIF数据 void Check_Sum_Handle() { - if (read_success == 1) //如果成功读取一帧数据 + if (read_success == 1) // 如果成功读取一帧数据 { - //一帧数据接收成功后先根据协议要求进行校验和,验证数据的正确性 - //如果数据正确,根据接收的数据进行分析获取需要的内容 + // 一帧数据接收成功后先根据协议要求进行校验和,验证数据的正确性 + // 如果数据正确,根据接收的数据进行分析获取需要的内容 //if (check_OK) { memset(sif_receive_data, 0, REV_DATA_NUM); @@ -214,7 +199,7 @@ void Check_Sum_Handle() memset(sif_receive_data_buf, 0, REV_DATA_NUM); } - read_success = 0; //读取一帧数据清0 + read_success = 0; // 读取一帧数据清0 } } diff --git a/Source/SIF.h b/Source/SIF.h index 582e9a5..6a36444 100644 --- a/Source/SIF.h +++ b/Source/SIF.h @@ -8,6 +8,8 @@ #include #include +#include "pico/stdlib.h" +#include "hardware/gpio.h" #define _SIF_DEBUG_ 1