嵌入式学习小组
直播中

莫循虎

7年用户 889经验值
私信 关注

关于M451的串口接收问题求解

由于新项目使用了新唐的M451,由于对款MCU不熟悉,今天碰到一个串口接收的问题,弄了很久没有搞定,可否麻烦大家说下串口接收的用法,就以串口0为例,我不是很明白这个串口中断函数里会有一个UART_INTSTS_RDAINT_Msk和一个UART_INTSTS_RXTOINT_Msk,一个数据接收中断和一个接收超时中断,怎么样区分,为什么两个一起用?还有个问题,我老是一次只能收到16个字节的数据,反复测试了都不行,麻烦大家帮忙详细说明M451串口的使用方法和配置代码,比如,我现在要接收长度大于16字节的数据,该如何配置,总这对个串口实在头大,之前使用STM32的串口简单明了,在此先谢谢大家了!

我的串口0初始配置代码如下,也不是很懂:
void UART0_Init(void)//visual data process
{
        memset(Uart0_rx_buf,0,sizeof(Uart0_rx_buf));
        memset(Uart0_tx_buf,0,sizeof(Uart0_tx_buf));
        Uart0_rx_Count = 0;                        //接收字节个数        
      Uart0_tx_Count = 0;                        //发送字节个数
        Uart0_rx_P = 0;                                //接收指针
        Uart0_tx_P = 0;                                //发送指针
        Uart0_rx_Finish = 0;                //接收完成标志
        Uart0_tx_Finish = 0;                //发送完成标志
        
        SYS->GPD_MFPL = SYS_GPD_MFPL_PD1MFP_UART0_TXD | SYS_GPD_MFPL_PD0MFP_UART0_RXD;
        
    SYS_ResetModule(UART0_RST);
    UART_Open(UART0, 115200);
        
        UART0->FIFO &= ~UART_FIFO_RFITL_Msk;
        UART0->FIFO |= UART_FIFO_RFITL_14BYTES;
    //UART0->FIFO|=UART_FIFO_RFITL_1BYTE;
        
        UART_SettimeoutCnt(UART0, 40);
        
    UART_EnableInt(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
//        NVIC_EnableIRQ(UART0_IRQn);
}

这个是中断处理函数,是之前的工程师做的
void UART0_TEST_HANDLE(void)//for visual data process
{
    uint8_t u8InChar = 0xFF;
        uint8_t i;
   
    uint32_t u32IntSts = UART0->INTSTS;
    //接收有效数据
    if(u32IntSts & UART_INTSTS_RDAINT_Msk)
    {      
        while(UART_GET_RX_EMPTY(UART0)==0)
        {
            //read data
            u8InChar = UART_READ(UART0);
            Uart0_rx_buf[Uart0_rx_P]=u8InChar;
                        Uart0_rx_P
    }
   
        //接收超时中断
        if(u32IntSts & UART_INTSTS_RXTOINT_Msk)
    {
        //Uart0_tx_Finish = 0;
        //Uart0_rx_P = 0;
                /*i=0;
        while(UART_GET_RX_EMPTY(UART0)==0)
        {
            u8InChar = UART_READ(UART0);
            Uart0_rx_buf[Uart0_rx_P]=u8InChar;
                        Uart0_rx_P ++;      
            
               
                If (Uart0_rx_P==32)      
                           {
                                Uart0_rx_Finish = 1;
                Uart0_rx_Count = Uart0_rx_P;
                Uart0_rx_P = 0;
                             }

               

        
   
        //发送完成中断
    if(u32IntSts & UART_INTSTS_THREINT_Msk)
    {
                if(Uart0_tx_P=Uart0_tx_Count)
                                {                                        UART_DISABLE_INT(UART0, UART_INTEN_THREIEN_Msk);
                                        Uart0_tx_Finish = 0;
                                        Uart0_tx_P = 0;
                                        break;
                                }
                                if(i>=16)break;
                        }
                }
                else
                {
                        UART_DISABLE_INT(UART0, UART_INTEN_THREIEN_Msk);
                        Uart0_tx_Finish = 0;
                        Uart0_tx_P = 0;
                }
    }
}



回帖(1)

维生素B2

2024-4-24 17:47:44
在M451中,串口接收可以使用中断方式或者轮询方式。

1.中断方式

中断方式需要先开启中断,并在中断处理函数中进行数据的处理。

首先需要在代码中进行初始化串口:

```c
UART_Open(UART0, 115200);
```

然后开启接收中断:

```c
UART_EnableInt(UART0, UART_INTEN_RDAIEN_Msk); // 接收到至少一个数据字节时触发中断
```

在中断处理函数中判断是数据接收中断还是超时中断,并对数据进行处理:

```c
void UART0_IRQHandler()
{
    uint32_t  u32IntSts = UART0->INTSTS;

    if ((u32IntSts & UART_INTSTS_RDAINT_Msk) || (u32IntSts & UART_INTSTS_RXTOINT_Msk))
    {
        // 数据接收中断 or 接收超时中断

        while (UART_IS_RX_READY(UART0))
        {
            // 读取串口接收缓存内的数据
            uint8_t u8RxData = UART_READ(UART0);

            // 进行处理,例如将接收到的数据存入缓存数组中
        }
    }
}
```

其中,UART_INTSTS_RDAINT_Msk 表示数据接收中断,UART_INTSTS_RXTOINT_Msk 表示接收超时中断。可以使用按位或的方式同时判断两种中断情况。

2.轮询方式

轮询方式需要循环读取串口接收缓存的数据,在读取前需要判断缓存内是否有数据可读。

初始化串口:

```c
UART_Open(UART0, 115200);
```

循环读取串口接收缓存中的数据:

```c
while (1)
{
    if (UART_IS_RX_READY(UART0))
    {
        // 读取串口接收缓存内的数据
        uint8_t u8RxData = UART_READ(UART0);

        // 进行数据处理
    }
}
```

另外,对于只能接收到16个字节的问题,可以设置接收缓存的大小来解决。在 M451 中,每个串口都有 2KB 的接收缓存,可以通过下面的方式进行设置:

```c
// 设置 UART0 接收缓存区大小为 256 字节
UART0->FIFO &= ~UART_FIFO_RFITL_Msk;
UART0->FIFO |= UART_FIFO_RFITL_4BYTES;
```

其中,UART_FIFO_RFITL_Msk 表示接收 FIFO 中断触发深度, UART_FIFO_RFITL_4BYTES 表示 FIFO 中有 4 字节时触发中断。可以根据实际需求设置不同的大小。

总之,在使用 M451 的串口接收时,需要注意中断和缓存的相关设置,确保接收数据的准确性和稳定性。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分