【嵌入式LINUX系统编程】嵌入式LINUX串口编程

(一)背景介绍

串口编程算是学完了,对于LINUX系统编程我也已经有了一个初步的概念
本来以为LINUX没了库函数 得要一个位一个位的去设置和单片机没有库函数一样,现在发现自己错了
LINUX作为一个中介,很好的将底层函数与上层系统分割开来,所有的操作都是围绕着文件展开的,在完成驱动的封装后我们所需要做的仅仅就是对于文件的读取与写入。
怪不到之前听说LINUX中一切都是文件。
观察LINUX的文件进入 dev文件夹 所有的硬件都被打包成文件

这次来搞个串口的编程

实现开机后打印10个HELLOWORLD
然后进入死循环轮询串口:收到指令后将收到的内容返回

(二)软件设计


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

int set_opt(int,int,int,char,int);

void main(){
	int fd,wr_static,i=10,nByte;
	char *uart3 = "/dev/ttySAC3";
	char *buffer0 = "hello world!\n";
	char *buffer1 = "你发送的消息为:\n";
    char buffer[512];	
	char *uart_out = "please input\r\n";
	memset(buffer, 0, sizeof(buffer));
    if((fd=open(uart3,O_RDWR|O_CREAT,0777))<0)
	{
		printf("failed");

	}
	else{
		printf("success");
        set_opt(fd, 115200, 8, 'N', 1); 
		//发送十次数据
		while(i--)
		{
			wr_static = write(fd,buffer0, strlen(buffer0));
            //向设备结点写入10次数据
			if(wr_static<0)
				printf("write failed\n");
			else{
				printf("wr_static is %d\n",wr_static);
			}
			sleep(1);
		}
        write(fd,uart_out, strlen(uart_out));
   		while(1){
				//如果串口读到数据
		   //提醒输入
		   
			while((nByte = read(fd, buffer, 512))>0){
				buffer[nByte+1] = '\0';//在数据后加结束符
 				write(fd,buffer1,strlen(buffer1));//把接收到的发送回去            				
				write(fd,buffer,strlen(buffer));//把接收到的发送回去
				memset(buffer, 0, strlen(buffer));//将接受buffer清空
				nByte = 0;
			}
	
	
		
		
		
		
	             }
       close(fd);

	}

   

}


//串口通用初始化函数
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio,oldtio;//定义结构体newtio和oldtio
	//测试串口能否运行并将原串口的数据取到oldtio
	if  ( tcgetattr( fd,&oldtio)  !=  0) { 
		perror("SetupSerial 1");
		return -1;
	}
	//将newio清零和设置c_cflag
	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;
	case 460800:
		cfsetispeed(&newtio, B460800);
		cfsetospeed(&newtio, B460800);
		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;//读取最小字符数为0
	tcflush(fd,TCIFLUSH);//清空缓冲区
	//进行初始化设置
	if((tcsetattr(fd,TCSANOW,&newtio))!=0)
	{
		perror("com set error");
		return -1;
	}
//	printf("set done!\n\r");
	return 0;
}

对于一般的片上系统都会将串口的底层进行一步封装。
实现上没有任何困难,底层已经完全被打包好了,调用API函数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

与光同程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值