Linux下串口协议控制51单片机.docx
- 文档编号:7354294
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:16
- 大小:17.75KB
Linux下串口协议控制51单片机.docx
《Linux下串口协议控制51单片机.docx》由会员分享,可在线阅读,更多相关《Linux下串口协议控制51单片机.docx(16页珍藏版)》请在冰豆网上搜索。
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.注意实践和理论的结合,理论不行先实践,实践受挫在看理论。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 串口 协议 控制 51 单片机
