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开发板串程序,使用的是开发板提供的程序,发送函数:
主函数: - int main(int argc, char *argv[])
- {
- int result = 0;
- //检测是否有参数
- if (argc < 2 || strncmp(argv[1], "tty", 3))
- {
- print_usage(argv[0]);
- exit(1);
- }
- //检测是否有--h或--help
- if ((!strcmp(argv[1], "--h")) || (!strcmp(argv[1], "--help")))
- {
- print_usage(argv[0]);
- exit(1);
- }
- strcpy(dev, "/dev/");
- strcat(dev, argv[1]);
- //从main函数带来的参数解析为串口参数
- get_param(argc, argv, &tty_param);
- //当知道设备名称时可以直接赋值dev,例strcpy(dev, "/dev/ttymxc1");
- //打开串口 设置可读写,不被输入影响,不等待外设响应
- fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
- if (fd < 0)
- {
- perror(dev);
- printf("Can't Open Serial Port %s \n", dev);
- exit(0);
- }
- else
- {
- 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);
- //设置串口参数
- if ((result = func_set_opt(fd, tty_param.baudrate, tty_param.data_bit, tty_param.stop_bit, tty_param.check, tty_param.hardware)) < 0)
- {
- perror("set_opt error");
- exit(0);
- }
- //设置串口为阻塞方式
- /*if(fcntl(fd, F_SETFL, 0)<0)
- {
- printf("fcntl failed!\n");
- }
- else
- {
- printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
- }*/
- //设置串口为非阻塞方式
- /*if(fcntl(fd, F_SETFL, FNDELAY)<0)
- {
- printf("fcntl failed!\n");
- }
- else
- {
- printf("fcntl=%d\n",fcntl(fd, F_SETFL,FNDELAY));
- }*/
- }
- while (1)
- {
- receive_num = func_receive_frame(fd, receive_buff, sizeof(receive_buff)); /*读取串口收到的数据*/
- if (receive_num > 0)
- {
- printf("[nread=%d] ", receive_num);
- func_my_print(receive_buff, receive_num, 'c'); /*打印接收到的数据*/
- }
- //组织发送数据
- if ((1 == loopback_send_mode) && (receive_num > 0)) //数据回环处理
- {
- send_num = receive_num;
- memcpy(send_buff, receive_buff, receive_num);
- }
- else if (1 == active_send_mode)
- {
- if (active_send_time_count >= active_send_time)
- {
- active_send_time_count = 0;
- send_num = active_send_num;
- memcpy(send_buff, active_send_buff, active_send_num);
- }
- else
- {
- active_send_time_count++;
- }
- }
- //数据发送
- if (send_num > 0)
- {
- real_send_num = func_send_frame(fd, send_buff, send_num);
- if (real_send_num > 0)
- {
- printf("[nwrite=%d] ", real_send_num); /*打印发送的数据*/
- func_my_print(send_buff, real_send_num, 'c');
- }
- memset(send_buff, 0, send_num);
- send_num = 0;
- }
- usleep(1000);
- }
- exit(0);
- }
复制代码编译生产可执行文件:
拖入开发板,添加可执行权限,设置串口相关参数:
通过逻辑分析仪观察串口发送的数据: 结果:
|