[AT32F405] 【AT-START-F405测评】串口通讯

[复制链接]
 楼主| yinwuqing110 发表于 2024-5-3 22:54 | 显示全部楼层 |阅读模式
本帖最后由 yinwuqing110 于 2024-5-3 23:10 编辑

      上期借助雅特力官方主推的“AT32 Workbench图形化配置软件”进行工程设计,此次就官方提供的“AT32F402_405_Firmware_Library_V2.0.6.zip”工程示例包,展开此次串口通讯的话题。打开“printf”例程,工程路径:“AT32F402_405_Firmware_Library_V2.0.6\project\at_start_f405\examples\usart\printf”,该工程只用到串口输出,在此基础上添加串口接收功能接口函数。通过“AT_START_F405_V1.0_SCH”原理图文档,可知连接了AT-Link-EZ模块端的Type-C接口,意味着连接串口1。
原理图.jpg
       再者,我们需要查看管脚复用功能参考手册,以及需要注意串口状态寄存器的设置,主要查看“RM_AT32F402_405_CH_V2.00.pdf”文档,复用功能以及状态寄存器标志位设置正确后,才能在串口接收中断函数中处理接收数据。
复用寄存器.jpg
        串口接收中断函数中需要注意bit5、bit6两个位
串口状态寄存器.jpg
        接下来编写串口接收中断函数,在“at32f402_405_usart.c”中添加部分代码,见如下
  1. #include "at32f402_405_conf.h"

  2. u32 USART_RX_status = 0;
  3. u8 USART_RX_FLAG = 0;
  4. u8 USART_RX_BUF[USART_REC_LEN];

  5. void USART1_IRQHandler(void)
  6. {
  7.         u8 Res;
  8.         
  9.         if(usart_interrupt_flag_get(USART1, USART_RDBF_FLAG) != RESET)
  10.         {
  11.                 Res = usart_data_receive(USART1);        //读取接收到的数据
  12.                 if((USART_RX_status & 0x0020) == 0)//接收未完成
  13.                 {
  14.                         if(USART_RX_status & 0x0040)  //接收到0x0d
  15.                         {
  16.                                 if(Res != 0x0a)USART_RX_status = 0; //接收错误,重新开始接收
  17.                                 else
  18.                                 {
  19.                                         USART_RX_status |= 0x0020;     //接收完成
  20.                                         USART_RX_FLAG = 0x01;
  21.                                 }
  22.                         }
  23.                         else   //还没接收到到0x0d
  24.                         {
  25.                                 if(Res == 0x0d)USART_RX_status |= 0X0040;
  26.                                 else
  27.                                 {
  28.                                         USART_RX_BUF[USART_RX_status & 0X3fff] = Res;
  29.                                         USART_RX_status++;
  30.                                         if(USART_RX_status > USART_REC_LEN -1)USART_RX_status = 0;  //接收错误,重新开始接收
  31.                                 }
  32.                         }
  33.                 }
  34.         }
  35. }
main.c中具体代码实现如下:
  1. #include "at32f402_405_board.h"
  2. #include "at32f402_405_clock.h"
  3. #include "string.h"

  4. //用于命令解析用的命令值
  5. #define LED3ON        1
  6. #define LED3OFF        2
  7. #define LED4ON        3
  8. #define LED4OFF        4
  9. #define COMMANDERR        0XFF

  10. extern u16 USART_RX_status;
  11. extern u8 USART_RX_BUF[USART_REC_LEN];
  12. extern u8 USART_RX_FLAG;

  13. //将字符串中的小写字母转换为大写
  14. void LowerToUpp(u8 *str,u8 len)
  15. {
  16.         u8 i;
  17.         for(i=0;i<len;i++)
  18.         {
  19.                 if((96<str[i])&&(str[i]<123))        
  20.                 str[i]=str[i]-32;                                
  21.         }
  22. }

  23. u8 dataprocess(u8 * str)
  24. {
  25.         u8 commanddata = COMMANDERR;
  26.         if(strcmp((char *)str,"LED3ON")==0)commanddata = LED3ON;
  27.         else if(strcmp((char *)str,"LED3OFF")==0)commanddata = LED3OFF;
  28.         else if(strcmp((char *)str,"LED4ON")==0)commanddata = LED4ON;
  29.         else if(strcmp((char*)str,"LED4OFF")==0)commanddata = LED4OFF;
  30.         return commanddata;
  31. }        
  32. __IO uint32_t time_cnt = 0;

  33. int main(void)
  34. {
  35.   u8 len = 0;
  36.   u8 temp_string[100]={0};
  37.   u8 command = COMMANDERR;
  38.   system_clock_config();
  39.   at32_board_init();
  40.   uart_print_init(115200);
  41.   while(1)
  42.   {
  43.         if(USART_RX_FLAG == 0x01)
  44.         {
  45.                 len = USART_RX_status & 0x3fff;
  46.                 sprintf((char *)temp_string,"%s",USART_RX_BUF);
  47.                 LowerToUpp(temp_string,len);
  48.                 command = dataprocess(temp_string);
  49.                 if(command != COMMANDERR)
  50.                 {
  51.                         printf("receive command data: %d\r\n",command);
  52.                         switch(command)
  53.                         {
  54.                                 case LED3ON:
  55.                                         if(gpio_output_data_bit_read(LED3_GPIO,LED3_PIN)==RESET)
  56.                                                 printf("LED3 already ON!\r\n");
  57.                                         else
  58.                                                 at32_led_on(LED3);
  59.                                         break;
  60.                                 case LED3OFF:
  61.                                         if(gpio_output_data_bit_read(LED3_GPIO,LED3_PIN)==SET)
  62.                                                 printf("LED3 already OFF!\r\n");
  63.                                         else
  64.                                                 at32_led_off(LED3);
  65.                                         break;
  66.                                 case LED4ON:
  67.                                         if(gpio_output_data_bit_read(LED4_GPIO,LED4_PIN)==RESET)
  68.                                                 printf("LED4 already ON!\r\n");
  69.                                         else
  70.                                                 at32_led_on(LED4);
  71.                                         break;
  72.                                 case LED4OFF:
  73.                                         if(gpio_output_data_bit_read(LED4_GPIO,LED4_PIN)==SET)
  74.                                                 printf("LED4 already OFF!\r\n");
  75.                                         else
  76.                                                 at32_led_off(LED4);
  77.                                         break;
  78.                         }                                       
  79.                 }
  80.                 else
  81.                 {
  82.                         printf("此命令无效!\r\n");
  83.                 }
  84.                 USART_RX_status = 0;
  85.                 USART_RX_FLAG = 0;
  86.                 memset(USART_RX_BUF,0,sizeof(USART_RX_BUF));
  87.         }
  88.     else
  89.     delay_ms(500);
  90.   }
  91. }
      由以上源码可知,可通过Type-C数据线连接到电脑端,通过串口调试工具,发送“LED3ON”、“LED3OFF”、“LED4ON”、“LED4OFF”字符,即可对板上的LED3、LED4进行开、关控制,#define LED3ON:接收数据状态值1,#define LED3OFF:接收数据状态值2,#define LED4ON:接收数据状态值3,#define LED4OFF:接收数据状态值4;当然命令中字母的大小写均有效,不是其中的字符则会打印输出“此命令无效!”提示信息。中断函数中主要注意USART_STS寄存器的第5位与第6位的值。进行编译下载,调试效果。 识别调试器.jpg
下载算法.jpg
       在PC端上的串口调试助手上发送指定字符,则可实现对板上的LED3、LED4控制。
打印输出.jpg
      两盏灯同时被点亮的状态如下:
两颗LED点亮.jpg


caigang13 发表于 2024-5-4 08:31 来自手机 | 显示全部楼层
把配置工具和开发工具集成到一起就好了
trucyw 发表于 2024-5-4 20:37 | 显示全部楼层
这个板的USB好多呀
您需要登录后才可以回帖 登录 | 注册

本版积分规则

106

主题

1098

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部

106

主题

1098

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部