admin管理员组文章数量:1558883
第一次用兆易创新32位arm,感觉同为国产,确实不如华大改动(创新)大,至少给人的感觉几乎照搬ST的,虽然两者开发可参考资料都少的可怜;
对于USARTx的驱动配置步骤:
https://blog.csdn/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);
}
}
}
版权声明:本文标题:gd32f303在IAR下的printf串口助手打印+串口收发配置 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727404874a1113259.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论