2024-04-16 11:58:43 +08:00
|
|
|
|
#include "SIF.h"
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
#define DATA_REV_PIN gpio_get(SIF_REV_PIN)
|
2024-04-16 14:25:08 +08:00
|
|
|
|
|
|
|
|
|
#ifdef _SIF_DEBUG_
|
|
|
|
|
char log_str[128] = { 0 };
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
INITIAL_STATE = 0, // 初始状态,等待接收同步信号
|
|
|
|
|
SYNC_L_STATE = 1, // 接收同步低电平信号状态
|
|
|
|
|
SYNC_H_STATE = 2, // 接收同步高电平信号状态
|
|
|
|
|
DATA_REV_STATE = 3, // 读取数据码电平状态
|
|
|
|
|
END_SIGNAL_STATE = 4, // 接收结束电平信号状态
|
|
|
|
|
RESTART_REV_STATE = 5 // 接收过程出错重新接收状态
|
|
|
|
|
} REV_STATE_e; // 接收数据状态枚举
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
unsigned char receive_state = 0; // 接收数据状态
|
|
|
|
|
unsigned char receive_bit_num = 0; // 接收的bit位个数
|
|
|
|
|
unsigned char receive_data_num = 0; // 接收的数据个数
|
2024-04-16 14:25:08 +08:00
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
unsigned char sif_receive_data_buf[REV_DATA_NUM] = { 0 }; // 接收数据缓存数组如果一帧数据有多个数据打开注释
|
2024-04-16 14:25:08 +08:00
|
|
|
|
unsigned char sif_receive_data[REV_DATA_NUM] = { 0 };
|
2024-04-16 17:56:53 +08:00
|
|
|
|
unsigned int H_L_Level_time_cnt = 0; // 高低电平时间计数
|
|
|
|
|
|
|
|
|
|
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-结束标志
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void GPIO_SIF_Init(void) {
|
|
|
|
|
// 初始化 GPIO
|
2024-04-16 14:25:08 +08:00
|
|
|
|
gpio_init(SIF_REV_PIN);
|
2024-04-16 17:56:53 +08:00
|
|
|
|
|
|
|
|
|
// 将 GPIO 设置为输入模式
|
|
|
|
|
gpio_set_dir(SIF_REV_PIN, GPIO_IN);
|
|
|
|
|
|
|
|
|
|
// 启用下拉模式
|
|
|
|
|
gpio_pull_down(SIF_REV_PIN);
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
|
2024-04-16 14:25:08 +08:00
|
|
|
|
void TIMER_SIF_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
if (start_H_L_Level_timming_flag == 1) {
|
2024-04-16 17:56:53 +08:00
|
|
|
|
H_L_Level_time_cnt++; // 高低电平维持时间计数变量
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
Receive_SIF_Data_Handle(); // 接收数据处理,波特率自适应
|
2024-04-16 14:25:08 +08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Receive_SIF_Data_Handle(void)
|
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
switch (receive_state) // 检测当前接收数据状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
case INITIAL_STATE: // 初始状态,未接收到同步信息,进行同步判断
|
|
|
|
|
if (DATA_REV_PIN == LOW) // 判断接收引脚的电平状态,当读到低电平时,开始计时
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
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; // 开始高低电平计时
|
2024-04-16 14:25:08 +08:00
|
|
|
|
is_end_bit = 0;
|
2024-04-16 17:56:53 +08:00
|
|
|
|
receive_state = SYNC_L_STATE; // 进入读取同步低电平信号状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
memset(sif_receive_data_buf, 0, 16);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
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) // 判断接收引脚的电平状态,当读到高电平时
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
H_L_Level_time_cnt = 0; // 高低电平计时变量清0
|
|
|
|
|
receive_state = SYNC_H_STATE; // 进入读取同步信号高电平状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-04-16 17:56:53 +08:00
|
|
|
|
if (DATA_REV_PIN == HIGH) // 同步信号低电平检测期间读到高电平重新计时
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
receive_state = RESTART_REV_STATE; // 进入重新接收状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
case SYNC_H_STATE: // 在读取同步高电平信号期间
|
|
|
|
|
if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM * Tosc) // 如果高电平时间超过了(32+64=96)个Tosc,则认为超时
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
receive_state = RESTART_REV_STATE; // 进入重新接收状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
} else {
|
2024-04-16 17:56:53 +08:00
|
|
|
|
if (DATA_REV_PIN == LOW) // 同步信号高电平检测期间读到低电平
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
Tosc = H_L_Level_time_cnt / SHORT_TIME_NUM; // 调整 Tosc 的值
|
|
|
|
|
H_L_Level_time_cnt = 0; // 高低电平计时变量清0
|
|
|
|
|
receive_state = DATA_REV_STATE; // 进入读取数据码低电平状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
case DATA_REV_STATE: // 在读取数据码电平期间
|
2024-04-16 14:25:08 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2024-04-16 17:56:53 +08:00
|
|
|
|
// 如果已经读取一个bit位,且时间计数已经>=96Tosc,说明一个逻辑周期过去了
|
2024-04-16 14:25:08 +08:00
|
|
|
|
if ((has_read_bit == 1) && (H_L_Level_time_cnt >= (LOGIC_CYCLE_NUM * Tosc))) {
|
2024-04-16 17:56:53 +08:00
|
|
|
|
H_L_Level_time_cnt = 0; // 高低电平计时变量清0
|
|
|
|
|
has_read_bit = 0; // 清0,读取下一个bit位
|
|
|
|
|
receive_bit_num--; // 接收的bit数--
|
|
|
|
|
if (receive_bit_num == 0) // 如果一个字节8个bit位接收完成
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
receive_data_num++; // 接收的数据个数++
|
|
|
|
|
receive_bit_num = REV_BIT_NUM; // 重置接收bit位个数
|
2024-04-16 14:25:08 +08:00
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
if (receive_data_num >= REV_DATA_NUM) // 如果数据采集完毕 超出了最大值
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
start_H_L_Level_timming_flag = 0; // 停止高低电平计时
|
|
|
|
|
H_L_Level_time_cnt = 0; // 定时器计数值清0
|
|
|
|
|
receive_state = INITIAL_STATE; // 接收状态清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
2024-04-16 17:56:53 +08:00
|
|
|
|
} else // 如果一个字节8个bit位还没有接收完成
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
// 将接收数据缓存左移一位,数据从高bit位开始接收
|
2024-04-16 14:25:08 +08:00
|
|
|
|
sif_receive_data_buf[receive_data_num] = sif_receive_data_buf[receive_data_num] << 1;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 记录 结束标志
|
|
|
|
|
if (H_L_Level_time_cnt == (END_SIGNAL_FLAG_NUM * Tosc) && (DATA_REV_PIN == LOW)) {
|
|
|
|
|
is_end_bit = 1;
|
|
|
|
|
has_read_bit = 0;
|
2024-04-16 17:56:53 +08:00
|
|
|
|
read_success = 1; // 一帧数据读取成功
|
2024-04-16 14:25:08 +08:00
|
|
|
|
#ifdef _SIF_DEBUG_
|
|
|
|
|
sprintf(log_str, "rn:%d,%s.", receive_data_num, sif_receive_data_buf);
|
|
|
|
|
#endif
|
|
|
|
|
Check_Sum_Handle();
|
2024-04-16 17:56:53 +08:00
|
|
|
|
start_H_L_Level_timming_flag = 0; // 停止高低电平计时
|
|
|
|
|
H_L_Level_time_cnt = 0; // 定时器计数值清0
|
|
|
|
|
receive_state = INITIAL_STATE; // 接收状态清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
case END_SIGNAL_STATE: // 在接收结束信号低电平期间
|
2024-04-16 14:25:08 +08:00
|
|
|
|
if (DATA_REV_PIN == LOW) {
|
2024-04-16 17:56:53 +08:00
|
|
|
|
if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM * Tosc) // 如果读到低电平时间>=5ms
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
read_success = 1; // 一帧数据读取成功
|
2024-04-16 14:25:08 +08:00
|
|
|
|
Check_Sum_Handle();
|
2024-04-16 17:56:53 +08:00
|
|
|
|
start_H_L_Level_timming_flag = 0; // 停止高低电平计时
|
|
|
|
|
H_L_Level_time_cnt = 0; // 定时器计数值清0
|
|
|
|
|
receive_state = INITIAL_STATE; // 接收状态清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
2024-04-16 17:56:53 +08:00
|
|
|
|
} else // 结束信号低电平检测期间一直为低
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
//if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM) // 如果读到低电平时间>=10ms,认为超时
|
|
|
|
|
{ // 一帧数据发送完成后需要间隔50ms才发送第二帧数据,期间肯定会被拉高
|
|
|
|
|
receive_state = RESTART_REV_STATE; // 进入重新接收状态
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-04-16 17:56:53 +08:00
|
|
|
|
case RESTART_REV_STATE: // 重新接收数据状态
|
|
|
|
|
start_H_L_Level_timming_flag = 0; // 停止高低电平计时
|
|
|
|
|
H_L_Level_time_cnt = 0; // 定时器计数值清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
is_end_bit = 0;
|
2024-04-16 17:56:53 +08:00
|
|
|
|
receive_state = INITIAL_STATE; // 接收状态清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
unsigned char *pGetSIFData(void) // 获取SIF数据
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
return sif_receive_data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef _SIF_DEBUG_
|
2024-04-16 17:56:53 +08:00
|
|
|
|
char *pGetLogStr(void) // 获取SIF数据
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
return log_str;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void Check_Sum_Handle()
|
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
if (read_success == 1) // 如果成功读取一帧数据
|
2024-04-16 14:25:08 +08:00
|
|
|
|
{
|
2024-04-16 17:56:53 +08:00
|
|
|
|
// 一帧数据接收成功后先根据协议要求进行校验和,验证数据的正确性
|
|
|
|
|
// 如果数据正确,根据接收的数据进行分析获取需要的内容
|
2024-04-16 14:25:08 +08:00
|
|
|
|
//if (check_OK)
|
|
|
|
|
{
|
|
|
|
|
memset(sif_receive_data, 0, REV_DATA_NUM);
|
|
|
|
|
memcpy(sif_receive_data, sif_receive_data_buf, REV_DATA_NUM);
|
|
|
|
|
memset(sif_receive_data_buf, 0, REV_DATA_NUM);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 17:56:53 +08:00
|
|
|
|
read_success = 0; // 读取一帧数据清0
|
2024-04-16 14:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 11:58:43 +08:00
|
|
|
|
|
|
|
|
|
void SIF(void *p)
|
|
|
|
|
{
|
|
|
|
|
(void)p;
|
2024-04-16 14:25:08 +08:00
|
|
|
|
|
|
|
|
|
GPIO_SIF_Init();
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
char *SIF_DATA = (char *)pGetSIFData();
|
|
|
|
|
|
|
|
|
|
printf("%s", SIF_DATA);
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ;
|
2024-04-16 11:58:43 +08:00
|
|
|
|
}
|