说明:整理之前项目博客,此系列之前发表于与非网
http://www.openhw.org/module/forum/thread-552493-1-1.html
除了ZED与数据库的网络通信外,ZED与8051的通信也是我们小组设计计划中另一重要部分,我们用8051模拟用电器工作,因此需要通过ZED来猜的8051的工作状态,经过处理后在通过网络传送至数据库。
我们的设计是ZED与88051之间通过UART接口传输数据,因此首先实现Linux环境下PC与8051的通信,再移植至ZED板,网上的教程有很多,我直接上程序。
PC端(移植后的ZED板端):
#include
#include
#include
#include
#include
#include
#include
void init(int fd)
{
struct termios new1,old;
if (fd==-1)
{
printf("Error when open the com! \n");
exit(-1);
}
tcgetattr(fd,&old);
//得到串口缺省参数设置,以便用完后恢复缺省设置
bzero(&new1,sizeof(new1));
//设置波特率,8个数据位,本地链接
new1.c_cflag=B4800|CS8|CLOCAL|CREAD;
new1.c_iflag=IGNPAR;
new1.c_oflag=0;
new1.c_lflag=0;
//设定每接收到一个字符立即读取
new1.c_cc[VMIN]=1;
new1.c_cc[VTIME]=0;
tcflush(fd,TCIOFLUSH); //清除输入输出缓冲流
tcsetattr(fd,TCSANOW,&new1); //设置立即生效
}
int main(void)
{
int fd=open("/dev/ttyUSB0",O_RDWR);
char wbuf[800]="b101010",rbuf[800]="";
init(fd);
write(fd,wbuf,10);
read(fd,rbuf,10);
printf("read string is %s\n",rbuf);
return 0;
}
8051端:
#include //52系列单片机头文件
#define uchar unsigned char
#define uint unsigned int
uchar add,add1,c; //
uchar temp[5];
uchar temp1[7];
uchar seg4[4]; //暂存接收数据
uchar led6[6];
uint flag1,flag2;
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit key1=P3^2;
sbit key2=P3^3;
uchar code position[]={0xfe,0xfd,0xfb,0xf7}; //数码管位置数组
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管编码
void display(); //声明子函数
void delay(uint z); //声明子函数
void Init(); //初始化函数
void main()
{
Init();
display();
}
void display()
{
while(1)
{
if((temp[0]+48)=='a')
{
seg4[0]=temp[1];
seg4[1]=temp[2];
seg4[2]=temp[3];
seg4[3]=temp[4];
}
P2=position[0];
P0=table[seg4[0]]; //给第一个数码管送"a"
delay(1); //延时1ms
P2=position[1];
P0=table[seg4[1]]; //给第二个数码管送"b"
delay(1); //延时1ms
P2=position[2];
P0=table[seg4[2]]; //给第三个数码管送"c"
delay(1); //延时1ms
P2=position[3];
P0=table[seg4[3]]; //给第三个数码管送"d"
delay(1);
if((temp1[0]+48)=='b')
{
led6[0]=temp1[1];
led6[1]=temp1[2];
led6[2]=temp1[3];
led6[3]=temp1[4];
led6[4]=temp1[5];
led6[5]=temp1[6];
}
led0=led6[0];
led1=led6[1];
led2=led6[2];
led3=led6[3];
led4=led6[4];
led5=led6[5];
} //延时1ms
}
void delay(uint z) //延时子函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*******初始化函数**********/
void Init()
{
TMOD=0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1=0xFD; // 波特率9600
TL1=0xFD;
SCON=0x50; // 设定串行口工作方式
PCON&=0xef; // 波特率不倍增
TR1=1; // 启动定时器1
EA=1; //开总中断
ES=1; //串行中断允许
EX0 = 1; //打开外部中断0
EX1 = 1; //打开外部中断1
IT0 = 1; //外部中断0触发方式选择位: 72页
IT1 = 1; //外部中断1触发方式选择位
IP = 0x01; //外部中断0定义为高优先级中断
P0=0x3f;
P2=0x00;
add=0;
flag1=1;
flag2=1;
}
void Serial_INT() interrupt 4 //串口中断
{
c=SBUF;
if(RI)
{
if(c=='a')
{
add=0;
}
temp[add]=SBUF-48;
RI=0;
add++;
if(add==5)
add=0;
if(c=='b')
{
add1=0;
}
temp1[add1]=SBUF-48;
RI=0;
add1++;
if(add1==7)
add1=0;
}
}
void EX_INT0() interrupt 0 //外部中断0
{
if(key1==0)
{
delay(10);
if((key1==0)&&flag1)
{
led6[0]=0;
ES=0;
SBUF='1';
flag1=0;
temp1[0]='0';
while(!TI);
TI=0;
ES=1;
}
else if((key1==0)&&(flag1==0))
{
led6[0]=1;
ES=0;
SBUF='2';
flag1=1;
temp1[0]='0';
while(!TI);
TI=0;
ES=1;
}
}
}
void EX_INT1() interrupt 2 //外部中断1
{
if(key2==0)
{
delay(10);
if((key2==0)&&flag2)
{
led6[1]=0;
ES=0;
SBUF='3';
flag2=0;
temp1[0]='0';
while(!TI);
TI=0;
ES=1;
}
else if((key2==0)&&(flag2==0))
{
led6[1]=1;
ES=0;
SBUF='4';
flag2=1;
temp1[0]='0';
while(!TI);
TI=0;
ES=1;
}
}
}
操作:
1.将8051通过USB连接至电脑,在虚拟机中确定所占用com名称,修改相应程序部分。
2.在 server.cpp 目录下用管理员权限运行 ./server
3.在8051上按键,会在8051的七段显示器上显示由PC发送的数据,在PC上的终端中也会打印出8051返回的数据。
4.交叉编译server.cpp得到server.out,拷贝至ZED板SD卡的FAT分区,操作方法一致。