gd32f303在IAR下的printf串口助手打印+串口收发配置

第一次用兆易创新32位arm,感觉同为国产,确实不如华大改动(创新)大,至少给人的感觉几乎照搬ST的,虽然两者开发可参考资料都少的可怜;
对于USARTx的驱动配置步骤:
https://blog.csdn.net/JackieCoo/article/details/126777665(可参考)
1、以USART0为例(查询方式)
使能GPIOA时钟;
使能USART0时钟;
使能复用功能AF时钟;
配置GPIOA的输出模式AF-PP,50MZ,PA9 TX;
配置GPIOA的输入模式IN-FLOATING,50MZ,PA10 RX;
复位USART0;
设置波特率115200;(主从机波特率一致)
数据格式8bit数据位、无奇偶校验、1bit停止+1bit起始;
使能发送器;
使能接收器;
使能USART0外设;
(采用中断方式可使能中断收发标志,参考GD32官方库,以上都可直接调用GD32官方库函数实现,不用手动底层驱动配置);
2、收发函数

void  usart_reveive(uint8_t *r_array,uint8_t length)
{
	uint8_t j = 0;
	while(j<length)
	{	
		while(RESET == usart_flag_get(USART0,USART_FLAG_RBNE));//这个接收标志是非空置1,就是当缓冲区不为空时,即有数据时要让CPU取走数据,即赋值给内存;当RBNE置1的时候跳出等待循环;
		r_array[j] = usart_data_receive(USART0);
		j++;
	}
}

void  usart_send(uint8_t *t_array,uint8_t length)
{
	uint8_t i = 0;
	while(i<length)
	{	
		usart_data_receive(USART0,USART_FLAG_TBE);
		while(RESET == usart_flag_get(USART0,USART_FLAG_TBE));//这个发送标志是空置1,就是当缓冲区为空时,即缓冲区无数据时要让CPU去放数据,当TBE置1的时候跳出等待循环;
		i++;
	}
}
uint8_t receive_trans[10];//串口助手发10个,再原值返回给它10个
int main()
{
	while(1)
	{
		//串口助手pc端与MCU的互动;
		usart_reveive(receive_trans,10);
		usart_send(receive_trans,10);
	}
}

3、当写完编译烧录成功以后,你会发现串口助手未必就能正常显示你收发的数据,可能乱码(前提是你串口号,波特率,数据格式这些常规选择正确,这个就不用说了),这时候关键就需要你去看看你板子硬件电路提供的晶振源了,看看systemClock的时钟源到底是多少,官库里有get_XX_Clock函数(每种ARM片子都有相应的函数);一般都是默认的晶振源是内部RC振荡器,有的会接外部晶振(具体看你硬件板子怎么设计的);这个时候如果选用外部晶振源,官库里关于外部晶振的宏定义一定要保持和实际外部晶振源(比如说外接了一个16M的)一致;
4、同样在IAR环境下使用printf要比keil好设置些,只需要调stdio.h函数,设置一下full,然后重定义fputc函数就行,如果出现乱码还是可能因为软件配置的时钟源的原因影响导致的;
5、关于中断方式的收发逻辑:
【注意】在连续接收的时候出现数据接收错位的原因?
TXE置1的条件:是将数据(10bit)完全从buffer缓冲区拿出到移位寄存器后;
RXNE置1的条件:是将数据(10bit)完全从移位寄存器移到buffer缓冲区后;
例如:发送trans[6]=0,1,2,3,4,5(发送帧);接收receive[6] = 0,1,2,3,4,5(接收帧);中间协议假设已给定会按照发送帧和接收帧的内容顺序通信;但是实际过程中有 while(rxcount < rx_size) 这句接收等待和没有这句语句的区别就是,当有等待的时候会在一次轮询当中(一拍当中)完全等到数组receive[6]把6个数据接收赋值完成,所以顺序不会错位;但是当没有等待的时候,RXNE是每隔一个很短时间才置1的,data寄存器被读出后,标志清0退出ISR,然后主函数会在这个间隔去执行自己,有可能接收端的下个数据在路上时(亦还没到移位寄存器将数据完全移入biffer缓冲区时),主函数已经执行下一拍到重新开始发送处了,这时候又开始进行发送中断了,所以上一拍就相当于成功接收了一个字节的数据,如果连续3拍因为硬件的问题都只来的及成功接收一个字节,那就会出现receive[6] = 0,0,0,0,1,2(接收帧)的现象(还需要注意计数值是全局变量);所以当没有 while(rxcount < rx_size) 这句接收等待时,就只能靠硬件传输的足够快和连续,能将receive[6]这个6个字节数据在usart_interrupt_enable(USART0, USART_INT_RBNE)和txcount = rxcount = 0;之间执行进6次接收中断执行完,这样赋值顺序才不会错位,按照接收receive[6] = 0,1,2,3,4,5(接收帧);

uint8_t tx_size = TRANSMIT_SIZE;
uint8_t rx_size = 32;
uint8_t txcount = 0; 
uint16_t rxcount = 0;   //注意计数值是全局变量
/* enable USART TBE interrupt */  
    usart_interrupt_enable(USART0, USART_INT_TBE);
    
    /* wait until USART send the transmitter_buffer */
    while(txcount < tx_size);
    
    while(RESET == usart_flag_get(USART0, USART_FLAG_TC));
    
    usart_interrupt_enable(USART0, USART_INT_RBNE);  //
    
    /* wait until USART receive the receiver_buffer */
    while(rxcount < rx_size);
    txcount = rxcount = 0;

/***********************************************************************/
void USART0_IRQHandler(void)
{
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){
        /* receive data */
        rxbuffer[rxcount++] = usart_data_receive(USART0);
        if(rxcount == rx_size){
            usart_interrupt_disable(USART0, USART_INT_RBNE);
        }
    }
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE)){
        /* transmit data */
        usart_data_transmit(USART0, txbuffer[txcount++]);
        if(txcount == tx_size){
            usart_interrupt_disable(USART0, USART_INT_TBE);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SUR0608

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值