接下来,我们弄下串口的接收发送。之前生成的程序里面,把串口初始化,
printf重定向都弄好了,我们只需加上中断和接收的中断处理函数就可以了。
直接上代码:
根据电路图得知,指令用的串口4作为调试串口。
在串口初始化函数里面加上,开启接收中断的代码:
void gd_com_init(uint32_t usart_periph)
{
/* enable GPIO TX and RX clock */
rcu_periph_clock_enable(GD32_COM_TX_GPIO_CLK);
rcu_periph_clock_enable(GD32_COM_RX_GPIO_CLK);
/* enable USART clock */
rcu_periph_clock_enable(GD32_COM_CLK);
/* connect port to USARTx_Tx */
gpio_init(GD32_COM_TX_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GD32_COM_TX_PIN);
/* connect port to USARTx_Rx */
gpio_init(GD32_COM_RX_GPIO_PORT, GPIO_MODE_IN_FLOAtiNG, GPIO_OSPEED_50MHZ, GD32_COM_RX_PIN);
/* USART configure */
usart_deinit(usart_periph);
usart_baudrate_set(usart_periph, 115200U);
usart_word_length_set(usart_periph, USART_WL_8BIT);
usart_stop_bit_set(usart_periph, USART_STB_1BIT);
usart_parity_config(usart_periph, USART_PM_NONE);
usart_hardware_flow_rts_config(usart_periph, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(usart_periph, USART_CTS_DISABLE);
usart_receive_config(usart_periph, USART_RECEIVE_ENABLE);
usart_transmit_config(usart_periph, USART_TRANSMIT_ENABLE);
usart_enable(usart_periph);
//使能接收中断
usart_interrupt_enable(usart_periph, USART_INT_RBNE);
//配置中断等级
ECLIC_EnableIRQ(UART4_IRQn);
ECLIC_SetLevelIRQ(UART4_IRQn,1);
ECLIC_SetPriorityIRQ(UART4_IRQn,1);
}
//接收中断代码,参考自原子STM32的中断接收代码,个人觉得很好用。
uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
uint16_t USART_RX_STA=0; //接收状态标记
void UART4_IRQHandler(void)
{
uint8_t Res;
if(SET==usart_interrupt_flag_get(UART4,USART_INT_FLAG_RBNE))
{
Res =usart_data_receive(UART4); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
usart_interrupt_flag_clear(UART4,USART_INT_FLAG_RBNE);
}
}
在main函数里面的修改:
int main(void)
{
uint16_t t;
uint16_t len;
uint16_t times=0;
gd_rvstar_led_init(LED1);
gd_rvstar_led_init(LED2);
//gd_rvstar_key_init(KEY_WAKEUP,KEY_MODE_GPIO);
gd_rvstar_key_init(KEY_WAKEUP,KEY_MODE_EXTI);
//非向量中断
//ECLIC_Register_IRQ(EXTI0_IRQn,ECLIC_NON_VECTOR_INTERRUPT,
// ECLIC_LEVEL_TRIGGER,1,0,NULL);
//向量中断 注册外部中断
ECLIC_Register_IRQ(EXTI0_IRQn,ECLIC_VECTOR_INTERRUPT,
ECLIC_LEVEL_TRIGGER,1,0,NULL);
//注册串口中断
ECLIC_Register_IRQ(UART4_IRQn,ECLIC_NON_VECTOR_INTERRUPT,
ECLIC_LEVEL_TRIGGER,1,0,NULL);
__enable_irq();
while(1) {
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("rn您发送的消息为:rnrn");
for(t=0;t
{
usart_write(UART4, USART_RX_BUF[t]);//向串口1发送数据
}
printf("rnrn");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("rnRV_STAR 串口实验rn");
}
if(times%200==0)printf("请输入数据,以回车键结束n");
if(times%30==0) gd_rvstar_led_toggle(LED1);//闪烁LED,提示系统正在运行.
delay_1ms(10);
}
}
return 0;
}
编译,下载,查看现象:
|