c++ win32 获取串口高低电平_嵌入式Linux串口编程

简介

嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的。嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大多是RS232或者RS485接口,对于软件层面上来说,RS232与RS48区别不大。RS232与RS485在使用上的区别,RS232是全双工的,只能对接一个设备串口设备。RS485是半双工的总线协议,一般可以挂多个传感器设备,半双工的意思是同时只能有一个设备向串口发数据。

用到的API函数

函数说明
open打开设备,用于打开串口设备
fcntl修改设备描述符属性参数
isatty检测打开的描述符是否指向一个终端
tcgetattr用来获取串口终端参数
cfmakeraw将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
tcflush用于清空输入、输出缓冲区
tcsetattr设置串口终端参数
read读取数据
write写数据
close关闭串口设备

代码

  1#include
2#include "uart.h"
3
4/*************************************** 5*name    : open_port 6*功能描述: 打开串口 7*入口参数: 串口号 8*返 回 值: 成功返回文件描述符,失败返回负值 9*作    者:  10*修改时间: 11***************************************/
12int open_port(const char * com_port) 13{
14    int fd;
15
16    if( com_port == NULL ){
17        printf("the port name is null\n");
18        return -1;
19    }
20    /*open port*/
21    fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
22    if(fd 0){
23        fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
24        if(fd 0){
25            perror("open serial port");
26            return -1;
27        }
28    }
29    printf("open %s OK!\n", com_port);
30    if(fcntl(fd, F_SETFL,0) 0){
31        perror("fcntl F_SETFL");
32    }
33
34    if(isatty(fd) == 0){
35        perror("isatty is not a terminal device");
36    }
37    return fd;
38}
39
40/****************************** 41*name    : set_port 42*功能描述: 设置串口参数 43*入口参数: fd 文件描述符, baud_rate 波特率, data_bits 数据位, 44*          parity 奇偶校验, stop_bits 停止位 45*            调用示例: set_port(fd, 115200, 8, 'N',1); 46*返 回 值: 成功返回0,失败返回-1 47*作    者:  48*修改:  49******************************/
50int set_port(int fd, int baud_rate, 51             int data_bits, char parity, int stop_bits) 52{
53    struct termios new_cfg, old_cfg;
54    int speed_arry[]= {B2400, B4800, B9600, B19200, B38400,B57600, B115200};
55    int speed[]={2400,4800,9600,19200,38400,57600,115200};
56    int i = 0;
57
58    /*save and test the serial port*/
59    if(tcgetattr(fd, &old_cfg) 0){
60        perror("tcgetattr");
61        return -1;
62    }
63
64    if(fcntl(fd,F_SETFL,0) 0)//恢复为阻塞模式
65    {
66        perror("fcntl(CzjFd,F_SETFL,0)!");
67    }
68
69    new_cfg = old_cfg;
70    cfmakeraw(&new_cfg);     //配置为原来配置
71    new_cfg.c_cflag &= ~ CSIZE;     //用数据位掩码清空数据位的设置
72
73    /*set baud_rate*/
74    for(i = sizeof(speed_arry) / sizeof(speed_arry[0]); i > 0; i--)
75    {
76        if(baud_rate == speed[i]){
77            cfsetispeed(&new_cfg,speed_arry[i]);
78            cfsetospeed(&new_cfg,speed_arry[i]);
79        }
80    }
81
82    switch(data_bits)    /*设置数据位*/
83    {
84        case 7:
85                new_cfg.c_cflag |= CS7;
86                break;
87
88        default:
89        case 8:
90                new_cfg.c_cflag |= CS8;
91                break;
92    }
93
94    switch(parity)
95    {
96        default:
97        case 'N':
98        case 'n':
99        {
100            new_cfg.c_cflag &= ~PARENB;     //清除校验位
101            new_cfg.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF);      //关闭奇偶校验  关闭软件流控
102
103            break;
104        }
105
106        case 'o':
107        case 'O':
108        {
109            new_cfg.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
110            new_cfg.c_iflag |= INPCK;
111            break;
112        }
113
114        case 'e':
115        case 'E':
116        {
117            new_cfg.c_cflag |= PARENB;
118            new_cfg.c_cflag &= ~PARODD;     //使用偶校验
119            new_cfg.c_iflag |= INPCK;
120            break;
121        }
122
123        case 's':
124        case 'S':
125        {
126            new_cfg.c_cflag &= ~PARENB;
127            new_cfg.c_cflag &= ~CSTOPB;
128            break;
129        }
130    }
131
132    new_cfg.c_iflag &= ~(ICRNL| IXON | IXOFF  );      //关闭奇偶校验  关闭软件流控
133    new_cfg.c_oflag &= ~OPOST;
134
135    switch(stop_bits)
136    {
137        default:
138        case 1:
139        {
140            new_cfg.c_cflag &= ~CSTOPB;
141            new_cfg.c_cflag &= ~CRTSCTS;   //禁用硬件流控
142            //new_cfg.c_cflag |= CRTSCTS;    //启用硬件流控
143            break;
144        }
145        case 2:
146        {
147            new_cfg.c_cflag |= CSTOPB;
148            break;
149        }
150    }
151
152    /*set wait time*/
153    new_cfg.c_cc[VTIME] = 0;
154    new_cfg.c_cc[VMIN]  = 1;
155
156    tcflush(fd, TCIFLUSH);   //处理未接收字符
157    if((tcsetattr(fd, TCSANOW, &new_cfg)) 0)
158    {
159        perror("tcsetattr");
160        return -1;
161    }
162
163    return 0;
164}

调用测试代码:

 1#include "uart.h"
2#include 
3#include 
4
5
6int main() 7{
8    int fd = open_port("/dev/ttyS1");
9    if ( fd 0 )
10    {
11        perror("open port");
12        return -1;
13    }
14
15    set_port(fd, 115200, 8, 'N',1);
16
17    char readBuf[32] ={0};
18    const char *pstr="hello world";
19    write(fd, pstr, strlen(pstr)+1);
20
21    read(fd, readBuf, sizeof(readBuf));
22
23    close(fd);
24}

微信公众号:

29d66f84-491f-eb11-8da9-e4434bdf6706.png
微信公众号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值