Linux下的串口总线驱动(四)

发布者:Serendipity66最新更新时间:2016-03-08 来源: eefocus关键字:Linux  串口  总线驱动 手机看文章 扫描二维码
随时随地手机看文章
六.串口测试代码

我们已经配置了mini2440的串口配置,然后根据mini2440开发板的硬件电路知道S3C2440本身总共有3个串口:UART0、1、2,其中UART0,1可组合为一个全功能的串口,在大部分的应用中,我们只用到3个简单的串口功能(本开发板提供的Linux和WinCE驱动也是这样设置的),即通常所说的发送(TXD)和接收(RXD),它们分别对应板上的CON1、CON2、CON3,这3个接口都是从CPU直接引出的,是TTL电平。为了方便用户使用,其中UART0做了RS232电平转换,它们对应于COM0,可以通过附带的直连线与PC机互相通讯。我们这个实验选用CON1作为测试串口的端口。用导线将CON1的1号(TXD1)和2号(RXD1)引脚相连,实现自发自收。

 

 

实验环境:内核linux2.6.32.2,arm-linux-gcc交叉编译器,mini2440开发板

内核配置:选中s3c2440.o   samsung.o  serial_core.o tty_io.o   n_tty.o   tty_ioctl.o   tty_ldisc.o   tty_buffer.o   tty_port.o。

测试代码如下:

 

#include      

#include

#include     

#include  

#include   

#include      

#include    

#include      

#include

#include

#define FALSE 1

#define TRUE 0

char *recchr="We received:\"";

int speed_arr[] = {

       B921600, B460800, B230400, B115200, B57600, B38400, B19200,

       B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,

       B4800, B2400, B1200, B300,

};

int name_arr[] = {

       921600, 460800, 230400, 115200, 57600, 38400,  19200,  

       9600,  4800,  2400,  1200,  300, 38400,  19200,  9600,

       4800, 2400, 1200,  300,

};

void set_speed(int fd, int speed)

{

       int   i;

       int   status;

       struct termios   Opt;

       tcgetattr(fd, &Opt); //获取线路设置

       for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {

              if  (speed == name_arr[i])    

                     tcflush(fd, TCIOFLUSH); //刷新输入输出队列

                     cfsetispeed(&Opt, speed_arr[i]);  //设置输入波特率

                     cfsetospeed(&Opt, speed_arr[i]);  //设置输出波特率

                     status = tcsetattr(fd, TCSANOW, &Opt);  //设置线路设置

                     if  (status != 0)

                            perror("tcsetattr fd1");

                            return;

              }

              tcflush(fd,TCIOFLUSH);  //刷新输入输出队列

   }

}

int set_Parity(int fd,int databits,int stopbits,int parity, int flowctrl)

{

       struct termios options;

       if  ( tcgetattr( fd,&options)  !=  0) { //获取线路设置

              perror("SetupSerial 1");

              return(FALSE);

       }

       options.c_cflag &= ~CSIZE ;   //利用CSIZE掩码把正确位从cflag中分离并清零,其他位不变

       switch (databits) {

       case 7:

              options.c_cflag |= CS7;

       break;

       case 8:

              options.c_cflag |= CS8;

       break;

       default:

              fprintf(stderr,"Unsupported data size\n");

              return (FALSE);

       }

       switch (parity) {

       case 'n':

       case 'N':

              options.c_cflag &= ~PARENB;  

              options.c_iflag &= ~INPCK;    

       break;

       case 'o':

       case 'O':

              options.c_cflag |= (PARODD | PARENB); 

              options.c_iflag |= INPCK;            

       break;

       case 'e':

       case 'E':

              options.c_cflag |= PARENB;    

              options.c_cflag &= ~PARODD;  

              options.c_iflag |= INPCK;      

       break;

       case 'S':  

       case 's': 

              options.c_cflag &= ~PARENB;

              options.c_cflag &= ~CSTOPB;

       break;

       default:

              fprintf(stderr,"Unsupported parity\n");

              return (FALSE);

       }

       

      switch (stopbits) {

     case 1:

           options.c_cflag &= ~CSTOPB;  //相应位置0

      break;

      case 2:

             options.c_cflag |= CSTOPB;

      break;

      default:

             fprintf(stderr,"Unsupported stop bits\n");

             return (FALSE);

      }

      

       if (flowctrl)

              options.c_cflag |= CRTSCTS;

       else

              options.c_cflag &= ~CRTSCTS;

     

      if (parity != 'n')

           options.c_iflag |= INPCK;

    // VTIME设定字节输入时间计时器

      options.c_cc[VTIME] = 150; // 15 seconds

       //VMIN设定满足读取功能的最低字节个数

    options.c_cc[VMIN] = 0;

       options.c_lflag &= ~(ECHO | ICANON);

      tcflush(fd,TCIFLUSH);       //刷新输入队列

      if (tcsetattr(fd,TCSANOW,&options) != 0) { //设置线路设置

           perror("SetupSerial 3");

             return (FALSE);

      }

       return (TRUE);

}

int OpenDev(char *Dev)  //打开串口

{

       int fd = open( Dev, O_RDWR );         //| O_NOCTTY | O_NDELAY

      if (-1 == fd) {

            perror("Can't Open Serial Port");

            return -1;

       } else

              return fd;

}

int main(int argc, char *argv[])

{

    int  fd, next_option, havearg = 0;

    char *device = "/dev/ttySAC1";

       int speed = 115200;

       int flowctrl = 0;

 

      int nread;              

      char buff[512];            

       pid_t pid;

       char *xmit = "com test by ptr 2012";

       sleep(1);

      fd = OpenDev(device);

      if (fd > 0) {

          set_speed(fd,speed);

      } else {

             fprintf(stderr, "Error opening %s: %s\n", device, strerror(errno));

             exit(1);

      }

       if (set_Parity(fd,8,1,'N',flowctrl)== FALSE) {

          fprintf(stderr, "Set Parity Error\n");

              close(fd);

          exit(1);

       

       pid = fork();  

       if (pid < 0) {

              fprintf(stderr, "Error in fork!\n");

    } else if (pid == 0){

              while(1) {

                     printf("SEND: %s\n",xmit);

                     write(fd, xmit, strlen(xmit));

                     sleep(1);

              }

              exit(0);

    } else {

              while(1) {

                     if (nread > 0) {

                            buff[nread] = '\0';

                            printf("RECV: %s\n", buff);

                     }

                

    }

       close(fd);

    exit(0);

}

 

测试结果:

虚拟机下编译arm-linux-gcc serial.c –o serial

在超级终端下运行./serial

可以看到:

SEND:com test by ptr 2012

RECV:com test by ptr 2012

关键字:Linux  串口  总线驱动 引用地址:Linux下的串口总线驱动(四)

上一篇:Linux下的串口总线驱动(三)
下一篇:stm32 can总线通信[库函数]

推荐阅读最新更新时间:2024-03-16 14:46

单片机串口通信UART与USART的区别
UART与USART都是单片机上的串口通信,他们之间的区别如下: 首先从名字上看: UART:universal asynchronous receiver and transmitter通用异步收/发器 USART:universal synchronous asynchronous receiver and transmitter通用同步/异步收/发器 从名字上可以看出,USART在UART基础上增加了同步功能,即USART是UART的增强型,事实也确实是这样。但是具体增强到了什么地方呢? 其实当我们使用USART在异步通信的时候,它与UART没有什么区别,但是用在同步通信的时候,区别就很明显了:大家都知道
[单片机]
Linux驱动曝光AMD Vega20核心:有望对应7nm加速卡
  这两天发硬件新闻总市心有戚戚,即便看到挺靠谱的消息,也总是有一种愚人节埋雷的隐忧。不过,下面这则,笔者仔细查验了一番,应该可信。下面就随嵌入式小编一起来了解一下相关内容吧。   据VideoCardz,在 Linux 的Freedesktop分支中,出现了Vega20的芯片识别代码。   Vega20识别出来了6种型号,此前Vega 10在驱动中识别出9种,覆盖Instinct、Radeon Pro和RX系列产品。     不过,按照 AMD 的规划,GPU产品线在2018年分为三个级别,其中高端桌面的Vega 56/64已经与我们见面,Vega Mobile已经用在APU和Intel的Kaby Lake-G中。而唯一称
[嵌入式]
再造STM32---第十七部分:USART—串口通讯
本章参考资料:《STM32F4xx 中文参考手册》 USART 章节。 学习本章时,配合《STM32F4xx 中文参考手册》 USART 章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。 特别说明, 本书内容是以 STM32F42xxx 系列控制器资源讲解。 17.1 串口通讯协议简介: 物理层: 规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。其实就是硬 件部分。 协议层: 协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。其实就是软件部分。 1-RS232标准: RS232标准串口通讯结构图: 1、 RS232标准串口主要用于工业设备直接通信 2、电平转换芯片一般有M
[单片机]
再造STM32---第十七部分:USART—<font color='red'>串口</font>通讯
#51单片机#蓝牙模块(ATKSPPHC06从机串口)的使用方法
#include AT89X51.H #include intrins.h // 函数原形定义 #define uchar unsigned char #define uint unsigned int void main (void); // 主函数 void LED_OUT(uchar X); // LED单字节串行移位函数 void LED_print (uchar p, uchar x) ; unsigned char code LED_0F ; // LED字模表 sbit DIO = P1^0; //串行数据输入 sbit RCLK = P1^1; //时钟脉冲信号 上升沿有效 sbit SCLK =
[单片机]
#51单片机#蓝牙模块(ATKSPPHC06从机<font color='red'>串口</font>)的使用方法
TI MSP430系列单片机串口通信波特率计算方法
TI MSP430系列单片机,usart模块的波特率值设定是通过以下三个寄存器决定的:UxBR0,UxBR1,UxMCTL 波特率=BRCLK/N ,主要是计算出N。 BRCLK:时钟源,可以通过寄存器设定何为时钟源; 通过寄存器UCAxCTL1的SSEL两位选择,01:ACLK,02:SMCLK N:波特率产生的分频因子。N=UxBR1+UxBR0+UxMCTL,其中UxBR1+UxBR0为整数部分,UxMCTL为设定小数部分,其中 UxBR1为高位,UxBR0为低位,两者结合起来为一个16位的字。 举例说明:波特率=115200,时钟源=8MHz ,为外部晶体振荡器 N=8000000/115200=69.44
[单片机]
嵌入式linux在工业控制领域中的应用
摘要:针对嵌入网络设备的应用特点,介绍了嵌入式linux的主要技术及在工业控制领域的应用方法。结合硬件平台详细说明了嵌入式linux系统的主要实现方法同时也简要介绍了该嵌入式系统的实时内核、内存机制和文件系统的设计等内容。 关键词:嵌入式系统;嵌入式linux;工业控制 1 前言 随着Internet的飞速发展,网络应用越来越广泛,对各种工业控制设备的网络功能要求也越来越高。当前的要求是希望工业控制设备能够支持TCP/IP以及其它Internet协议,从而能够通过用户熟悉的浏览器查看设备状态、设置设备参数,或者将设备采集到的数据通过网络传送到Windows或Unix/Linux服务器上的数据库中。这就要求工控系统必须具备两
[应用]
AVR串口多机通讯过程的解答
网友NE5532提问: AVR的串口说有多机通讯功能,就是在第一帧发送从机的地址,再发数据,呢么请问,从机的地址是在什么地方写的呢?是从机自己就包含地址(硬件)还是在软件上给从机赋值?DATASHEET里面好像没写啊。 -------------------------------------------------------------------------------- 马潮老师的解答: 根据你提的问题看,你对串口多机通信的过程是不清楚的,应该先深入了解和掌握多机通信的过程。 在多机通信过程中,所有设备的RS232接口是并在通信线上的,其中只能有一个设备为主机,其他为从机,通信由主机发起。数据帧一般采用1位起始位、9 位
[单片机]
arm linux 从入口到start_kernel 代码分析 - 5
4. 调用平台特定的 __cpu_flush 函数 当 __create_page_tables 返回之后 此时,一些特定寄存器的值如下所示: r4 = pgtbl (page table 的物理基地址) r8 = machine info (struct machine_desc的基地址) r9 = cpu id (通过cp15协处理器获得的cpu id) r10 = procinfo (struct proc_info_list的基地址) 在我们需要在开启mmu之前,做一些必须的工作:清除ICache, 清除 DCache, 清除 Writeb
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved