Linux下串口协议控制51单片机.docx

上传人:b****6 文档编号:7354294 上传时间:2023-01-23 格式:DOCX 页数:16 大小:17.75KB
下载 相关 举报
Linux下串口协议控制51单片机.docx_第1页
第1页 / 共16页
Linux下串口协议控制51单片机.docx_第2页
第2页 / 共16页
Linux下串口协议控制51单片机.docx_第3页
第3页 / 共16页
Linux下串口协议控制51单片机.docx_第4页
第4页 / 共16页
Linux下串口协议控制51单片机.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

Linux下串口协议控制51单片机.docx

《Linux下串口协议控制51单片机.docx》由会员分享,可在线阅读,更多相关《Linux下串口协议控制51单片机.docx(16页珍藏版)》请在冰豆网上搜索。

Linux下串口协议控制51单片机.docx

Linux下串口协议控制51单片机

linux下串口协议控制51单片机(涉及多线程操作)

/***************************************************************************

writenbyjingshui7-17201112:

53

说明:

这是一个linux下串口,多线程测试程序

Version0.26

***************************************************************************/

#include

#include

#include

#include

#include

#include

#include

#include

#include

intfd;

pthread_tthread[2];

pthread_mutex_tmutex;

/****************************************************************************

结构体说明:

传送控制单片机的信息

成员1:

select选择功能模块

成员2:

control控制单片机相应的动作

*****************************************************************************/

structprotocal

{

unsignedcharselect;

unsignedcharcontrol;

};

structprotocalptr[14]={{0xa1,0x01},{0xa1,0x02},{0xa1,0x03},{0xa1,0x04},{0xa1,0x05},

{0xa1,0x06},{0xa1,0x07},{0xa1,0x08},{0xb2,0x00},{0xb2,0x03},

{0xb2,0x06},{0xb2,0x09},{0xb2,0x0e},{0xc3,0xd4}};

/********************************************************************

功能说明:

设置linux串口参数

传入参数:

fdnspeednbitneventnstop

文件句柄波特率数据位奇偶校验停止位

返回值:

fd文件句柄

********************************************************************/

intset_port(intfd,intnspeed,intnbits,charnevent,intnstop)

{

structtermiosnewtio,oldtio;

if(tcgetattr(fd,&oldtio)!

=0)

{

perror("setupserial");

return-1;

}

bzero(&newtio,sizeof(newtio));

newtio.c_cflag|=CLOCAL|CREAD;

newtio.c_cflag&=~CSIZE;

switch(nbits)

{

case7:

newtio.c_cflag|=CS7;

break;

case8:

newtio.c_cflag|=CS8;

break;

}

switch(nevent)

{

case'N':

newtio.c_cflag&=~PARENB;

break;

}

switch(nspeed)

{

case9600:

cfsetispeed(&newtio,B9600);

cfsetospeed(&newtio,B9600);

break;

}

switch(nstop)

{

case1:

newtio.c_cflag&=~CSTOPB;

break;

case2:

newtio.c_cflag|=CSTOPB;

break;

}

newtio.c_cc[VTIME]=0;

newtio.c_cc[VMIN]=14;

tcflush(fd,TCIFLUSH);

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

=0)

{

perror("comset");

return-1;

}

return0;

}

intopen_port(intfd,intcomport)

{

if(comport==1){

fd=open("/dev/ttyUSB0",O_RDWR);

if(-1==fd){

perror("can'topenserialport");

return-1;

}

}

returnfd;

}

voidwrite_port(void)

{

intnwrite,i;

for(i=0;i<14;i++)

{

nwrite=write(fd,&ptr[i],2);

usleep(200000);/*每200ms秒发一次数据*/

}

}

voidread_port(void)

{

fd_setrd;

intnread,retval;

unsignedcharmsg[14];

structtimevaltimeout;

FD_ZERO(&rd);

FD_SET(fd,&rd);

timeout.tv_sec=1;

timeout.tv_usec=0;

retval=select(fd+1,&rd,NULL,NULL,&timeout);/*select实现i/o复用*/

switch(retval)

{

case0:

printf("nodatainputwithin1seconds.\n");

break;

case-1:

perror("select");

break;

default:

if((nread=read(fd,msg,14))>0)

{

printf("nread=%d,msg=%s\n",nread,msg);

}

break;

}

}

void*recv_thread(void)

{

pthread_mutex_lock(&mutex);

read_port();

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

}

void*send_thread(void)

{

pthread_mutex_lock(&mutex);

write_port();

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

}

voidcreate_thread(void)

{

inttemp;

memset(thread,0,sizeof(thread));

if((temp=pthread_create(&thread[0],NULL,(void*)send_thread,NULL))!

=0)

printf("createsend_threadfailed!

\n");

if((temp=pthread_create(&thread[1],NULL,(void*)recv_thread,NULL))!

=0)

printf("createrecev_threadfailed!

\n");

}

voidwait_thread(void)

{

if(thread[0]!

=0)

{

pthread_join(thread[0],NULL);

printf("send_threadend\n");

}

if(thread[1]!

=0)

{

pthread_join(thread[1],NULL);

printf("recev_threadend\n");

}

}

intmain(void)

{

inti;

if((fd=open_port(fd,1))<0){

perror("open_porterror");

}

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

perror("set_opterror");

}

/*用默认属性初始化互斥锁*/

pthread_mutex_init(&mutex,NULL);

intnum=100;

while(num)

{

create_thread();

wait_thread();

num--;

}

pthread_mutex_destroy(&mutex);

close(fd);

return0;

}

51单片机程序

#include

typedefunsignedcharuint8;

typedefunsignedintuint16;

sbitkey=P3^2;

sbits1=P2^0;//选通数码管1

sbits2=P2^1;

sbits3=P2^2;

sbits4=P2^3;

sbiten=P2^5;//573锁存使能位

sbitbuzzer=P2^4;//蜂鸣器选通位

sbitkey1=P3^2;

sbitkey2=P3^3;

sbitkey3=P3^4;

sbitkey4=P3^5;

sbitkey5=P3^7;

uint8i=0;

uint8r_data[2];//用来接收数据的缓冲区

uint8codesmg[16]={0xC0,0xF9,0xA4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

unsignedcharcodepmd[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsignedcharcodes_data1[]="key1pressed\n";

unsignedcharcodes_data2[]="key2pressed\n";

unsignedcharcodes_data3[]="key3pressed\n";

unsignedcharcodes_data4[]="key4pressed\n";

unsignedcharcodes_data5[]="key5pressed\n";

voidinit_serial(void)//初始化串口

{

TMOD=0x20;//设置定时器1工作方式1;

TH1=0xFD;//波特率发生器,产生9600的波特率

TL1=0xFD;

PCON=0x00;

SCON=0x50;//选择串口工作方式1,允许接收

EA=1;//开中断

ES=1;

TR1=1;//启动定时器

}

voiddelay(uint16i)//20ms

{

unsignedcharj,k;

for(j=i;j>0;j--)

for(k=115;k>0;k--);

}

voidtest_serial1(void)

{

inti;

EA=0;

for(i=0;i

{

SBUF=s_data1[i];

while(TI==0);

TI=0;

}

EA=1;

}

voidtest_serial2(void)

{

inti;

EA=0;

for(i=0;i

{

SBUF=s_data2[i];

while(TI==0);

TI=0;

}

EA=1;

}

voidtest_serial3(void)

{

inti;

EA=0;

for(i=0;i

{

SBUF=s_data3[i];

while(TI==0);

TI=0;

}

EA=1;

}

voidtest_serial4(void)

{

inti;

EA=0;

for(i=0;i

{

SBUF=s_data4[i];

while(TI==0);

TI=0;

}

EA=1;

}

voidtest_serial5(void)

{

inti;

EA=0;

for(i=0;i

{

SBUF=s_data5[i];

while(TI==0);

TI=0;

}

EA=1;

}

voidled_control(uint8i)//led控制模块

{

unsignedcharx;

if(i>8)

{

P1=0xff;

delay(10);

}

else

{

x=i-1;

P1=pmd[x];

delay(80);

P1=0xff;

}

}

voidseg_control(uint8i)//数码管控制模块

{

en=1;

s1=0;

s3=0;

s2=0;

s4=0;

if(i>0x0f)

{

P0=0xff;

delay(10);

}

else

{

P0=smg[i];

delay(80);

P0=0xff;

}

}

voidbuzzer_control(uint8i)//蜂鸣器控制模块

{

if(i==0xd4)

buzzer=0;

delay(100);

buzzer=1;

}

voidhandle_date()

{

uint8i=r_data[0];

switch(i)

{

case0xa1:

led_control(r_data[1]);

break;

case0xb2:

seg_control(r_data[1]);

break;

case0xc3:

buzzer_control(r_data[1]);

default:

break;

}

}

voidreadkey(void)

{

RI=0;

if(!

key1)

{

delay(30);

if(!

key1)

{

test_serial1();

while(!

key1);

}

}

if(!

key2)

{

delay(30);

if(!

key2)

{

test_serial2();

while(!

key2);

}

}

if(!

key3)

{

delay(30);

if(!

key3)

{

test_serial3();

while(!

key3);

}

}

if(!

key4)

{

delay(30);

if(!

key4)

{

test_serial4();

while(!

key4);

}

}

if(!

key5)

{

delay(30);

if(!

key5)

{

test_serial5();

while(!

key5);

}

}

}

voidmain(void)

{

init_serial();

while

(1)

{

readkey();

}

}

voidserver(void)interrupt4

{

ES=0;

RI=0;

r_data[i]=SBUF;

if(2==++i)

{

handle_date();

i=0;

}

ES=1;

}

/*******************************************************************************

writenbyjingshui

说明:

51单片机检测程序,把从上位机接收的数据发回去。

*******************************************************************************/

#include

bitflag;

unsignedchara,i;

voidinit_serial(void)

{

TMOD=0x20;//定时器1的工作方式2

TL1=0xfd;//装载计数初值

TH1=0xfd;

SCON=0x50;//采用串口工作方式1,无奇偶校验

PCON=0x00;//串口波特率不加倍

IE=0x90;//开总中断,开串口中断

TR1=1;//启动定时器1

}

voidmain()

{

init_serial();

while

(1)

{

if(flag==1)

{

ES=0;

SBUF=a;

while(!

TI);

TI=0;

ES=1;

flag=0;

}

}

}

voidisr()interrupt4

{

RI=0;

a=SBUF;

flag=1;

}

编程经验:

1.51相对来说是一个很低端的处理器,所以上位机要注意加延时,下位机程序不应有很复杂的语法。

2.调试时应一步步追踪。

3.从最简单朴素的例子开始,先搭一个简单的框架,再一步步添加其他功能。

4.注意实践和理论的结合,理论不行先实践,实践受挫在看理论。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1