这是前篇:
本篇介绍下uart的使用, 采用米尔MYS-6ULX板子出厂配置的系统. 主要参考自野火的10. 串口通讯与终端设备 .
米尔的板子引出了2, 3, 4串口:
在ttymxc与uart 如何对应一文中回复:
UART1 对应 ttymxc0
UART2 对应 ttymxc1
UART3 对应 ttymxc2
…
然而ls /dev/tty*
, 只有用作调试口的ttymxc0:
root@mys6ull14x14:~# ls /dev/tty*
/dev/tty /dev/tty18 /dev/tty28 /dev/tty38 /dev/tty48 /dev/tty58
/dev/tty0 /dev/tty19 /dev/tty29 /dev/tty39 /dev/tty49 /dev/tty59
/dev/tty1 /dev/tty2 /dev/tty3 /dev/tty4 /dev/tty5 /dev/tty6
/dev/tty10 /dev/tty20 /dev/tty30 /dev/tty40 /dev/tty50 /dev/tty60
/dev/tty11 /dev/tty21 /dev/tty31 /dev/tty41 /dev/tty51 /dev/tty61
/dev/tty12 /dev/tty22 /dev/tty32 /dev/tty42 /dev/tty52 /dev/tty62
/dev/tty13 /dev/tty23 /dev/tty33 /dev/tty43 /dev/tty53 /dev/tty63
/dev/tty14 /dev/tty24 /dev/tty34 /dev/tty44 /dev/tty54 /dev/tty7
/dev/tty15 /dev/tty25 /dev/tty35 /dev/tty45 /dev/tty55 /dev/tty8
/dev/tty16 /dev/tty26 /dev/tty36 /dev/tty46 /dev/tty56 /dev/tty9
/dev/tty17 /dev/tty27 /dev/tty37 /dev/tty47 /dev/tty57 /dev/ttymxc0
用另外几个可能需要修改设备树(参考【imx6ul应用开发】如何修改串口?一文), 暂时还没到这里, 为了方便, USB口插一个ST-Link(本想用CH340小板子的, 未遂), 自带虚拟串口, 对应/dev/ttyACM0
:
ST-Link插到板子USB口时, 调试串口会打印:
root@mys6ull14x14:~# usb 1-1.2: new full-speed USB device number 6 using ci_hdrc
usb-storage 1-1.2:1.1: USB Mass Storage device detected
scsi host0: usb-storage 1-1.2:1.1
cdc_acm 1-1.2:1.2: ttyACM0: USB ACM device
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
scsi 0:0:0:0: Direct-Access MBED microcontroller 1.0 PQ: 0 ANSI: 2
sd 0:0:0:0: [sda] 72 512-byte logical blocks: (36.8 kB/36.0 KiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] No Caching mode page found
sd 0:0:0:0: [sda] Assuming drive cache: write through
sd 0:0:0:0: [sda] Attached SCSI removable disk
再用一个CH340的USB转串口的小板子连接到Windows电脑, CH340小板和ST-Link的TX/RX交叉连接, 这样就相当于Windows和i.MX6通过串口通信了, 经测试, 默认的波特率是9600, 8N1.
调试串口输入:
root@mys6ull14x14:~# echo Hello,Uart > /dev/ttyACM0
可以在Windows的SSCOM中看到接收:
调试串口中输入cat /dev/ttyACM0
, 然后SSCOM发送:
可以在调试串口中收到:
至于SSCOM为什么会收到…
除了open, read, write, close系统调用, Linux系统可以利用termios里的库函数来设置串口的参数, termios是对ioctl系统调用的封装, 搬来野火改的uart_test.c
:
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 第一部分代码 */
//根据具体的设备修改
const char default_path[] = "/dev/ttyACM0";
char buf[1024] = "uart send test.\n";
int main(int argc, char *argv[])
{
int fd;
int res;
char *path;
/* 第二部分代码 */
path = (char *)default_path;
//获取串口设备描述符
printf("This is tty/usart demo.\n");
fd = open(path, O_RDWR);
if (fd < 0)
{
printf("Fail to Open %s device\n", path);
return 0;
}
/* 第三部分代码 */
struct termios opt;
//清空串口接收缓冲区
tcflush(fd, TCIOFLUSH);
// 获取串口参数opt
tcgetattr(fd, &opt);
//设置串口输出波特率
cfsetospeed(&opt, B115200);
//设置串口输入波特率
cfsetispeed(&opt, B115200);
//设置数据位数
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
//校验位 N
opt.c_cflag &= ~PARENB; /* Clear parity enable */
opt.c_iflag &= ~INPCK; /* Enable parity checking */
//设置停止位
opt.c_cflag &= ~CSTOPB;
//更新配置
tcsetattr(fd, TCSANOW, &opt);
printf("Device %s is set to 115200bps,8N1\n", path);
/* 第四部分代码 */
do
{
//发送字符串
write(fd, buf, strlen(buf));
//接收字符串
res = read(fd, buf, 1024);
if (res > 0)
{
//给接收到的字符串加结束符
buf[res] = '\0';
printf("Receive res = %d bytes data: %s\n", res, buf);
}
} while (res >= 0);
printf("read error,res = %d", res);
close(fd);
return 0;
}
交叉编译arm-linux-gnueabihf-gcc uart_test.c -o uart_test
, NFS挂载后运行./uart_test
, 注意波特率要改为115200:
欢迎扫描关注我的微信公众号, 及时获取最新文章: