原创 Linux下串口编程

2009-10-23 17:48 2777 8 10 分类: MCU/ 嵌入式

嵌入式Linux下串口编程<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


一、配置内核


在嵌入式Linux下进行串口编程之前,先在内核中配置串口部分,如下:



Device Drivers--->


       character devices--->


              Serial drivers--->


                     <*>Samssung S<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3C2440/S3C2442 Serial port support


二、应用程序


C文件:


uart_init.c:打开设备、初始化串口(设置参数)


main.c:测试串口读写


头文件:


uart_init.h


Makfile


 


 


uart_init.c


#include <stdio.h>


#include <stdlib.h>


#include <string.h>


#include <error.h>


#include <unistd.h>


#include <fcntl.h>


#include <sys/types.h>


#include <sys/stat.h>


#include <termios.h>


 


int open_termios(char *dev)


{


       int fd = -1;


       if(-1 == (fd = open(dev,O_RDWR|O_NOCTTY|O_NONBLOCK)))


       {


              printf("open termios error!\n");


       }


       return fd;


}


 


int set_termios(int fd,long speed,char databit,char stopbit,char oebit)


{


       struct termios newtio;


       int err = -1;


      


       //清零结构体


       bzero(&newtio,sizeof(newtio));


       //设置接收使能


       newtio.c_cflag |= CLOCAL | CREAD;


       // 设置数据位


       switch(databit)


       {


              case 7:


                     newtio.c_cflag |= CS7;


                     break;


              case 8:


                     newtio.c_cflag |= CS8;


                     break;


              default:


                     newtio.c_cflag |= CS8;


                     break;


       }


       //设置停止位


       switch(stopbit)


       {


              case 1:


                     newtio.c_cflag &= ~CSTOPB;


                     break;


              case 2:


                     newtio.c_cflag |= CSTOPB;


                     break;


              default:


                     newtio.c_cflag &= ~CSTOPB;


                     break;


       }


       //设置校验位


       switch(oebit)


       {


              case 'O':    //奇校验


                     newtio.c_cflag |= PARENB;


                     newtio.c_cflag |= (INPCK | ISTRIP);


                     newtio.c_cflag |= PARODD;


                     break;


              case 'E':    //偶数


                     newtio.c_cflag |= PARENB;


                     newtio.c_cflag |= (INPCK | ISTRIP);


                     newtio.c_cflag &= ~PARODD;


                     break;


              case 'N':    //不校验


                     newtio.c_cflag &= ~PARODD;


                     break;


              default:


                      //不校验


                     newtio.c_cflag &= ~PARODD;


                     break;


       }


       //设置波特率


       switch(speed)


       {


              case 2400:


                     cfsetispeed(&newtio,B2400);


                     cfsetospeed(&newtio,B2400);


                     break;


              case 4800:


                     cfsetispeed(&newtio,B4800);


                     cfsetospeed(&newtio,B4800);


                     break;


              case 9600:


                     cfsetispeed(&newtio,B9600);


                     cfsetospeed(&newtio,B9600);


                     break;    


              case 57600:


                     cfsetispeed(&newtio,B57600);


                     cfsetospeed(&newtio,B57600);


                     break;    


              case 115200:


                     cfsetispeed(&newtio,B115200);


                     cfsetospeed(&newtio,B115200);


                     break;    


              default:


                     cfsetispeed(&newtio,B9600);


                     cfsetospeed(&newtio,B9600);


                     break;    


       }


       //设置等待时间和最小接收字符数


       newtio.c_cc[VTIME] = 0;


       newtio.c_cc[VMIN] = 0;


       //处理未接收字符


       tcflush(fd,TCIFLUSH);


       //激活配置


       if((tcsetattr(fd,TCSANOW,&newtio)) != 0)


              perror("com set error!");


       else


              err = 0;


       perror("com set done!");


       return err;


}


 


 


uart_init.h


#ifndef __UART_INIT__


#define __UART_INIT__


extern int open_termios(char *dev);


int set_termios(int fd,long speed,char databit,char stopbit,char oebit);


#endif


 


 


main.c


#include <stdio.h>


#include <stdlib.h>


#include <error.h>


#include <unistd.h>


#include <sys/types.h>


#include <sys/stat.h>


#include <termios.h>


#include "uart_init.h"


 


char *uart0_dev="/dev/ttySAC0";


 


int main(void)


{


       int uart0_fd;


       int err = 0;


       char uart0_byte = 0;     


       char *uart0_buff[8]={0};


 


       uart0_fd = open_termios(uart0_dev);


       if(uart0_fd < 0)


       {


              exit(1);


       }


       do


       {


              err = set_termios(uart0_fd,115200,8,1,'N');


       }


       while(-1 == err);


       while(1)


       {


              read(uart0_fd,&uart0_byte,1);


              if(0xfd == uart0_byte)         


              {


                     read(uart0_fd,uart0_buff,8);


                     write(uart0_fd,uart0_buff,8);


                     memset(uart0_buff,0,sizeof(uart0_buff));


                     uart0_byte = 0;


              }           


             


       }


       exit(0);


}


 


 


Makefile


#You can add source code file like the following


SOURCE += main.c


SOURCE += uart_init.c


 


##You can add header code file like the following


HEADER += uart_init.h


 


 


#You can name the executable file like the following


TARGET = UART_ARM


 


#You can add include path like the following


INCLUDEPATH =


#You can library path like the following


LIBPATH =


#You can add library like the following


LIBS = -lpthread


 


 


#You cant add compile options like the following


OPTION += -Wall 


OPTION += -g


 


#You can specify the compiler


CC=arm-linux-gcc


 


#Don't modify the following code unless you know howto exactly


OBJECTS =$(SOURCE:%.c=%.o)


 


$(TARGET):$(OBJECTS)


       $(CC) $(OPTION) $(INCLUDEPATH) $(LIBPATH) $(LIBS) -o $(TARGET) $(OBJECTS)


clean:


       -rm -f $(TARGET) *.o *~


 


在串口调试助手选择波特率,选择十六进制显示并打开串口后,发送“fd 31 32 33 34 35 36 37 38”这串十六进制数据后,接收端就出现“31 32 33 34 35 36 37 38”数据。

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1398279 2009-10-24 00:25

我只用到我常用的波特率,呵呵。

用户131114 2009-10-23 21:15

const int speed_arr[] = { B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000}; const uint32 name_arr[] = { 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000}; for (i = 0; i < dimof(speed_arr); i++) { if (baudrate == name_arr[i]) { cfsetispeed(&opt, speed_arr[i]); cfsetospeed(&opt, speed_arr[i]); } }

用户190061 2009-4-13 10:24

121
相关推荐阅读
用户1398279 2010-07-08 00:12
C语言共享库的制作
C语言共享库的制作0推荐 作者:杨硕,华清远见嵌入式学院讲师。1)基本概念共享库也是.o文件的集合,但是这些文件由编译器按照一种特殊的方式生成(Linux中,共享库文件为"ELF"格式,共享库已经具备...
用户1398279 2010-07-04 22:37
Linux 2.6.11 MTD驱动情景分析
Linux 2.6.11 MTD驱动情景分析最近几天为了熟悉linux的驱动开发,我选择了其MTD驱动做了一些研究。我能找到的文章中我觉得有些部分不够细致,所以我还是自己写了一部分分析,希望对别人也能...
用户1398279 2010-05-05 14:25
automake使用及库和头文件的链接
automake使用及库和头文件的链接关于automake的实践今天弄了很久的automake,自动生成Makefile,这样写程序时就会方便很多。之前也花时间看过一次,但当时只是对着一个hello....
用户1398279 2010-05-05 11:33
HP总裁退休时的信件
HP总裁退休时的信件<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />我有个有趣的观察...
用户1398279 2010-04-23 18:04
VMWare的NAT配置(包括DHCP和固定IP配置)
NAT的DHCP配置:这个网上别人写过,自己实验了下,没有问题。1 .最重要的是你的两个服务必须开启:VMware DHCP Service 和VMware NAT Service。具体操作如下: 开...
用户1398279 2010-04-23 10:48
gcc命令objdump用法
gcc命令objdump用法2009年03月29日 星期日 23:49gcc命令之 objdump ---------------objdump是用查看目标文件或者可执行的目标文件的构成的GCC工具-...
EE直播间
更多
我要评论
2
8
关闭 站长推荐上一条 /3 下一条