MAX32630/MAX32625学习:UART串口初始化、发送函数,接收中断及实验(绝对实用)

/*******************************************************************
内容:串口配置,给出中断式串口通信,详细的寄存器作用解析
作者:Justice_Gao
日期:2017年7月29日

问题描述:
参考源代码中串口通信程序初始化设置以及通信的方式,比较难理解,和STM32F4的串口通信不同,特别是接收
这里我提供一个中断式的串口接收处理函数以及串口发送处理
思路采用STM32F4的方式,接收1个字节,触发一次中断,然后将接收到的字节存入数组中,或者环形缓存区,如ringbuffer
MAX32625的串口接收和发送自带了32字节深度的FIFO

注意事项:
(1)在调试debugger模式下,不要在中断中设置断点,因为FIFO一直在缓存数据,如果FIFO的接收缓存处理比串口接收传输
慢,则当接收数据大于32字节时,会出现溢出现象,会丢失32字节以后的数据,可以在主函数中设置断点,查看接收到的数据,这
一点非常重要
(2)若在发送数据前后设置RX_FIFO_EN的使能,需要加一定的延时,原因是,数据为发送完,就使能了RX_FIFO_EN,会丢失最后
两个字节

*******************************************************************/
(1)首先,介绍串口的初始化设置,配置串口UART1

  1. /*******************************************************************************
  2. * Function Name  : USART1_Configuration
  3. * Description    : Configures the different GPIO ports.
  4. * Input          : None
  5. * Output         : None
  6. * Return         : None
  7. *******************************************************************************/
  8. void USART1_Configuration(uint32_t UART_BAUD)
  9. {
  10.     // Initialize the UART
  11.     uart_cfg_t cfg;
  12.     cfg.parity = UART_PARITY_DISABLE;
  13.     cfg.size = UART_DATA_SIZE_8_BITS;
  14.     cfg.extra_stop = 0;
  15.     cfg.cts = 1;
  16.     cfg.rts = 1;
  17.     cfg.baud = UART_BAUD;

  18.     sys_cfg_uart_t sys_cfg;
  19.     sys_cfg.clk_scale = CLKMAN_SCALE_AUTO;
  20.     sys_cfg.io_cfg = (ioman_cfg_t)IOMAN_UART(1, IOMAN_MAP_A, IOMAN_MAP_A, IOMAN_MAP_A, 1, 1, 1);
  21.                 UART_Init(MXC_UART1, &cfg, &sys_cfg);
  22.                     //接收到1个字节触发中断
  23.                 MXC_UART1->rx_fifo_ctrl = (0 <<
  24.                 MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS);
  25.                 //设置FIFO填充中断使能
  26.                 MXC_UART1->inten |= MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY;
  27.         
  28. }
复制代码

在源代码中,是没有
  1. //接收到1个字节触发中断
  2. MXC_UART1->rx_fifo_ctrl = (0 <<
  3. MXC_F_UART_RX_FIFO_CTRL_FIFO_AF_LVL_POS);
  4. //设置FIFO填充中断使能
  5. MXC_UART1->inten |= MXC_F_UART_INTEN_RX_FIFO_NOT_EMPTY;
复制代码



这两条语句的,第一条语句的作用是设置接收到1个字节触发一次串口中断,即与STM32F4的串口接收方式相同;第二条语句的作用就是使能中断标志,如果串口接收FIFO不为空,则中断处理。

(2)初始化串口后,编写串口接收中断函数
  1. void UART1_IRQHandler(void)
  2. {
  3.                 uint8_t value;
  4. //                static uint16_t count;
  5.                 if(((UART_GetFlags(MXC_UART1))&MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY))
  6.                 {
  7.                         value=UART1_GetChar();
  8.                        if(rb_can_write(&u_ring_buff) > 0)
  9.                         {
  10.                                   rb_write(&u_ring_buff, &value, 1);//将数据写入ringbuffer中
  11.                                                 
  12.                         }
  13.                         else
  14.                         {
  15.                                 rb_new(&u_ring_buff);
  16.                         }                                
  17.                         UART_ClearFlags(MXC_UART1,MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY|MXC_F_UART_INTFL_RX_FIFO_AF); //清楚中断标志
  18.                 }
  19. }
复制代码

其中,UART1_GetChar();为接收一个字节函数,代码为
  1. //单个字节接收,从RX_FIFO中读取
  2. uint8_t UART1_GetChar(void)
  3. {
  4.     return MXC_UART1_FIFO->rx;
  5. }
复制代码

是不是很简单,思路和STM32F4一模一样,如果你按照源代码去调试,估计一时半会调不出来,我也研究了好久,建议大家debugger模式下多看看UART的寄存器值是如何变化的。
(3)串口发送函数
  1. //单个字节发送,存入TX_FIFO中,然后发送
  2. void UART1_PutChar(const uint8_t data)
  3. {
  4.     // Wait for TXFIFO to not be full
  5.     while ((MXC_UART1->tx_fifo_ctrl & MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY) == MXC_F_UART_TX_FIFO_CTRL_FIFO_ENTRY);
  6.     MXC_UART1->intfl = MXC_F_UART_INTFL_TX_DONE; // clear DONE flag for UART_PrepForSleep
  7.     MXC_UART1_FIFO->tx = data;
  8. }

  9. /*******************************************************************************
  10. * Function Name  : SendToUart
  11. * Description    : Send data to Uart
  12. * Input          : buf:Start address; packLen:data len
  13. * Output         : None
  14. * Return         : None
  15. * Attention                   :
  16. *******************************************************************************/

  17. void SendToUart(mxc_uart_regs_t * MXC_UARTx,uint8_t* buf, uint16_t packLen)
  18. {
  19.         uint16_t i;
  20.         UART_DrainRX(MXC_UART1);
  21.         for(i=0;i<packLen;i++)
  22.         {
  23.                 UART1_PutChar(buf);
  24.         }
  25.         (MXC_UARTx->ctrl) |= MXC_F_UART_CTRL_RX_FIFO_EN;
  26. }
复制代码

发送函数较为简单,这里不做详细解析


具体的解析我就不写了,大家自己选择用哪种,大家应该都比较习惯第一种吧,下面我用第1种方法做个实验。
实验结果:串口发送什么数据,则返回:已接收:xx数据

 
重要的事情再说一遍,
注意事项:
(1)在调试debugger模式下,不要在中断中设置断点,因为FIFO一直在缓存数据,如果FIFO的接收缓存处理比串口接收传输慢,则当接收数据大于32字节时,会出现溢出现象,会丢失32字节以后的数据,可以在主函数中设置断点,查看接收到的数据,这一点非常重要
(2)若在发送数据前后设置RX_FIFO_EN的使能,需要加一定的延时,原因是,数据为发送完,就使能了RX_FIFO_EN,会丢失最后两个字节

猜你喜欢

转载自blog.csdn.net/jdsnpgxj/article/details/79684259