LINUX下(虚拟机中的LINUX系统)串口通讯 part2------示例代码

来源:互联网 发布:博客程序源码 编辑:程序博客网 时间:2024/05/22 00:12

LINUX  c部分:

 

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>

 

**************设置串口函数*******************

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
     struct termios newtio,oldtio;
     if ( tcgetattr( fd,&oldtio) != 0)

    {
         perror("SetupSerial 1");
         return -1;
    }
    bzero( &newtio, sizeof( newtio ) );
    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch( nBits )
   {
         case 7:
         newtio.c_cflag |= CS7;
         break;
         case 8:
         newtio.c_cflag |= CS8;
         break;
   }

   switch( nEvent )
  {
         case 'O':
         newtio.c_cflag |= PARENB;
         newtio.c_cflag |= PARODD;
         newtio.c_iflag |= (INPCK | ISTRIP);
         break;
        

         case 'E':
         newtio.c_iflag |= (INPCK | ISTRIP);
         newtio.c_cflag |= PARENB;
         newtio.c_cflag &= ~PARODD;
         break;
        

         case 'N':
          newtio.c_cflag &= ~PARENB;
          break;
   }

   switch( nSpeed )
   {
         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 115200:
         cfsetispeed(&newtio, B115200);
         cfsetospeed(&newtio, B115200);
         break;

         default:
         cfsetispeed(&newtio, B9600);
         cfsetospeed(&newtio, B9600);
         break;
   }
   if( nStop == 1 )
   newtio.c_cflag &= ~CSTOPB;
   else if ( nStop == 2 )
   newtio.c_cflag |= CSTOPB;

   newtio.c_cc[VTIME] = 0;
   newtio.c_cc[VMIN] = 0;

   tcflush(fd,TCIFLUSH);

   if((tcsetattr(fd,TCSANOW,&newtio))!=0)
   {
         perror("com set error");
         return -1;
   }
   printf("set done!/n");
   return 0;

}

 

*********************打开串口函数********************

int open_port(int fd,int comport)
{
     char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
     long vdisable;
     if (comport==1)
     { 

           fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);
           if (-1 == fd)

           {
                  perror("Can't Open Serial Port");
                  return(-1);
           }
           else 
          {

                  printf("open ttyS0 ...../n");

          }
     }
     else if(comport==2)
     {

           fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
           if (-1 == fd)

           {
                   perror("Can't Open Serial Port");
                   return(-1);
            }
            else 
            { 

                   printf("open ttyS1 ...../n");

            }
     }
     else if (comport==3)
    {
             fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);
             if (-1 == fd)

             {
                    perror("Can't Open Serial Port");
                    return(-1);
             }
             else
             {

                     printf("open ttyS2 ...../n");

             }
    }

    if(fcntl(fd, F_SETFL, 0)<0)
    printf("fcntl failed!/n");
    else
    printf("fcntl=%d/n",fcntl(fd, F_SETFL,0));

   

    if(isatty(STDIN_FILENO)==0)
    printf("standard input is not a terminal device/n");
    else
    printf("isatty success!/n");

 

    printf("fd-open=%d/n",fd);
    return fd;
}

**************主函数(读串口)************************
int main(void)
{
      int fd;
      int nwrite,i,j=0;
      char buff[40];

 

      if((fd=open_port(fd,2))<0)

      {
              perror("open_port error");
              return;
      }//这里必须要用Com1,其他的试了,都不行。

      if((i=set_opt(fd,9600,8,'N',1))<0)

      {
              perror("set_opt error");
              return;
      }
      printf("fd=%d/n",fd);
      fd = 3;


      sleep(1);
      nwrite=read(fd,bod,40);
      printf("nwrite=%d,bod=%s/n",nwrite,bod);
      close(fd);
      return;
}

 

 

 

单片机 C部分:

 

/*RS-232串口*/

#include "reg52.h"

typedef unsigned char uint8;
typedef unsigned int  uint16;

 

sbit key = P3^2;

 

void _delay(uint16 ms) // 延时子程序

{            uint8 i ;
      while(ms--)
      {
            for(i = 0 ; i<250;i++) ;
      }
}

 

 

void init_serial(void) 
{
     TMOD=0x20; //定时器1的工作方式2
     TL1=0xfd;   //装载计数初值
     TH1=0xfd; 
     SCON=0x50; //采用串口工作方式1,无奇偶校验
     PCON=0x00;  //串口波特率不加倍
     //IE=0x90; 没有用到中断
     TR1=1;      //启动定时器1
}

code unsigned char send_txt[]={"Serial Interface Test OK!/n"};

void test_serial(void)
{
       int i;
      //串口是一位一位串行发送,而到达PC机(包括虚拟机)后有一个串并转换,它是先把数据放到缓存里,然后再一并发送(个人理解)

      for(i=0;i<sizeof(send_txt);i++)
      {
              SBUF=send_txt[i];
              while(TI==0);
              TI=0;
      }
}

 

void getch(void) //按下按键后就将字符串发送一遍
{
      RI=0;

      if(!key)
     {
           _delay(20);
           if(!key)
           { 
                 test_serial();
                 while(!key);
           }
      }       
}

 

main()
{
       init_serial();
       while(1)
       {
            getch();
        }  
}

                    

只要把单片机部分的C程序编译生成HEX文件烧到单片机内,然后通过串口把单片机和PC连接起来, 然后在PC上运行相应程序后,按下按键后就可以看到读取到的单片机发送给PC机的字符串。