基于GD32F407單片機(jī)與循環(huán)隊(duì)列的BIT上報(bào)學(xué)習(xí)記錄
c文件
static uint8_t rx_buf[MAX_485_RX_LEN] = {0};
static uint8_t rx_buf_data_cnt = DATA;
static uint8_t rs485TXBuf[MAX_485_RX_LEN] = {0};
usart_device_t usart_device_485 = {
.rcv_state = DRI_RS485_STATE_IDLE,
.front = 0,
.rear = 0,
};
/*緩存區(qū)初始化*/
void dri_rs485_buf_empty(void)
{
dri_usart_empty(&usart_device_485);
memset(rx_buf, 0, sizeof(rx_buf));
rx_buf_data_cnt = DATA;
}
/*中斷接收,中斷收一個(gè)數(shù)據(jù),push一次*/
int dri_rs485_rcv(uint8_t data)
{
int rv = 0;
rv = dri_usart_plush(&usart_device_485, data);
if(rv != 0)
{
printf("queue is full\r\n");
dri_rs485_buf_empty();
}
return rv;
}
/*bit接收,循環(huán)一次,pop一個(gè)數(shù)據(jù)*/
int dri_rs485_buf_pop(uint8_t *data)
{
int rv = 0;
rv = dri_usart_pop(&usart_device_485, data);
return rv;
}
/************************************************
函數(shù)名稱 : dri_rs485_request_empty
功 能 : 當(dāng)出現(xiàn)錯(cuò)誤時(shí),或者信息有誤,如:slot不匹配,
恢復(fù)初始狀態(tài)
參 數(shù) : 無(wú)
返 回 值 : 無(wú)
作 者 :
*************************************************/
static void dri_rs485_request_empty(void)
{
//memset(rx_buf, 0, sizeof(rx_buf));
usart_device_485.rcv_state = DRI_RS485_STATE_IDLE;
rx_buf_data_cnt = DRI_RS485_PKG_DATA;
}
/*
*********************************************************************************************************
* dri_rs485_check_usart2()
*
* Description : Handle set packge
*
* Argument(s) : config : information at module.
* Return(s) : none.
*
* Caller(s) : app.c.
*
* Note(s) : 包結(jié)構(gòu):0xaa 0x55 slot len type data... crc 0xfd 0xfd
********************************************************************************************************
*/
void dri_rs485_rcv_process(void)
{
uint8_t data;
int rv = 0;
rv = dri_rs485_buf_pop(&data);
if(rv != 0)
return;
switch(usart_device_485.rcv_state)
{
case STATE_IDLE: //head
if(data == 0xaa)
{
usart_device_485.rcv_state = STATE_SYNC;
rx_buf[DRI_RS485_PKG_IDLE] = data;
}
break;
case STATE_SYNC:
if(data == 0x55)
{
usart_device_485.rcv_state = STATE_SLOT;
rx_buf[DRI_RS485_PKG_SYNC] = data;
}
else if(data == 0xaa)
{
usart_device_485.rcv_state = STATE_SYNC;
}
else
{
usart_device_485.rcv_state = STATE_IDLE;
}
break;
case STATE_SLOT:
rx_buf[DRI_RS485_PKG_SLOT] = data;
usart_device_485.rcv_state = STATE_LEN;
break;
case STATE_LEN:
rx_buf[DRI_RS485_PKG_LEN] = data;
usart_device_485.rcv_state = STATE_TYPE;
break;
case STATE_TYPE:
rx_buf[DRI_RS485_PKG_TYPE] = data;
usart_device_485.rcv_state = STATE_TAIL;
break;
case STATE_TAIL:
if(data == 0xfd)
{
usart_device_485.rcv_state = STATE_LAST;
}
else
{
/*在此等待報(bào)尾,在報(bào)尾到來(lái)之前的都是數(shù)據(jù)*/
rx_buf[rx_buf_data_cnt++] = data;
}
break;
case STATE_LAST:
if(data == 0xfd)
{
usart_interrupt_disable(DRI_RS485_USART, USART_INT_RBNE);
/*
數(shù)據(jù)寫到了CRC位,由于是++后綴,rx_buf_data_cnt實(shí)際累加到了tail位,
后面還有1B報(bào)尾,所以實(shí)際最后一個(gè)BYTE的索引為:rx_buf_data_cnt + 1;
rx_buf_data_cnt計(jì)數(shù)從0開始,所以實(shí)際報(bào)長(zhǎng)為rx_buf_data_cnt + 2。
*/
if(rx_buf[DRI_RS485_PKG_SLOT] != slot)
{
RS485_ERROR("slot error\r\n");
goto pkg_error;
}
if (rx_buf[DRI_RS485_PKG_LEN] != rx_buf_data_cnt + 2)
{
RS485_ERROR("len error\r\n");
goto pkg_error;
}
if (rx_buf[rx_buf_data_cnt -1] != checksum(rx_buf, rx_buf_data_cnt - 1))
{
RS485_ERROR("checksum error\r\n");
goto pkg_error;
}
if(rx_buf[DRI_RS485_PKG_LEN] <= MAX_485_RX_LEN )
{
/*bit處理函數(shù)*/
}
dri_rs485_request_empty();
usart_interrupt_enable(DRI_RS485_USART, USART_INT_RBNE);
}
else
{
/*數(shù)據(jù)中有可能有報(bào)尾結(jié)束符0xfd*/
rx_buf[rx_buf_data_cnt++] = data;
usart_device_485.rcv_state = STATE_TAIL;
break;
}
return;
default:
break;
}
return;
pkg_error:
dri_rs485_request_empty();
usart_interrupt_enable(DRI_RS485_USART, USART_INT_RBNE);
return;
}
頭文件
#if 0
#define RS485_DEBUG(format,...) printf(" LINE: %d: "format, __LINE__, ##__VA_ARGS__)
#else
#define RS485_DEBUG(format,...)
#endif
#if 1
#define RS485_ERROR(format,...) printf("FILE: "__FILE__" LINE: %d: "format"/n", __LINE__, ##__VA_ARGS__)
#else
#define RS485_ERROR(format,...)
#endif
#define DRI_PERIPH_USART RCU_USART0
#define DRI_RS485_USART USART0
#define DRI_RS485_EN_PIN DRI_GPIOA_RS485_EN
#define DRI_RS485_EN_PORT GPIOA
#define DRI_RS485_TX_PIN DRI_GPIOA_RS485_TX
#define DRI_RS485_TX_PORT GPIOA
#define DRI_RS485_RX_PIN DRI_GPIOA_RS485_RX
#define DRI_RS485_RX_PORT GPIOA
#define MAX_485_RX_LEN 160
/*****************************************state machine*****************************************/
#define STATE_IDLE 0x00 //0xaa
#define STATE_SYNC 0x01 //0x55
#define STATE_SLOT 0x02 //槽位號(hào)
#define STATE_LEN 0x03 //報(bào)長(zhǎng)
#define STATE_TYPE 0x04 //類型
#define STATE_TAIL 0x05 //0xfd
#define STATE_LAST 0x06 //0xfd
enum pkg_struct{
DRI_RS485_PKG_IDLE,
DRI_RS485_PKG_SYNC,
DRI_RS485_PKG_SLOT,
DRI_RS485_PKG_LEN,
DRI_RS485_PKG_TYPE,
DRI_RS485_PKG_DATA,
DRI_RS485_PKG_TAIL,
DRI_RS485_PKG_LAST
};
中斷處理:
void USART0_IRQHandler(void)
{
uint8_t data;
if(usart_flag_get(USART0, USART_FLAG_PERR)!= RESET)
{
usart_data_receive(USART0);
usart_flag_clear(USART0, USART_FLAG_PERR);
}
if(usart_flag_get(USART0, USART_FLAG_ORERR)!= RESET)
{
usart_data_receive(USART0);
usart_flag_clear(USART0, USART_FLAG_ORERR);
}
if(usart_flag_get(USART0, USART_FLAG_FERR)!= RESET)
{
usart_data_receive(USART0);
usart_flag_clear(USART0, USART_FLAG_FERR);
}
if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) !=RESET)
{
usart_flag_clear(USART0, USART_FLAG_RBNE);
data = usart_data_receive(USART0);
dri_rs485_rcv(data);
}
}
上述方法與中斷接收時(shí)將數(shù)據(jù)直接存入rx_buf,等待收完再處理的區(qū)別在于接收過程,其他沒什么區(qū)別。
純屬記錄學(xué)習(xí),如有助益,不勝歡喜;如有問題,歡迎指正!

浙公網(wǎng)安備 33010602011771號(hào)