linux 虚拟机串口通信,单片机和虚拟机里的Linux进行串口通信

2023-05-16

最近在做单片机的火焰传感器采集数据并且并且将危险信息发送给PC端的Linux。一直卡在Linux端的,所以,做了各种尝试,参考了网上一篇大神的代码,终于把自己的东西弄了出来。

先说明设备吧,CC2530单片机、linux下的pl2303的驱动、虚拟机环境下的CentOS以及minicom。

下面我把单片机端的代码贴出来:

/*

************************************************

*Name : serial_communication_CC2530 *

*Date : 2015-04-29 *

*Author : Sniper *

*Aim : fire sensor check the fire and send the *

* message to linux wihich though the *

* serial port. *

************************************************

*/

#include "ioCC2530.h"

#include

#include

#define uchar unsigned char

#define uint unsigned int

void Uart_send_char(int data);

uchar Recdata[]="fire!";

/*

* init the clock

*/

void initclk(void)

{

SLEEPCMD&= ~0X04;

CLKCONCMD = 0X10;

while(CLKCONSTA!=0X10);

SLEEPCMD = 0X04;//主频32M

}

/*

*init the uart

*/

void inituart(void)

{

IEN0|=0x84;//总中断,接收中断使能

U0CSR|=0xc0;//UART模式,允许接收

U0GCR=10;

U0BAUD=59;

}

/*

*init the IO

*/

void initio(void)

{

P0SEL|=0x0c;

}

/*

*Uart send the string

*/

void UartTX_Send_String(uchar Data[],int len)

{

int j;

for(j=0;j

{

U0DBUF = *Data++;

while(UTX0IF == 0);

UTX0IF = 0;

}

}

/*

*fire sensor check the fire , if the fire is occured.

*It will send the message.

*/

int main(void)

{

initio();

initclk();

inituart();

P0DIR|=0x40;

int i=0;

while(1)

{

if((P0&0x20)&& (i==0))

{

UartTX_Send_String(Recdata,sizeof(Recdata));

i++;

}

else if(!(P0&0x20))

{

i=0;

}

}

}

/*

*interupt

*/

#pragma vector=URX0_VECTOR

__interrupt void UART0_IRQ(void)

{

URX0IF=0;

U0DBUF=U0DBUF;

while(!UTX0IF);

UTX0IF=0;

}这个是linux端的代码,因为我用的设备设置是波特率38400、串口ttyUSB0、数据位8位、停止位1位、无校验方式。

/*

*************************************************

*Name : Serial_communication.c *

*Date : 2015-04-29 *

*Author : Sniper *

*Aim : make the CC2530 single chip and *

* Linux (CentOS) communication. *

* Linux receive and print the message*

*************************************************

*/

#include

#include

#include

#include

#include

#include

/*

*terminal device header file

*/

#include

#include

#include

/*

*struct termios

*

struct termios{

unsigned short c_iflag; //输入模式标志

unsigned short c_oflag; //输出模式标志

unsigned short c_cflag; //控制模式标志

unsigned short c_lflag; //区域模式标志或本地模式标志或局部模式

unsigned char c_line; //行控制line discipline

unsigned char c_cc[NCC]; // 控制字符特性

};

*/

#defineSERIAL_PORT"/dev/ttyUSB0"//串口地址

#definePORT_SPEED38400//串口波特率

#defineDATABITS8//数据位

#defineSTOPBITS1//停止位

#definePARITY'n'//校验方式 (不校验)

int setSpeed(int, int, struct termios*);

int setParity(int, int, int, int, struct termios);

int openPort(void);

int init(void);

void readPort(int);

int main()

{

char *quit = (char*)malloc(sizeof(char*));

int fd;

char write_buf[256];

memset(write_buf,'\0',sizeof(write_buf));

fd = init();//初始化端口设置

printf("configure complete\n");

printf("start send and receive data...\n");

while(1)

{

readPort(fd);

}

close(fd);

}

void readPort(int fd)

{

int i;

int len;

int n;

char read_buf[256];

memset(read_buf,'\0',sizeof(read_buf));

while(1)

{

bzero(read_buf, sizeof(read_buf));

while((n = read(fd, read_buf, sizeof(read_buf))) > 0)

{

printf("%s\n", read_buf);

}

}

}

/*

*init serial port

*1 failure, 0 success

*/

int init(void)

{

int fd;

struct termios opt;//定义termios结构

//打开串口

fd = openPort();

//设置波特率

if(setSpeed(fd, PORT_SPEED, &opt) == 1)

{

printf("setSpeed failed!\n");

exit(1);

}

//设置数据位、停止位和校验位

if(setParity(fd, DATABITS, STOPBITS, PARITY, opt) == 1)

{

printf("setParity failed!\n");

exit(1);

}

if(tcsetattr(fd, TCSANOW, &opt) != 0)//TCSANOW:不等数据传输完毕就立即改变属性。

{//TCSADRAIN:等待所有数据传输结束才改变属性。

perror("serial error");

return -1;

}

return fd;

}

/*

*openPort function

*1 failure, 0 success

*/

int openPort()

{

int fd;

/*

*serial address is /dev/ttyUSB*, open the serial address

*/

fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY |O_NDELAY);

if(fd == -1)

{

perror("open serial failed!\n");

exit(1);

}

return fd;

}

/*

*setSpeed

*SetSpeed(38400, 19200, 9600, 4800, 2400, 1200, 300)

* 1 failure, 0 success

*/

int setSpeed(int fd, int speed, struct termios *Opt)

{

int i;

if(tcgetattr(STDIN_FILENO, &Opt) != 0)

{

perror("tcgetattr fd\n");

return 1;

}

/*

*set speed

*/

tcflush(fd, TCIOFLUSH);

cfsetispeed(&Opt, speed);

cfsetospeed(&Opt, speed);

//set ways of receive

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

{

perror("tcsetattr fd");

return 1;

}

tcflush(fd, TCIOFLUSH);

return 0;

}

/*

*setParity

*set the data bit,stop bit and check bit

* 1 failure, 0 success

*/

int setParity(int fd, int databits, int stopbits, int parity, struct termios Opt)

{

if(tcgetattr(fd, &Opt) != 0)

{

perror("tcgetattr fd");

return 1;

}

Opt.c_cflag |= (CLOCAL | CREAD);

/*

*Data bit

*/

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS8;

/*

*check bit

*/

Opt.c_cflag &= ~PARENB;

Opt.c_iflag &= ~INPCK;

/*

*stop bit

*/

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag |= (CLOCAL | CREAD);

Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

Opt.c_oflag &= ~OPOST;//OPOST :启用具体实现自行定义的输出处理。

Opt.c_oflag &= ~(ONLCR | OCRNL); //OCRNL :将输出中的回车映射为新行符

//ONLCR :(XSI) 将输出中的新行符映射为回车-换行。

Opt.c_iflag &= ~(ICRNL | INLCR);//ICRNL :将输入中的回车翻译为新行 (除非设置了 IGNCR)(否则当输入信号有 CR 时不会终止输入)。

//INLCR :将输入中的 NL 翻译为 CR。(将收到的换行符号转换为Return)

Opt.c_iflag &= ~(IXON | IXOFF | IXANY);//IXON :启用输出的 XON/XOFF 流控制。

//IXOFF :启用输入的 XON/XOFF 流控制。

//IXANY :(不属于 POSIX.1;XSI) 允许任何字符来重新开始输出。

tcflush(fd, TCIFLUSH);//清空输入缓存

//MIN = 0 , TIME =0; 有READ立即回传否则传回 0,不读取任何字元

Opt.c_cc[VTIME] = 0;

Opt.c_cc[VMIN] = 0;

if(tcsetattr(fd, TCSANOW, &Opt) != 0)//设置数据接收方式

{

perror("tcsetattr fd");

return 1;

}

return 0;

}运行方式:(1)生成可执行文件,执行。(2)打开minicom,设置相关参数。(3)接上单片机,并且打开电源。

linux端的代码参考了一下网址,此外,因为个人需要,做了相应的缩减,望大家批评指正:

http://blog.csdn.net/cooljun008/article/details/8181906

这个单片机可以使用别的单片机,只要通信的方式的参数对了,应该都可以通信。

下面一篇会分享两者通过串口双向通信,敬请期待!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux 虚拟机串口通信,单片机和虚拟机里的Linux进行串口通信 的相关文章

随机推荐