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满之后的那一次命令可能会识别失败,需要在发一次命令。

纯属记录学习,如有问题,欢迎指正!

posted @ 2023-03-06 16:43  xMofang  阅读(203)  评论(0编辑  收藏  举报