[MM32软件] MM32F0140 UART1中断接收和UART1中断发送

[复制链接]
 楼主| 我喜欢打游戏 发表于 2023-2-24 15:33 | 显示全部楼层 |阅读模式
提要:

学习MM32F0140 UART1中断接收和UART1中断发送数据,通过上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0140的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1中断发送函数,把UART1中断接收到的数据原样发送到串口助手显示出来。


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:33 | 显示全部楼层
内容:

1、MM32F0140简介:

(1)MM32F0140微控制器是基于Arm® Cortex®-M0内核,最高工作频率可达72MHz;

(2)供电电压支持:2.0V - 5.5V;

(3)多达64KB的Flash,8KB的SRAM;

(4)1个I2C;

(5)3个UART;

(6)1个12位共13通道的ADC;

(7)2个I2C或I2S;

(8)1个16位高级定时,1个16位和1个32位的通用定时器,3个16位的基本定时器;

(9)1个FlexCAN接口;

(10)1个IWDG和1个WWDG看门狗。


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:34 | 显示全部楼层
2.初始化MM32F0140 UART1和NVIC中断:

MM32F0140 UART1的GPIO初始化,根据MM32F0140的DS数据手册选择PA9:UART1_TX,PA10:UART1_RX做为UART1的发送和接收数据的引脚,具体配置步骤,及其初始化如下所示:

(1)使能GPIOA外设时钟;

(2)配置IO管脚GPIO_AFx复用为UART1功能;

(3)配置UARTx IO的管脚;

(4)配置GPIO的输出速度;

(5)配置IO管脚的工作模式;

(6)根据GPIOA配置的参数整体初始化GPIO各管脚的成员参数。
  1. static void Bsp\_UART1\_GPIO\_Init(void)
  2. {
  3. GPIO\_InitTypeDef GPIO\_InitStruct;

  4. //Enable GPIOA Clock
  5. RCC\_AHBPeriphClockCmd(RCC\_AHBENR\_GPIOA, ENABLE);
  6. GPIO\_PinAFConfig(GPIOA, GPIO\_PinSource9, GPIO\_AF\_1);
  7. GPIO\_PinAFConfig(GPIOA, GPIO\_PinSource10, GPIO\_AF\_1);

  8. //PA9:UART1\_TX
  9.     GPIO\_StructInit(&GPIO\_InitStruct);
  10. GPIO\_InitStruct.GPIO\_Pin = GPIO\_Pin\_9;
  11. GPIO\_InitStruct.GPIO\_Speed = GPIO\_Speed\_50MHz;
  12. GPIO\_InitStruct.GPIO\_Mode = GPIO\_Mode\_AF\_PP;
  13. GPIO\_Init(GPIOA, &GPIO\_InitStruct);

  14. //PA10:UART1\_RX
  15.     GPIO\_InitStruct.GPIO\_Pin = GPIO\_Pin\_10;
  16. GPIO\_InitStruct.GPIO\_Mode = GPIO\_Mode\_IPU;
  17. GPIO\_Init(GPIOA, &GPIO\_InitStruct);
  18. }
MM32F0140 UART1和NVIC中断优先级初始化,具体配置步骤,及其初始化如下所示:

(1)使能UART1外设时钟;

(2)调用之前配置的UART1 GPIO初始化函数;

(3)调配置UART1通信波特率为115200;

(4)配置UART1字长为8位;

(5)配置UART1收发数据为1位停止位;

(6)配置UART1收发数据为无奇偶校验位;

(7)配置UART1允许串口收发数据;

(8)根据以上配置参数初始化UART1结构体成员;

(9)使能UART1中断接收功能;

(10)配置UART1的NVIC中断优先级为0,并使能和初始化NVIC中断(优先级为0-3均可,参数越小优先级越高)。

根据以上配置参数,初始化UART1并使能UART1,则UART1初始化代码如下所示:
  1. void Bsp\_UART1\_NVIC\_Init(u32 baudrate)
  2. {
  3. UART\_InitTypeDef UART\_InitStruct;
  4. NVIC\_InitTypeDef NVIC\_InitStruct;

  5. //Enable UART1 Clock
  6. RCC\_APB2PeriphClockCmd(RCC\_APB2ENR\_UART1, ENABLE);

  7. Bsp\_UART1\_GPIO\_Init();

  8. UART\_StructInit(&UART\_InitStruct);
  9. UART\_InitStruct.BaudRate = baudrate;
  10. //The word length is in 8-bit data format.
  11.     UART\_InitStruct.WordLength = UART\_WordLength\_8b;
  12. UART\_InitStruct.StopBits = UART\_StopBits\_1;
  13. //No even check bit.
  14.     UART\_InitStruct.Parity = UART\_Parity\_No;
  15. //No hardware data flow control.
  16.     UART\_InitStruct.HWFlowControl = UART\_HWFlowControl\_None;
  17. UART\_InitStruct.Mode = UART\_Mode\_Rx | UART\_Mode\_Tx;
  18. UART\_Init(UART1, &UART\_InitStruct);

  19. UART\_ITConfig(UART1,UART\_IT\_RXIEN, ENABLE);

  20. //UART1 NVIC
  21.     NVIC\_InitStruct.NVIC\_IRQChannel = UART1\_IRQn;
  22. NVIC\_InitStruct.NVIC\_IRQChannelPriority = 0;
  23. NVIC\_InitStruct.NVIC\_IRQChannelCmd = ENABLE;
  24. NVIC\_Init(&NVIC\_InitStruct);

  25. UART\_Cmd(UART1, ENABLE);
  26. }


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:35 | 显示全部楼层

3.编写MM32F0140 UART1使能中断发送函数

(1)定义与UART1中断发送相关的缓存、变量,代码如下所示:

  1. //UART1 Tx Buffer
  2. u8 gUART1\_Tx\_Buf[UART1\_TXD\_LEN] = {0x00};
  3. //UART1 Tx Lenth
  4. u8 gUART1\_Tx\_Lenth = 0;
  5. //UART1 Tx Count
  6. u8 gUART1\_Tx\_Real\_Cnt = 0;
  7. //UART1 Tx OK Flag
  8. u8 gUART1\_Tx\_OK\_Flag = 0;

(2)根据以上步骤(1)中定义,编写MM32F0140 UART1使能中断发送函数,代码如下所示:

  1. void Bsp\_UART1\_Interrupt\_Send\_Data(UART\_TypeDef* Uart, u8 *pBuf,u8 data\_lenth)
  2. {
  3. gUART1\_Tx\_Real\_Cnt = 0;
  4. gUART1\_Tx\_Lenth = data\_lenth;
  5. memcpy(gUART1\_Tx\_Buf,pBuf,data\_lenth);
  6. UART\_ITConfig(Uart, UART\_IT\_TXIEN, ENABLE );
  7. }


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:35 | 显示全部楼层

4.编写MM32F0140 UART1中断接收和中断发送函数:

MM32F0140 UART1中断接收和中断发送函数代码如下所示,当UART1中断发送完数据后需失能中断发送,当UART1中断发送数据时再次使能中断发送即可。

  1. void UART1\_IRQHandler(void)
  2. {
  3. u8 Recv;

  4. if(UART\_GetITStatus(UART1, UART\_IT\_RXIEN) != RESET)
  5. {
  6. UART\_ClearITPendingBit(UART1, UART\_IT\_RXIEN);

  7. Recv = UART\_ReceiveData(UART1);

  8. gUART1\_Rx\_Buf[gUART1\_Rx\_Cnt] = Recv;

  9. if(gUART1\_Rx\_Cnt < UART1\_RXD\_LEN-1)
  10. {
  11. gUART1\_Rx\_Cnt++;
  12. }
  13. else
  14. {
  15. gUART1\_Rx\_Cnt = 0;
  16. }
  17. if(gUART1\_Rx\_Cnt == 8)
  18. {
  19. UART1\_Rx\_Flag = true;
  20. }
  21. }
  22. if(UART\_GetITStatus(UART1, UART\_IT\_TXIEN) != RESET)
  23. {
  24. UART\_ClearITPendingBit(UART1, UART\_IT\_TXIEN);

  25. if(gUART1\_Tx\_Real\_Cnt < gUART1\_Tx\_Lenth)
  26. {
  27. UART\_SendData(UART1,(u8)gUART1\_Tx\_Buf[gUART1\_Tx\_Real\_Cnt]);
  28. gUART1\_Tx\_Real\_Cnt++;
  29. }
  30. else
  31. {
  32. UART\_ITConfig(UART1, UART\_IT\_TXIEN, DISABLE);
  33. gUART1\_Tx\_OK\_Flag = 1;
  34. }
  35. }
  36. }


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:36 | 显示全部楼层
5.编写MM32F0140 UART1处理中断接收和UART1使能中断发送函数:

MM32F0140 UART1处理中断接收和使能中断发送数据函数如下所示,当上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0140的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1使能中断发送函数,原样发送UART1中断接收到的数据到串口助手,代码如下所示:
  1. void Bsp\_UART1\_Recv\_Task(void)
  2. {
  3. if(UART1\_Rx\_Flag == true)
  4. {
  5. UART1\_Rx\_Flag = false;

  6. if((gUART1\_Rx\_Buf[0] == 0xAA) && (gUART1\_Rx\_Buf[1] == 0x01) && (gUART1\_Rx\_Buf[2] == 0x02) && (gUART1\_Rx\_Buf[3] == 0x03) && \
  7. (gUART1\_Rx\_Buf[4] == 0x04) && (gUART1\_Rx\_Buf[5] == 0x05) && (gUART1\_Rx\_Buf[6] == 0x06) && (gUART1\_Rx\_Buf[7] == 0x55))
  8. {
  9. Bsp\_UART1\_Interrupt\_Send\_Data(UART1,gUART1\_Rx\_Buf,gUART1\_Rx\_Cnt);
  10. }
  11. gUART1\_Rx\_Cnt = 0;
  12. memset(gUART1\_Rx\_Buf,0,sizeof(gUART1\_Rx\_Buf));
  13. }
  14. }


 楼主| 我喜欢打游戏 发表于 2023-2-24 15:36 | 显示全部楼层
6.MM32F0140 UART1中断发送UART1中断接收到的数据到上位机串口助手:

当上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0140的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1使能中断发送函数,采用UART1中断发送函数原样发送UART1中断接收到的数据到串口助手显示。

(1)在main函数中调用UART1 NVIC初始化函数;

(2)在main函数的while(1)主循环中调用UART1处理中断接收到的数据函数,循环检测UART1的接收中断是否接收到上位机串口助手下发的数据,如有收到就调用UART1使能中断发送函数,原样发送UART1中断接收到的数据到上位机串口助手上显示出来,代码如下所示,
  1. int main(void)
  2. {
  3. //UART1 NVIC Init Baudrate:115200
  4. Bsp\_UART1\_NVIC\_Init(UART1\_BAUDRATE);

  5. while(1)
  6. {
  7. //Test UART1 RX TX
  8. Bsp\_UART1\_Recv\_Task();
  9. }
  10. }


lihuami 发表于 2023-3-2 16:07 | 显示全部楼层
这个的最大的传输速度是多少?              
tpgf 发表于 2023-3-3 15:43 | 显示全部楼层
在什么情况下需要使用发送中断的功能呢
qcliu 发表于 2023-3-3 16:10 | 显示全部楼层
数据接收中断一般要非常注意缓存数据的处理
drer 发表于 2023-3-3 16:27 | 显示全部楼层
在什么情况下会进入发送中断函数呢
benjaminka 发表于 2023-3-3 22:01 | 显示全部楼层
MM32F0140 有多少个串口呢?
coshi 发表于 2023-3-4 13:31 | 显示全部楼层
我喜欢打游戏 发表于 2023-2-24 15:36
6.MM32F0140 UART1中断发送UART1中断接收到的数据到上位机串口助手:

当上位机串口助手发送8字节的十六进 ...

我们在发送串口数据的时候,单片机会自动给加校验位吗
kxsi 发表于 2023-3-4 14:01 | 显示全部楼层
coshi 发表于 2023-3-4 13:31
我们在发送串口数据的时候,单片机会自动给加校验位吗

应该不会自动添加的吧  不过这个也不难写 我们可以手动添加
wiba 发表于 2023-3-4 14:24 | 显示全部楼层
我喜欢打游戏 发表于 2023-2-24 15:36
6.MM32F0140 UART1中断发送UART1中断接收到的数据到上位机串口助手:

当上位机串口助手发送8字节的十六进 ...

如果是多个串口的话 如何保证均可以正常工作呢 就是优先级如何确定呢
vivilyly 发表于 2023-3-4 22:15 | 显示全部楼层
可以使用dma实现的吗?              
wwppd 发表于 2023-3-4 22:30 | 显示全部楼层
使用dma吧,简单方便一些。              
maudlu 发表于 2023-3-4 22:36 | 显示全部楼层
直接使用串口发送不行吗?              
jonas222 发表于 2023-3-5 10:38 | 显示全部楼层
使用dma吧,简单方便一些。              
kkzz 发表于 2023-3-5 11:10 | 显示全部楼层
直接使用串口发送不行吗?              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

627

帖子

1

粉丝
快速回复 返回顶部 返回列表