参照下面文章,单线通讯—SIF通讯协议(一线通)案例二 作者Geek YANG,程序中有少许错误,移植过来后,有修改,比如数据的时间长度,校验方式,接收收据的处理等,最后成功实现。 注释有些没改过来。。
#include <gd32f10x.h>
#include <gd32f103e_eval.h>
#define DATA_REV_PIN gpio_input_bit_get(GPIOB,BIT(9))
#define LOW 0
#define HIGH 1
#define SYNC_L_TIME_NUM 1100
#define SYNC_H_TIME_NUM_MIN 8
#define SYNC_H_TIME_NUM_MAX 12
#define SHORT_TIME_NUM_MIN 9
#define SHORT_TIME_NUM_MAX 11
#define LONG_TIME_NUM_MIN 18
#define LONG_TIME_NUM_MAX 22
#define LOGIC_CYCLE_NUM_MIN 26
#define LOGIC_CYCLE_NUM_MAX 34
#define HALF_LOGIC_CYCLE_MIN 13
#define HALF_LOGIC_CYCLE_MAX 17
#define END_SIGNAL_TIME_NUM 100
#define REV_BIT_NUM 8
#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;
unsigned char receive_data_num=0;
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;
uint8_t check_OK = 0;
uint8_t read_success=0;
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);
void Timer0_Init(void);
void Receive_Data_Handle(void);
void Check_Sum_Handle(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;
}
}
void TIMER1_IRQHandler(void)
{
if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_CH0)){
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();
gd_eval_led_toggle(LED2);
}
}
void Receive_Data_Handle(void)
{
switch (receive_state)
{
case INITIAL_STATE:
if (DATA_REV_PIN == LOW)
{
receive_bit_num = 0;
receive_data_num = 0;
H_L_Level_time_cnt = 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)
{
H_L_Level_time_cnt = 0;
receive_state = SYNC_H_STATE;
}
else
{
receive_state = RESTART_REV_STATE;
}
}
break;
case SYNC_H_STATE:
if (DATA_REV_PIN == LOW)
{
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;
receive_state = DATA_REV_STATE;
}
else
{
receive_state = RESTART_REV_STATE;
}
}
else
{
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;
}
if ((has_read_bit==1) && (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM_MIN && H_L_Level_time_cnt <= LOGIC_CYCLE_NUM_MAX))
{
H_L_Level_time_cnt = 0;
has_read_bit = 0;
receive_bit_num++;
if (receive_bit_num == REV_BIT_NUM)
{
receive_data_num++;
receive_bit_num = 0;
if (receive_data_num == REV_DATA_NUM)
{
receive_state = END_SIGNAL_STATE;
}
}
else
{
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)
{
read_success = 1;
SIF_Handle();
start_H_L_Level_timming_flag = 0;
H_L_Level_time_cnt = 0;
receive_state = INITIAL_STATE;
}
}
else
{
{
receive_state = RESTART_REV_STATE;
}
}
break;
case RESTART_REV_STATE:
start_H_L_Level_timming_flag = 0;
H_L_Level_time_cnt = 0;
receive_state = INITIAL_STATE;
break;
}
}
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;
}
最后版本的源文件附上:SIF.c
接收的数据,用串口发送出来,如下 完。
|