串口编程
2016-08-04 15:06
218 查看
1 关于串口的一些概念
开发过程中一般直接使用原厂提供的接口,进行初始化和配置。RS232有两种标准:25针和9针。但实际应用上只需要用到TX、RX和GND
流控:分为硬件流控和软流控。属于串口通信同步传输的作用
2 串口编程流程分析
开始打开串口
初始化串口
发送和接受数据
关闭
初始化串口比较难懂
2.1 打开串口
对串口的控制需要文件IO的基础如何确认设备节点
- 串口选取“靠近耳机接口的con2”文件名为:ttySAC3
- 一般为tty前缀设备,讯为4412为ttySAC*
- 打开串口即用open函数将设备文件ttySAC3打开。
程序代码:
void main(){ int fd; char *uart3 = "/dev/ttySAC3"; if((fd = open(uart3,O_RDWR|O_CREAT,0777))<0){ printf("open %s failed!\n",uart3); } else{ printf("open %s is success!\n",uart3); } close(fd); }
2.2 串口初始化
使用例程学习串口初始化:不管在什么平台,只需找到对应的例程修改学习串口初试。串口初始化学习步骤
通过串口助手初步了解初始化参数使用source insight查看内核参数定义的源码
内核目录“\arch\arm\include\asm\termios.h”
结构体termio
常用参数串口初始化步骤
读取当前参数修改参数
配置参数
涉及到的函数
函数tcgetattr (man 3 tcgetattr)读取当前参数函数
int tcgetattr(int fd,struct termios *termios_p);
获取当前波特率函数
speed_t cfgetispeed(const struct termios *termios_p);
speed_t cfgetospeed(const struct termios *termios_p);
波特率设置函数
int cfsetispeed(struct termios *termios_p,speed_t speed);
int cfsetospeed(struct termios *termios_p,speed_t speed);
波特率有以上两个专门的设置函数,也可以使用对c_cflag进行或操作实现对波特率的设置
清空串口BUFFER中的数据函数
int tcflush(int fd,int queue_selector);
设置串口参数函数
int tcsetattr(int fd,int optional_actions,const struct termios *termios_p);
串口完整配置函数
int set_com_config(int fd,int baud_rate, int data_bits, char parity, int stop_bits) { struct termios new_cfg,old_cfg; int speed; /*保存并测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/ if (tcgetattr(fd, &old_cfg) != 0) { perror("tcgetattr"); return -1; } /* 设置字符大小*/ new_cfg = old_cfg; cfmakeraw(&new_cfg); /* 配置为原始模式 */ new_cfg.c_cflag &= ~CSIZE; /*设置字符大小,先用数据位掩码清空数据位设置*/ /*设置波特率*/ switch (baud_rate) { case 2400: { speed = B2400; } break; case 4800: { speed = B4800; } break; case 9600: { speed = B9600; } break; case 19200: { speed = B19200; } break; case 38400: { speed = B38400; } break; default: case 115200: { speed = B115200; } break; } cfsetispeed(&new_cfg, speed); /*cfsetispeed设置波特率有专门的函数,也可以使用对c_cflag进行或操作*/ cfsetospeed(&new_cfg, speed); /*设置数据长度*/ switch (data_bits) { case 7: { new_cfg.c_cflag |= CS7; } break; default: case 8: { new_cfg.c_cflag |= CS8; } break; } /*设置奇偶校验位*/ switch (parity) { default: case 'n': case 'N': { new_cfg.c_cflag &= ~PARENB; /*关闭校验位使能*/ new_cfg.c_iflag &= ~INPCK; /*关闭输入奇偶校验使能*/ } break; case 'o': case 'O': { new_cfg.c_cflag |= (PARODD | PARENB); /*校验位使能,同时使用奇校验*/ new_cfg.c_iflag |= INPCK; /*开启输入奇校验使能*/ } break; case 'e': case 'E': { new_cfg.c_cflag |= PARENB; /*校验位使能*/ new_cfg.c_cflag &= ~PARODD; /*使用偶校验*/ new_cfg.c_iflag |= INPCK; /*开启输入奇校验使能*/ } break; case 's': /*as no parity*/ case 'S': { new_cfg.c_cflag &= ~PARENB; new_cfg.c_cflag &= ~CSTOPB; } break; } /*设置停止位*/ switch (stop_bits) { default: case 1: { new_cfg.c_cflag &= ~CSTOPB; } break; case 2: { new_cfg.c_cflag |= CSTOPB; } } /*设置等待时间和最小接收字符*/ new_cfg.c_cc[VTIME] = 0; new_cfg.c_cc[VMIN] = 1; /*处理未接收字符*/ tcflush(fd, TCIFLUSH); /*激活新配置*/ if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0) { perror("tcsetattr"); return -1; } return 0; }
2.3 串口发送
串口发送步骤就是对tty*文件进行write函数写东西void main() { int fd,wr_static,i=10; char *uart3 = "/dev/ttySAC3"; char *buffer = "hello world!\n"; printf("\r\nitop4412 uart3 writetest start\r\n"); if((fd = open(uart3, O_RDWR|O_NOCTTY|O_NDELAY))<0){ printf("open %s is failed",uart3); } else{ printf("open %s is success\n",uart3); set_opt(fd, 115200, 8, 'N', 1); while(i--) { wr_static = write(fd,buffer, strlen(buffer)); if(wr_static<0) printf("write failed\n"); else{ printf("wr_static is %d\n",wr_static); } sleep(1); } } close(fd); }
2.4 串口接收
串口接收就是用read函数对tty*文件进行读操作void main() { int fd,nByte; char *uart3 = "/dev/ttySAC3"; char buffer[512]; char *uart_out = "please input\r\n"; memset(buffer, 0, sizeof(buffer)); //定义一个较长的数组,最好使用memset将其清空 if((fd = open(uart3, O_RDWR|O_NOCTTY))<0) printf("open %s is failed",uart3); else{ set_opt(fd, 115200, 8, 'N', 1); write(fd,uart_out, strlen(uart_out)); /*使用write函数写一串字符到上位机*/ while(1){ while((nByte = read(fd, buffer, 512))>0){ /*每次读取的数据nByte*/ buffer[nByte+1] = '\0'; /*转化成字符串,接受数据存储在buffer是没有加\0*/ write(fd,buffer,strlen(buffer)); /*上位机回显,发送了什么数据,就会显示什么数据,用以确认板子是否接收到数据*/ memset(buffer, 0, strlen(buffer));/*重新清空buffer,准备下一次的数据*/ nByte = 0; } } } }
* 设置程序开机启动运行(最小系统)
将可执行程序复制到/bin目录下 “cp -r ..”修改权限成777 chmod 777 /bin/helloworld
修改启动文件,最小系统:vi /etc/init.d/rcs,在最后添加“/bin/可执行程序 &”
注、实验串口发送和串口接收时,一般情况下需要一个串口连接超级终端控制开发板,同时需要另一个串口作为实验对象。在串口不够用的情况下,可以采取将串口实验程序设置为开机启动运行模式,这样一来就省去在超级终端运行串口实验程序的步骤。
相关文章推荐
- 深入分析Visual C++进行串口通信编程的详解
- C#串口通信程序实例详解
- vspd
- JAVA 串口通信 RXTX 使用方法
- STM32 UART DMA实现未知数据长度接收(转自amoBBs)
- VC++串口通信小小测试(使用VPSM)
- C#串口控件关闭时死机卡住
- C#串口通信 实现打印功能
- PHP操作串口 --- 操作发送短信mod应用(真实项目)
- ti blueteeth stack 1.3.2 part1
- S5PV210串口通信学习
- SafeArray、COleSafeArray、VarType
- WiFi小车记录一:基本构思
- WIFI小车记录五:单片机串口通信
- GP2Y1010AU0F 粉尘传感器
- Android开发板之串口开发
- MFC下32位WINAPI串口编程
- 配置GDB+GdbServer远程调试环境
- 【解决】关于sscom不能保存当前窗口到文本文件的问题
- 【解决】关于蓝牙模块串口设置总是错误的问题