回答

收藏

[评测分享] 【更适合初学者的开发板ELF 1】+ 3.UART扩展

#板卡评测 #板卡评测 1749 人阅读 | 0 人回复 | 2023-12-17

1.前言
本次主要想实现的就是一个uart在imx6ull和单片间通信的功能,linux是非实时的系统,假如有那么一个场景需要实时的去控制一些设备,或者本身的MPU芯片资源不够用需要去扩展外设,那么此时可以考虑外挂一个芯片进行扩展,在mpu层只需要上传一下必要的信息进行数据交互或者mpu下发一些控制信息就可以了。当前这种情况已经用的很成熟了,很多公司内部也有自己的通信协议。本次就实现mpu和单片机间进行串口通信。
2.uart通信
串口通信这里不在说明了,都太熟悉了,这里记录说明Imx6ull怎么实现串口通信,以及和单片机间通信,通过开发板将数据发送到单片机,这里选择的是AC78406YGLA核心板,单片机接收到数据后通过串口打印出到上位机,MPU开发板一直发送elfboard。
本次选择串口2和单片机通信,MPU板子将串口发送接到单片的接收,首先先确定单片机能够将接收到的数据发送出来,将单片机开发板和串口连接,使用电脑上位机先测试一下。如下所示,代码已经提前调好了,PC8对应uart tx PC9对应uart rx:

单片机开发串口测试效果如下:

以下为linux 板的I/O引脚出图,硬连接只需要将Uart2TX连接到单片机的PC9,单片3的PC8连接到USB转串口的RX:

连接如下所示:
3.代码设计

单片机串口配置
串口中断收发配置:

Linux开发板串程序,使用的是开发板提供的程序,发送函数:

主函数:
  1. int main(int argc, char *argv[])
  2. {
  3.     int result = 0;

  4.     //检测是否有参数
  5.     if (argc < 2 || strncmp(argv[1], "tty", 3))
  6.     {
  7.         print_usage(argv[0]);
  8.         exit(1);
  9.     }

  10.     //检测是否有--h或--help
  11.     if ((!strcmp(argv[1], "--h")) || (!strcmp(argv[1], "--help")))
  12.     {
  13.         print_usage(argv[0]);
  14.         exit(1);
  15.     }

  16.     strcpy(dev, "/dev/");
  17.     strcat(dev, argv[1]);

  18.     //从main函数带来的参数解析为串口参数
  19.     get_param(argc, argv, &tty_param);

  20.     //当知道设备名称时可以直接赋值dev,例strcpy(dev, "/dev/ttymxc1");
  21.     //打开串口 设置可读写,不被输入影响,不等待外设响应
  22.     fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
  23.     if (fd < 0)
  24.     {
  25.         perror(dev);
  26.         printf("Can't Open Serial Port %s \n", dev);
  27.         exit(0);
  28.     }
  29.     else
  30.     {
  31.         printf("baudrate=%ld,data_bit=%d,stop_bit=%d,check='%c'\n", tty_param.baudrate, tty_param.data_bit, tty_param.stop_bit, tty_param.check);
  32.         //设置串口参数
  33.         if ((result = func_set_opt(fd, tty_param.baudrate, tty_param.data_bit, tty_param.stop_bit, tty_param.check, tty_param.hardware)) < 0)
  34.         {
  35.             perror("set_opt error");
  36.             exit(0);
  37.         }
  38.         //设置串口为阻塞方式
  39.         /*if(fcntl(fd, F_SETFL, 0)<0)
  40.         {
  41.             printf("fcntl failed!\n");
  42.         }
  43.         else
  44.         {
  45.             printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
  46.         }*/
  47.         //设置串口为非阻塞方式
  48.         /*if(fcntl(fd, F_SETFL, FNDELAY)<0)
  49.         {
  50.             printf("fcntl failed!\n");
  51.         }
  52.         else
  53.         {
  54.             printf("fcntl=%d\n",fcntl(fd, F_SETFL,FNDELAY));
  55.         }*/
  56.     }

  57.     while (1)
  58.     {
  59.         receive_num = func_receive_frame(fd, receive_buff, sizeof(receive_buff)); /*读取串口收到的数据*/
  60.         if (receive_num > 0)
  61.         {
  62.             printf("[nread=%d] ", receive_num);
  63.             func_my_print(receive_buff, receive_num, 'c'); /*打印接收到的数据*/
  64.         }
  65.         //组织发送数据
  66.         if ((1 == loopback_send_mode) && (receive_num > 0)) //数据回环处理
  67.         {
  68.             send_num = receive_num;
  69.             memcpy(send_buff, receive_buff, receive_num);
  70.         }
  71.         else if (1 == active_send_mode)
  72.         {
  73.             if (active_send_time_count >= active_send_time)
  74.             {
  75.                 active_send_time_count = 0;
  76.                 send_num = active_send_num;
  77.                 memcpy(send_buff, active_send_buff, active_send_num);
  78.             }
  79.             else
  80.             {
  81.                 active_send_time_count++;
  82.             }
  83.         }
  84.         //数据发送
  85.         if (send_num > 0)
  86.         {
  87.             real_send_num = func_send_frame(fd, send_buff, send_num);
  88.             if (real_send_num > 0)
  89.             {
  90.                 printf("[nwrite=%d] ", real_send_num); /*打印发送的数据*/
  91.                 func_my_print(send_buff, real_send_num, 'c');
  92.             }
  93.             memset(send_buff, 0, send_num);
  94.             send_num = 0;
  95.         }
  96.         usleep(1000);
  97.     }
  98.     exit(0);
  99. }
复制代码
编译生产可执行文件:

拖入开发板,添加可执行权限,设置串口相关参数:

通过逻辑分析仪观察串口发送的数据:
结果:



分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条