【串口操作方式】
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
int main()
{
int fd;
fd=open("/dev/ttyS0", O_RDWR);
if(fd==-1)
{
perror("open ttS0");
return 0;
}
printf("Open ttyS0 OK!\n");
close(fd);
return 0;
}
【运行结果】
lwb@ubuntu:~/uart$ gcc uart.c -o uart
lwb@ubuntu:~/uart$ sudo ./uart
Open ttyS0 OK!
Linux系统通常使用termios结构存储串口参数
struct termios
{
unsigned short c_iflag; //输入模式标志
unsigned short c_oflag; //输出模式标志
unsigned short c_cflag; //控制模式标志
unsigned short c_lflag; //本地模式标志
unsigned short c_line; //线路规则
unsigned short c_cc[NCC]; //控制字
}
【串口操作实例】
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#define STTY_DEV "/dev/ttyS0"
#define BUFF_SIZE 512
int main()
{
int stty_fd, n;
char buffer[BUFF_SIZE];
struct termios opt;
stty_fd = open(STTY_DEV, O_RDWR);
if(stty_fd==-1)
{
perror("open device");
return 0;
}
printf("Open device success, waiting user input ...\n");
tcgetattr(stty_fd, &opt);
tcflush(stty_fd, TCIOFLUSH);
cfsetispeed(&opt, B19200);
cfsetospeed(&opt, B19200);
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~PARENB;
opt.c_iflag &= ~INPCK;
opt.c_cflag &= ~CSTOPB;
opt.c_cc[VTIME] = 150;
opt.c_cc[VMIN] = 0;
if(tcsetattr(stty_fd, TCSANOW, &opt))
{
perror("set baudrate");
return 0;
}
tcflush(stty_fd, TCIOFLUSH);
while(1)
{
n = read(stty_fd, buffer, BUFF_SIZE);
if(n<=0)
{
perror("read data");
break;
}
buffer[n]='\0';
printf("%s",buffer);
if(strncmp(buffer, "quit", 4))
{
printf("user send quit!\n");
break;
}
printf("program will exit!\n");
close(stty_fd);
}
}
【运行结果】
lwb@ubuntu:~/uart$ gcc stty.c -o stty
lwb@ubuntu:~/uart$ sudo ./stty
[sudo] password for lwb:
Open device success, waiting user input …
两台机器下,在windows机上通过xshell打开串口,发送数据后,linux页面会有接收
【使用AT指令发送短信】
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //UNIX标准函数定义
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //文件控制定义
#include <termios.h> //PPSIX 终端控制定义
#include <errno.h> //错误号定义
#include <iconv.h>
#include <string.h>
#define STTY_DEV "/dev/ttyS0"
#define BUFF_SIZE 512
int SetOption(int fd)
{
struct termios opt;
tcgetattr(fd, &opt);
tcflush(fd, TCIOFLUSH);
cfsetispeed(&opt, B19200);
cfsetospeed(&opt, B19200);
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~PARENB;
opt.c_iflag &= ~INPCK;
opt.c_cflag &= ~CSTOPB;
opt.c_cc[VTIME] = 150;
opt.c_cc[VMIN] = 0;
if(tcsetattr(fd, TCSANOW, &opt)!=0)
{
perror("set baudrate");
return -1;
}
tcflush(fd, TCIOFLUSH);
return 0;
}
int main()
{
int stty_fd, n;
iconv_t cd;
char buffer[BUFF_SIZE];
char phone[20] = "+8618912345678"; //定义手机号码
char sms_number[20] = "+8613800200500"; //定义短消息中心号码
char sms_gb2312[140] = "工作愉快"; //定义短消息内容
char sms_utf8[140];
char *sms_in = sms_gb2312;
char *sms_out = sms_utf8;
int str_len, i, tmp;
int gb2312_len, utf8_len;
stty_fd = open(STTY_DEV, O_RDWR);
if(stty_fd==-1)
{
perror("open device");
return 0;
}
printf("Open device success!\n");
if(SetOption(stty_fd)!=0)
{
close(stty_fd);
return 0;
}
if(phone[0] = '+')
{
for(i=0;i<strlen(phone)-1;i++)
{
phone[i]=phone[i+1];
}
}
phone[i] = '\0';
str_len = strlen(phone);
if((strlen(phone)%2)!=0) //如果号码长度是奇数,在后面加字符'F'
{
phone[str_len] = 'F';
phone[str_len+1] = '\0';
}
for(i=0;i<strlen(phone);i+=2) //调换奇偶位
{
tmp=phone[i];
phone[i]=phone[i+1];
phone[i+1]=tmp;
}
if(sms_number[0]='+')
{
for(i=0; i<strlen(sms_number)-1; i++)
sms_number[i] = sms_number[i+1];
}
sms_number[i] = '\0';
str_len = strlen(sms_number);
if((strlen(sms_number)%2)!=0) //如果号码长度是奇数,在后面加字符'F'
{
sms_number[str_len] = 'F';
sms_number[str_len] = '\0';
}
for(i=0;i<strlen(sms_number);i+=2) //调换奇偶位
{
tmp = sms_number[i];
sms_number[i] = sms_number[i+1];
sms_number[i+1] = tmp;
}
str_len = strlen(sms_number);
for(i=strlen(sms_number)+2;i!=0;i--) //所有字符向后移动两个字节
sms_number[i] = sms_number[i-2];
sms_number[str_len+3] = '\0';
strncpy(sms_number, "91", 2); //开头加入字符串91
tmp = strlen(sms_number)/2;
str_len = strlen(sms_number); //计算字符串长度
for(i=strlen(sms_number)+2;i!=0;i--) //所有的字符向后移动两个字节
sms_number[i] = sms_number[i-2];
sms_number[str_len+3] = '\0';
sms_number[0] = (char)(tmp/10) + 0x30; //将字符串的长度值由整型转换为字符型类型写入到短信字符串的开头部分
sms_number[1] = (char)(tmp%10) + 0x30;
cd = iconv_open("utf-8", "gb2312");
if(cd==0)
{
perror("create iconv handle!");
close(stty_fd);
return 0;
}
gb2312_len = strlen(sms_gb2312); //输入字符串的长度
utf8_len = 140;
if(iconv(cd, &sms_in, &gb2312_len, &sms_out, &utf8_len)==-1) //转换字符为Unicode编码
{
perror("convert conde");
close(stty_fd);
return 0;
}
iconv_close(cd);
strcpy(buffer, "AT+CMGF=0\n");
write(stty_fd, buffer, strlen(buffer)); //写入配置命令
n=read(stty_fd, buffer, BUFF_SIZE);
if(n<=0)
{
perror("set pdu mode");
close(stty_fd);
return 0;
}
if(strncmp(buffer, "OK", 2)!=0) //判断命令是否执行成功
{
perror("set pdu mode");
close(stty_fd);
return 0;
}
sprintf(buffer, "AT+CMGS=%d\n", utf8_len); //写入发送消息命令
write(stty_fd, buffer, strlen(buffer)); //写入消息内容
write(stty_fd, sms_utf8, utf8_len);
printf("Send message OK!\n");
close(stty_fd);
}
摘自:弓雷 ARM嵌入式Linux系统开发详解