GD32F407 cmd USART+循环队列接收
中断:
void USART1_IRQHandler(void)
{
int data = 0;
if(usart_flag_get(USART1, USART_FLAG_PERR)!= RESET)
{
usart_data_receive(USART1);
usart_flag_clear(USART1, USART_FLAG_PERR);
}
if(usart_flag_get(USART1, USART_FLAG_ORERR)!= RESET)
{
usart_data_receive(USART1);
usart_flag_clear(USART1, USART_FLAG_ORERR);
}
if(usart_flag_get(USART1, USART_FLAG_FERR)!= RESET)
{
usart_data_receive(USART1);
usart_flag_clear(USART1, USART_FLAG_FERR);
}
if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) !=RESET)
{
usart_flag_clear(USART1, USART_FLAG_RBNE);
data = usart_data_receive(USART1);
dri_debug_rcv(data);
}
}
usart.c
/*******************************************************************************************************
* globle varible
*******************************************************************************************************/
usart_device_t usart_device_debug = {
.rcv_state=0,
.front = 0,
.rear = 0,
};
/*
*********************************************************************************************************
* dri_debug_init()
*
* Description : Init debug module.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : bsp.c.
*
* Note(s) : none.
*********************************************************************************************************
*/
void dri_debug_init(void)
{
rcu_periph_clock_enable(DRI_PERIPH_DEBUG_USART);
rcu_periph_clock_enable(RCU_GPIOD);
gpio_af_set(DRI_DEBUG_TX_PORT, GPIO_AF_7, DRI_DEBUG_TX_PIN);
gpio_af_set(DRI_DEBUG_RX_PORT, GPIO_AF_7, DRI_DEBUG_RX_PIN);
gpio_mode_set(DRI_DEBUG_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, DRI_DEBUG_TX_PIN);
gpio_output_options_set(DRI_DEBUG_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, DRI_DEBUG_TX_PIN);
gpio_mode_set(DRI_DEBUG_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, DRI_DEBUG_RX_PIN);
gpio_output_options_set(DRI_DEBUG_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, DRI_DEBUG_RX_PIN);
/* USART configure */
usart_deinit(DRI_DEBUG_USART);
// usart_word_length_set(DRI_DEBUG_USART, USART_WL_8BIT); // 字长
// usart_stop_bit_set(DRI_DEBUG_USART, USART_STB_1BIT); // 停止位
// usart_parity_config(DRI_DEBUG_USART, USART_PM_NONE);
usart_baudrate_set(DRI_DEBUG_USART, 115200U);
// usart_hardware_flow_rts_config(DRI_DEBUG_USART, USART_RTS_DISABLE);
// usart_hardware_flow_cts_config(DRI_DEBUG_USART, USART_CTS_DISABLE);
usart_receive_config(DRI_DEBUG_USART, USART_RECEIVE_ENABLE);
usart_transmit_config(DRI_DEBUG_USART, USART_TRANSMIT_ENABLE);
usart_enable(DRI_DEBUG_USART);
nvic_irq_enable(USART1_IRQn, 0, 0); //串口中断配置
usart_interrupt_disable(DRI_DEBUG_USART, USART_INT_RBNE); //失能串口接收中断
usart_flag_clear(DRI_DEBUG_USART, USART_FLAG_RBNE); //清除串口接收标志位
usart_interrupt_flag_clear(DRI_DEBUG_USART, USART_INT_FLAG_RBNE); //清除串口接收中断标志位
usart_interrupt_enable(DRI_DEBUG_USART, USART_INT_RBNE); //使能串口接收中断
}
/*
*********************************************************************************************************
* fputc()
*
* Description : function printf map.
*
* Argument(s) : 1) ch : data.
* 2) f :
* Return(s) : none.
*
* Caller(s) : .
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_PRINTF
#ifdef DEF_PRINTF
int fputc(int ch, FILE* f)
{
uint8_t tch=ch;
dri_usart_transmit_char(DRI_DEBUG_USART, tch);
return ch;
}
#else
int fputc(int ch, FILE* f)
{
return ch;
}
#endif
/*
*********************************************************************************************************
* dri_debug_process_cmd()
*
* Description : Process debug commend.
*
* Argument(s) : 1) cmd : commend.
* 2) cfg : module configration
* Return(s) : none.
*
* Caller(s) : .
*
* Note(s) : none.
*********************************************************************************************************
*/
static int dri_debug_process_cmd(char* cmd)
{
uint8_t TCAttn;
if(strcmp(cmd,"help")==0)
{
printf(" ver Version\r\n");
printf(" reboot Reboot system\r\n");
}
if(strcmp(cmd,"ver")==0)
{
printf("version : %s %s\r\n",__DATE__, __TIME__);
}
if(strcmp(cmd,"reboot")==0)
{
NVIC_SystemReset();
}
return 0;
}
void dri_debug_buf_empty(void)
{
dri_usart_empty(&usart_device_debug);
}
int dri_debug_rcv(uint8_t data)
{
int rv = 0;
if((data >= 0x20 && data <= 0x7f)|| data == 0x08) // printable char
{
usart_data_transmit(DRI_DEBUG_USART, data);
if(data != 0x7f || data != 0x08) // backspace
{
rv = dri_usart_plush(&usart_device_debug, data);
}
}
else if(data == 0x0D) // "\r"
{
printf("\r\n");
rv |= dri_usart_plush(&usart_device_debug, data);
}
if(rv != 0)
{
printf("queue is full\r\n");
dri_debug_buf_empty();
}
return rv;
}
int dri_debug_buf_pop(uint8_t *data)
{
int rv = 0;
rv = dri_usart_pop(&usart_device_debug, data);
return rv;
}
static int dri_debug_buf_is_empty(void)
{
int rv = 0;
rv = dri_usart_buf_is_empty(&usart_device_debug);
return rv;
}
/*
*********************************************************************************************************
* dri_debug_check_usart1()
*
* Description : Process Usart1 receive data.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : .
*
* Note(s) : none.
*********************************************************************************************************
*/
static uint8_t dbug_rx_buf[MAX_DEBUG_LEN] = {0};
static uint8_t dbug_rx_buf_cnt = 0;
void dri_debug_rcv_process(void)
{
char* ptr;
uint8_t i=0;
uint8_t data;
int rv = 0;
rv = dri_debug_buf_pop(&data);
if(rv != 0) {
return;
}
DBG_DEBUG(" pop data is 0x%02x\r\n", data);
dbug_rx_buf[dbug_rx_buf_cnt] = data;
dbug_rx_buf_cnt = (dbug_rx_buf_cnt + 1) % MAX_DEBUG_LEN;
DBG_DEBUG(" front is 0x%02x dbug_rx_buf_cnt is 0x%02x\r\n", usart_device_debug.front, dbug_rx_buf_cnt);
if (data == 0x0D) // "\r"
{
ptr = strstr((char*)dbug_rx_buf, "\r");
*ptr=0;
dri_debug_process_cmd((char*)dbug_rx_buf);
ptr++;
while(*ptr=='\r' || *ptr=='\n')
{
ptr++;
}
for(i = 0; ptr[i] != 0; i++)
{
dbug_rx_buf[i]=ptr[i];
ptr[i]=0;
}
dbug_rx_buf[i]=ptr[i]; //add \0 at the end
dbug_rx_buf_cnt = strlen((char*)dbug_rx_buf);
memset(dbug_rx_buf + dbug_rx_buf_cnt, 0, sizeof(dbug_rx_buf) - dbug_rx_buf_cnt);
printf(">");
}
}
该程序接收时将数据push到缓存,每次循环pop一个byte,并将其存入dbug_rx_buf;当遇到回车时处理命令。
usart_device_t是一个循环队列的结构体;
上述有一个问题:当dbug_rx_buf满之后的那一次命令可能会识别失败,需要在发一次命令。
纯属记录学习,如有问题,欢迎指正!