首页 > 评测 > 【LKS32AT085评测】2.电动自行车一线通应用之SIF
【LKS32AT085评测】2.电动自行车一线通应用之SIF
- [导读]
- 本帖最后由 yang377156216 于 2022-9-19 15:47 编辑 #申请原创# @21小跑堂 前言前面说到可以通过某个专业领域应用去打开市场,这里想推荐一个领域:两轮电动自行车。这个东西相信大家都非常熟悉,几乎每天都
本帖最后由 yang377156216 于 2022-9-19 15:47 编辑
#申请原创# @21小跑堂
前言
两轮电动车行业情况
电动自行车通信协议团体标准
一线通 SIF 协议
-
一线通 SIF 协议比较简单,实现起来成本较低,适用于一些数据量不大且通讯品质要求不那么高的场景;
-
属于单线主从单工通讯模式,类似 1-Wire 协议但又与之有很大不同,为单工通讯的,即设备要么仅作为发送端,要么仅作为接收方,比如上面框图中 BMS 为发送发(主机),控制器和充电器仅为接收方(从机);
-
波特率要么像 UART 一样提前固定好,要么让接收端自动适应发送方的同步信号从而来解析出匹配到的波特率;
-
一次传输一帧数据,每帧数据由 同步信号(发送主报文的前导信号) + 数据信号(8bit * 12个数据位的有效数据内容,按一定占空比进行发送)+ 结束信号(一帧完整的数据发送结束的标志信号) 3个部分组成,传输结束后要求线路空闲状态为低电平,每次传输需一次性完整传输所有数据;
-
数据的电平遵守 TTL 规范。
一般一线通接口原理设计如下,IN 为主机单片机的输出口,OUT 为总线接口:
-
32Tosc 范围为 0.5ms,考虑到响应速度,不要超过1ms
-
同步信号:>992Tosc 的低电平 + 32Tosc 的高电平,空闲位时间>15ms(0.5ms*992/32=15ms)
-
数据位逻辑 1 符合 高电平时间 > 低电平时间 + 0.5ms;
-
数据位逻辑 0 符合 低电平时间 > 高电平时间 + 0.5ms;
-
高低电平的比例一般使用 0.5ms 和 1ms 的比例,及占空比为 1:2 (适宜取 75%)
凌鸥 SIF 接口驱动代码
- #define SIF_VERSION 1
- #define SIF_SYNC 53
- #define SIF_SEND_COUNT 3
- volatile static uint8_t sif_sync_tosc = 0;
- volatile static uint8_t sif_send_tosc = 0;
- volatile static uint8_t state_mode = 0;
- volatile static int8_t bit_cnt = 7;
- volatile static uint8_t byte_cnt = 0;
- static uint8_t result[64] = {0};//需要发送的数据
- volatile static uint8_t length = 0;//数据的长度
- static void sif_send_data_handle(uint8_t state)
- {
- switch(state)
- {
- case SYNC_SIGNAL://同步模式
- if (sif_sync_tosc < SIF_SYNC - 2) {
- sif_turn_off();
- } else {
- sif_turn_on();
- }
- sif_sync_tosc++;
- if (sif_sync_tosc >= SIF_SYNC)
- {
- state_mode = SEND_DATA;
- sif_sync_tosc = 0;
- bit_cnt = 7;
- byte_cnt = 0;
- sif_send_tosc = 0;
- }
- break;
- case SEND_DATA: //发送数据
- static uint8_t res;
- uint8_t count = SIF_SEND_COUNT;
- static uint8_t nums = sizeof(uint8_t) * 8;
- uint8_t *p = (uint8_t *)result;
- sif_send_tosc = sif_send_tosc % count;
- uint8_t data = (p[byte_cnt] >> bit_cnt) & 0x1;
- if (data)
- {
- if (sif_send_tosc == 0)
- {
- sif_turn_off();
- sif_send_tosc ++;
- }
- else if (sif_send_tosc == 1)
- {
- sif_turn_on();
- sif_send_tosc ++;
- } else {
- sif_send_tosc = 0;
- }
- }
- else
- {
- if (sif_send_tosc == 0)
- {
- sif_turn_off();
- sif_send_tosc++;
- }
- else if (sif_send_tosc == 2)
- {
- sif_turn_on();
- sif_send_tosc = 0;
- } else
- {
- sif_send_tosc++;
- }
- }
- if (sif_send_tosc == 0)
- {
- if (--bit_cnt < 0)
- {
- byte_cnt++;
- bit_cnt = 7;
- }
- if (byte_cnt >= length)
- {
- state_mode = SEND_DATA_COMPLETE;
- break;
- }
- }
- break;
- case SEND_DATA_COMPLETE://数据发送完成,将标志位清0
- state_mode = 0;
- sif_turn_off();
- length = 0;
- memset(result, 0, sizeof(result));
- break;
- default:
- break;
- }
- }
- /*******************************************************************************
- * 版权所有 (C)2015, LINKO SEMICONDUCTOR Co.ltd
- *
- * 文件名称: lks32at08x_sif.c
- * 文件标识:
- * 内容摘要: SIF 外设驱动程序
- * 其它说明: 无
- * 当前版本: V 1.0
- * 作 者: yang377156216
- * 完成日期:
- *
- * 修改记录1:
- * 修改日期:
- * 版 本 号:V 1.0
- * 修 改 人:
- * 修改内容:创建
- *
- ******************************************************************************/
- #include "lks32at08x_sif.h"
- /*******************************************************************************
- 函数名称: void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct)
- 功能描述: SIF 初始化
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct)
- {
- if (SIFx == SIF0)
- {
- //开启 SIF 的时钟,这里默认就是开启的;
- }
- SIFx ->CFG &= ~(0x01 << 1);
- SIFx ->CFG |= (SIF_InitStruct->Endian << 1);
- SIFx ->FREQ &= ~(0x0F << 4);
- SIFx ->FREQ |= (SIF_InitStruct->Tosc << 4);
- SIFx ->FREQ &= ~(0x01 << 0);
- SIFx ->FREQ |= (SIF_InitStruct->Duty << 0);
- SIFx ->IRQ &= ~(0x01 << 0);
- SIFx ->IRQ |= (SIF_InitStruct->TxIE << 0);
- }
- /*******************************************************************************
- 函数名称: void SIF_DeInit(SIF_TypeDef *SIFx)
- 功能描述: SIF 反初始化
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_DeInit(SIF_TypeDef *SIFx)
- {
- SIFx ->CFG = 1;
- SIFx ->FREQ = 0;
- SIFx ->IRQ = 0;
- SIFx ->WDATA = 0;
- SIFx ->CFG = 0;
- }
- /*******************************************************************************
- 函数名称: void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct)
- 功能描述: SIF 结构体初始化
- 操作的表: 无
- 输入参数: SIF_InitTypeDef *SIF_InitStruct
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct)
- {
- SIF_InitStruct->Duty = SIF_DUTY_2_1;
- SIF_InitStruct->Endian = SIF_ENDIAN_LSB;
- SIF_InitStruct->Tosc = SIF_Tosc_32US_Default;
- SIF_InitStruct->TxIE = SIF_TX_IE_DIS;
- }
- /*******************************************************************************
- 函数名称: void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable)
- 功能描述: SIF 模块使能/关闭
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, uint8_t enable
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable)
- {
- if(enable == ENABLE)
- {
- SIFx ->CFG |= SIF_MODULE_EN;
- }
- else
- {
- SIFx ->CFG &= ~SIF_MODULE_EN;
- }
- }
- /*******************************************************************************
- 函数名称: void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable)
- 功能描述: SIF 结束本次传输
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, uint8_t enable
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable)
- {
- if(enable == ENABLE)
- {
- SIFx ->CFG |= SIF_LAST_BYTE_EN;
- }
- }
- /*******************************************************************************
- 函数名称: void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data)
- 功能描述: SIF 发送数据
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, uint8_t data
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data)
- {
- SIFx->WDATA = data;
- }
- /*******************************************************************************
- 函数名称: uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- 功能描述: 取得 SIF 中断标志
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, uint32_t tempFlag
- 输出参数: 无
- 返 回 值: SIF 中断标志
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- {
- if (((SIFx->IRQ & tempFlag) != Bit_RESET) && \
- (SIFx->IRQ & SIF_TX_IE_EN) != Bit_RESET)
- {
- return 1;
- }
- return 0;
- }
- /*******************************************************************************
- 函数名称: void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- 功能描述: 清除 SIF 中断标志位
- 操作的表: 无
- 输入参数: SIF_TypeDef *SIFx, uint32_t tempFlag
- 输出参数: 无
- 返 回 值: 无
- 其它说明:
- 修改日期 版本号 修改人 修改内容
- -------------------------------------------------------------------------------
- 2022/08/19 V1.0 yang377156216 创建
- ******************************************************************************/
- void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag)
- {
- SIFx->IRQ |= tempFlag;
- }
- /*********************** (C) COPYRIGHT LINKO SEMICONDUCTOR *****END OF FILE****/
- /*******************************************************************************
- * 版权所有 (C)2015, LINKO SEMICONDUCTOR Co.ltd
- *
- * 文件名称: lks32at08x_sif.h
- * 文件标识:
- * 内容摘要: SIF 驱动头文件
- * 其它说明: 无
- * 当前版本: V 1.0
- * 作 者: yang377156216
- * 完成日期:
- *
- * 修改记录1:
- * 修改日期:
- * 版 本 号:V 1.0
- * 修 改 人:
- * 修改内容:创建
- *
- ******************************************************************************/
- #ifndef __LKS32AT08x_SIF_H
- #define __LKS32AT08x_SIF_H
- /* Includes ------------------------------------------------------------------*/
- #include "lks32mc08x_lib.h"
- typedef struct
- {
- __IO uint32_t CFG;
- __IO uint32_t FREQ;
- __IO uint32_t IRQ;
- __IO uint32_t WDATA;
- } SIF_TypeDef;
- typedef enum
- {
- SIF_Tosc_32US_Default = 0x00,
- SIF_Tosc_32US = 0x01,
- SIF_Tosc_64US = 0x02,
- SIF_Tosc_96US = 0x03,
- SIF_Tosc_128US = 0x04,
- SIF_Tosc_160US = 0x05,
- SIF_Tosc_192US = 0x06,
- SIF_Tosc_220US = 0x07,
- SIF_Tosc_256US = 0x08,
- SIF_Tosc_288US = 0x09,
- SIF_Tosc_320US = 0x0A,
- } SIF_ToscSet;
- typedef struct
- {
- uint8_t Endian; /*SIF 大小端,1 = MSB , 0 = LSB 默认*/
- uint8_t Tosc; /*96Mhz 系统时钟下,基准时间单位 Tosc 设置*/
- uint8_t Duty; /*SIF 传输 Data 占空比*/
- uint8_t TxIE; /*发送中断使能*/
- } SIF_InitTypeDef;
- #ifndef SIF0
- #define SIF0 ((SIF_TypeDef *) SIF_BASE)
- #endif
- #ifndef SIF_MCU_MCLK
- #define SIF_MCU_MCLK (96000000LL) /* 系统时钟 */
- #endif
- #define SIF_LAST_BYTE_EN (1 << 4) /*是否结束本次传输*/
- #define SIF_ENDIAN_LSB 0 /*低端先发送*/
- #define SIF_ENDIAN_MSB 1 /*高端先发送*/
- #define SIF_MODULE_EN (1 << 0) /*SIF 模块使能*/
- #define SIF_DUTY_2_1 0 /*占空比为 2:1*/
- #define SIF_DUTY_3_1 1 /*占空比为 3:1*/
- #define SIF_TX_IE_DIS 0 /*SIF 中断禁止*/
- #define SIF_TX_IE_EN 1 /*SIF 中断使能*/
- /*中断标志定义*/
- #define SIF_TX_IFLAG (1 << 4) /*发送完成中断*/
- void SIF_MouduleEnable(SIF_TypeDef *SIFx, uint8_t enable);
- void SIF_LastByte_Set(SIF_TypeDef *SIFx, uint8_t enable);
- void SIF_DeInit(SIF_TypeDef *SIFx);
- void SIF_Init(SIF_TypeDef *SIFx, SIF_InitTypeDef *SIF_InitStruct);
- void SIF_StructInit(SIF_InitTypeDef *SIF_InitStruct);
- void SIF_SendData(SIF_TypeDef *SIFx, uint8_t data);
- uint32_t SIF_GetIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag);
- void SIF_ClearIRQFlag(SIF_TypeDef *SIFx, uint32_t tempFlag);
- #endif /*__lks32mc08x_SIF_H */
- /************************ (C) COPYRIGHT LINKO SEMICONDUCTOR *****END OF FILE****/
- /*******************************************************************************
- *@时 间 : 2022-2-22
- *@摘 要 : 主程序文件
- *@芯 片 :
- *
- *******************************************************************************/
- /*================================= Demo说明 ===================================
- 定时器 + 一个GPIO口进行通讯数据读取
- ==============================================================================*/
- /* 包含的头文件 ---------------------------------------------------------------*/
- //与实际单片机相关
- /* 宏定义 ---------------------------------------------------------------------*/
- #define DATA_REV_PIN gpio_input_bit_get(GPIOB,BIT(9)) //定义数据接收引脚(根据实际项目进行更改)
- #define LOW 0 //低电平
- #define HIGH 1 //高电平
- #define SYNC_L_TIME_NUM 1100 //同步信号低电平时间:50ms = 50000us / 50us = 1000
- #define SYNC_H_TIME_NUM_MIN 8 //同步信号高电平最小时间:500-100us = 400us / 50us = 8
- #define SYNC_H_TIME_NUM_MAX 12 //同步信号高电平最大时间:500+100us = 600us / 50us = 12
- #define SHORT_TIME_NUM_MIN 9 //一个逻辑周期中短的时间最小值:500-50us = 450us / 50us = 9
- #define SHORT_TIME_NUM_MAX 11 //一个逻辑周期中短的时间最大值:500+50us = 550us / 50us = 11
- #define LONG_TIME_NUM_MIN 18 //一个逻辑周期中长的时间最小值:1ms-100us = 900us / 50us = 18
- #define LONG_TIME_NUM_MAX 22 //一个逻辑周期中长的时间最大值:1ms+100us = 1100us / 50us = 22
- #define LOGIC_CYCLE_NUM_MIN 26 //一个逻辑周期最小时间:1.5ms-200us = 1300us / 50us = 26
- #define LOGIC_CYCLE_NUM_MAX 34 //一个逻辑周期最大时间:1.5ms+200us = 1700us / 50us = 34
- #define HALF_LOGIC_CYCLE_MIN 13 //一个逻辑周期的1/2最小时间:750-100us = 650us / 50us = 13
- #define HALF_LOGIC_CYCLE_MAX 17 //一个逻辑周期的1/2最大时间:750+100us = 850us / 50us = 17
- #define END_SIGNAL_TIME_NUM 100 //结束信号电平时间:5ms低电平 + Nms高电平,实际检测5ms低电平就行,一帧数据发送完成后检测5ms低电平就代表完成了,不发数据的时候上拉电阻拉高了
- #define REV_BIT_NUM 8 //接收的bit位个数,看是按字节接收还是按字接收,1字节=8bit,1字=2字节=16bit
- #define REV_DATA_NUM 12 //接收的数据个数
- /* 类型定义 -------------------------------------------------------------------*/
- 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; //接收数据状态枚举
- /* 变量定义 -------------------------------------------------------------------*/
- unsigned char receive_state=0; //接收数据状态
- unsigned char receive_bit_num=0; //接收的bit位个数
- unsigned char receive_data_num=0; //接收的数据个数
- //接收数据缓存数组-用一个数组来缓存数据,51个数据字节
- unsigned char receive_data_buf[REV_DATA_NUM]={0};
- unsigned char receive_data[REV_DATA_NUM] = {0};
- unsigned int H_L_Level_time_cnt=0; //高低电平时间计数
- uint8_t start_H_L_Level_timming_flag=0; //开始高低电平计时标记
- uint8_t has_read_bit = 0; //1-已经读取一个bit位
- uint8_t check_OK = 0; //1-校验和正确,0-校验和失败
- uint8_t read_success=0; //一帧数据是否读取成功,0-不成功,1-成功
- uint8_t Pin_Old = 0;
- uint8_t Pin_New = 0;
- uint8_t Pin_Change_Flag = 0;
- uint8_t BitFinish_Flag = 0;
- /* 函数声明 -------------------------------------------------------------------*/
- void GPIO_Init(void); //GPIO初始化函数
- void Timer1_Init(void); //定时器1初始化函数
- void Receive_Data_Handle(void); //接收数据处理
- void Check_Sum_Handle(void); //校验和处理
- /* 函数定义 -------------------------------------------------------------------*/
- /*******************************************************************************
- *函数名称 : SIF_Handle
- *函数功能 : SIF 解析函数,在主循环中调用
- *输入参数 : void
- *输出返回 : void
- *******************************************************************************/
- void main(void)
- {
- GPIO_Init(); //GPIO初始化,设置数据接收引脚P10为浮空输入,检测高低电平
- Timer1_Init(); //定时器1初始化,定时周期为:5微秒
- while(1)
- {
- SIF_Handle();
- }
- }
- /*******************************************************************************
- *函数名称 : SIF_Handle
- *函数功能 : SIF 解析函数,在主循环中调用
- *输入参数 : void
- *输出返回 : void
- *******************************************************************************/
- void SIF_Handle(void)
- {
- if (read_success == 1) //如果成功读取一帧数据
- {
- //一帧数据接收成功后先根据协议要求进行校验和,验证数据的正确性
- Check_Sum_Handle();
- //如果数据正确,根据接收的数据进行分析获取需要的内容
- if (check_OK)
- {
- memcpy(receive_data, receive_data_buf, REV_DATA_NUM);
- }
- read_success = 0; //读取一帧数据清0
- }
- }
- /*******************************************************************************
- *函数名称 : Timer1_isr
- *函数功能 : 定时器1中断处理函数
- *输入参数 : void
- *输出返回 : void
- *******************************************************************************/
- void TIMER1_IRQHandler(void)
- {
- if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH0))
- {
- /* clear channel 0 interrupt bit */
- timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH0);
- Pin_New = DATA_REV_PIN;
- if (start_H_L_Level_timming_flag==1)
- {
- H_L_Level_time_cnt++; //高低电平维持时间计数变量
- Pin_Change_Flag = 0;
- BitFinish_Flag = 0;
- if(Pin_New != Pin_Old)
- {
- Pin_Change_Flag = 1;
- if(0 == Pin_New)
- {BitFinish_Flag = 1;}
- }
- Pin_Old = Pin_New;
- }
- Receive_Data_Handle(); //接收数据处理,波特率自适应
- led_toggle(LED2);//测试用的 LED
- }
- }
- /*******************************************************************************
- *函数名称 : Receive_Data_Handle
- *函数功能 : 接收数据处理
- *输入参数 : void
- *输出返回 : void
- *******************************************************************************/
- void Receive_Data_Handle(void)
- {
- switch (receive_state) //检测当前接收数据状态
- {
- case INITIAL_STATE: //初始状态,未接收到同步信息,进行同步判断
- if (DATA_REV_PIN == LOW) //判断接收引脚的电平状态,当读到低电平时,开始计时
- {
- receive_bit_num = 0; //重置bit位计数器
- receive_data_num = 0; //重置接收数据个数
- H_L_Level_time_cnt = 0; //高低电平计时变量清0
- start_H_L_Level_timming_flag = 1; //开始高低电平计时
- receive_state = SYNC_L_STATE; //进入读取同步低电平信号状态
- memset(receive_data_buf, 0 ,REV_DATA_NUM);
- }
- break;
- case SYNC_L_STATE: //在读取同步低电平信号期间
- if (DATA_REV_PIN == HIGH) //同步信号低电平检测期间读到高电平
- {
- if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM)//如果同步信号低电平时间>=SYNC_L_TIME_NUM
- { //同步信号低电平时间要>=10ms
- H_L_Level_time_cnt = 0; //高低电平计时变量清0
- receive_state = SYNC_H_STATE; //进入读取同步信号高电平状态
- }
- else
- {
- receive_state = RESTART_REV_STATE; //进入重新接收状态
- }
- }
- break;
- case SYNC_H_STATE: //在读取同步信号高电平期间
- if (DATA_REV_PIN == LOW) //同步信号高电平检测期间读到低电平
- {
- //判断同步信号高电平时间是否在1ms±100us之间
- if (H_L_Level_time_cnt >= SYNC_H_TIME_NUM_MIN && H_L_Level_time_cnt <= SYNC_H_TIME_NUM_MAX)
- {
- H_L_Level_time_cnt = 0; //高低电平计时变量清0
- receive_state = DATA_REV_STATE; //进入读取数据状态
- }
- else
- {
- receive_state = RESTART_REV_STATE; //进入重新接收状态
- }
- }
- else //如果在同步信号高电平检测期间,时间超过2ms±200us,认为超时
- {
- //判断时间是否超时 2ms±200us
- if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM_MAX)
- {
- receive_state = RESTART_REV_STATE; //进入重新接收状态
- }
- }
- break;
- case DATA_REV_STATE: //在读取数据码电平期间
- if ((has_read_bit==0) && (H_L_Level_time_cnt >= HALF_LOGIC_CYCLE_MIN && H_L_Level_time_cnt <= HALF_LOGIC_CYCLE_MAX))
- {
- receive_data_buf[receive_data_num] |= DATA_REV_PIN;
- has_read_bit = 1;
- }
- //如果已经读取一个bit位,且时间计数已经>=2ms±200us,说明一个逻辑周期过去了
- if ((has_read_bit==1) && (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM_MIN && H_L_Level_time_cnt <= LOGIC_CYCLE_NUM_MAX))
- //if ((has_read_bit==1) && (1 == BitFinish_Flag))
- {
- H_L_Level_time_cnt = 0; //高低电平计时变量清0
- has_read_bit = 0; //清0,读取下一个bit位
- receive_bit_num++; //接收的bit数++
- if (receive_bit_num == REV_BIT_NUM) //如果一个字节8个bit位接收完成
- {
- //receive_data[receive_data_num] = receive_data_buf[receive_data_num];
- receive_data_num++; //接收的数据个数++
- receive_bit_num = 0; //接收bit位个数清0重新接收
- if (receive_data_num == REV_DATA_NUM) //如果数据采集完毕
- {
- receive_state = END_SIGNAL_STATE; //进入接收结束低电平信号状态
- }
- }
- else //如果一个字节8个bit位还没有接收完成
- {
- //将接收数据缓存左移一位,数据从低bit位开始接收
- receive_data_buf[receive_data_num] = receive_data_buf[receive_data_num] >> 1;
- }
- }
- break;
- case END_SIGNAL_STATE: //在接收结束信号低电平期间
- if (DATA_REV_PIN == LOW)
- {
- if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM) //如果读到低电平时间>=5ms
- {
- read_success = 1; //一帧数据读取成功
- SIF_Handle();
- start_H_L_Level_timming_flag = 0; //停止高低电平计时
- H_L_Level_time_cnt = 0; //定时器计数值清0
- receive_state = INITIAL_STATE; //接收状态清0
- }
- }
- else //结束信号低电平检测期间一直为低
- {
- //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
- receive_state = INITIAL_STATE; //接收状态清0
- break;
- }
- }
- /*******************************************************************************
- *函数名称 : Check_Sum_Handle
- *函数功能 : 校验和处理
- *输入参数 : void
- *输出返回 : void
- *******************************************************************************/
- void Check_Sum_Handle(void)
- {
- unsigned char i = 0, checkByte = 0;
- unsigned long checkXor = 0;
- for ( i = 0; i < (REV_DATA_NUM ); i++)
- {
- checkXor = checkXor ^ receive_data_buf[i];
- }
- checkByte = (unsigned char)checkXor;
- if (checkByte == receive_data_buf[REV_DATA_NUM-1]) //校验和正确
- {
- check_OK = 1; //标记校验成功
- }
- else
- {
- check_OK = 0; //标记校验失败
- }
- }
- uint8_t * pGetSIFData(void)
- {
- return receive_data;
- }
仪表盘液晶屏幕一线通应用
小结
- 本文系21ic原创,未经许可禁止转载!
网友评论
- 联系人:巧克力娃娃
- 邮箱:board@21ic.com
- 我要投稿
-
欢迎入驻,开放投稿
-
人均百万?英伟达中国员工收入曝光! 2024-08-29
-
《黑神话:悟空》玩家硬盘升级攻略:提升游戏体验,畅享3A大作 2024-08-29
-
数睿数据参加《系统与软件工程 低代码开发平台通用技术要求》国家标准编制 2024-08-29
- NRF52810蓝牙数字耳机找人定制
预算:¥30005天前
- 125KW模块式PCS软硬件外包开发
预算:¥1100000015小时前
- 12V汽车启动电源项目BMS设计
预算:¥50000023小时前
- 数据可视化软件 开发
预算:¥5000023小时前
- PLC项目调试修改
预算:¥100001天前
- 起动电机控制器开发
预算:¥1100001天前