电气控制课程报告.docx
《电气控制课程报告.docx》由会员分享,可在线阅读,更多相关《电气控制课程报告.docx(21页珍藏版)》请在冰豆网上搜索。
电气控制课程报告
附录一
3.3电路图
3.3.1整体电路图如下:
该电路图主要由STC89C52RC单片机、单片机最小系统上的4*4矩阵键盘和4位八段数码管、用于多机通信的MAX485E芯片以及4位拨码开关。
位于电路图最下面的485芯片的7、6引脚接另一系统中485芯片的7、6引脚。
附录二:
3.3.2元件明细表
元件
数量
备注
拨码开关
1
DIP8
104电容
8
105电容
8
103电容
8
120欧姆电阻
2
1K欧姆电阻
8
MAX485ECPA
1
DIP8封装,maxim公司的芯片
双绞线
2米
STC89C52单片机最小系统实验箱
1
内含数码管、矩阵键盘、发光二极管
附录三:
系统实现程序清单:
Main函数:
#include"typedef.h"
#include"key.h"
#include"display.h"
#include"uart.h"
#include"delay.h"
#include"ModeOne_Send.h"
#include"ModeTwo_Receive.h"
#definePORT_MODEP0//P0.4-P0.7
sbitre_ta=P3^7;//0:
接收;1:
发送
u8GetMode(void);
voidRECEIVE_CODE(void);
voidM_RECEIVE_CODE(void);
volatileu8MODE;//变量定义
voidmain()
{
EA=0;
Variable_Init();
display_init();
UART_init();
REN=1;//串口允许接收
EA=0;
while(!
(MODE=GetMode()))
{
PORT_BYTESEC=0;
PORT_SEGSEC=0;
}
EA=1;//开中断
while
(1)
{
switch(MODE)
{
case1:
re_ta=1;SENE_CODE();delay_ms(100);//单发
break;
case2:
re_ta=0;RECEIVE_CODE();//单收
break;
case3:
re_ta=1;M_Send();MODE=2;//多发
break;
case4:
re_ta=0;M_Receive();//多收
break;
default:
break;
}
}
}
u8GetMode(void)
{
u8temp;
PORT_MODE|=0xf0;
delay_ms
(1);
temp=PORT_MODE;
temp&=0xf0;
switch(temp)
{
case0x70:
return1;//发送
break;
case0xb0:
return2;//接收
break;
case0xd0:
return3;//单发多收
break;
case0xe0:
return4;
break;
default:
return0;
}
}
延时模块:
#include"delay.h"
voiddelay_ms(u16ms)
{
u16i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
显示模块:
#include"display.h"
#include"delay.h"
#include"reg52.h"
u8num[4]={0};
staticu8*numPointer=num;
externvolatileu8Num_Count;
voiddisplay_init()
{
TMOD=TMOD|0x01;
TH0=45536/256;
TL0=45536%256;
EA=1;
ET0=1;
TR0=1;
}
voiddisplay(u8pos,u8dat)
{
if(pos==0)
num[0]=dat;
elseif(pos==1)
num[1]=dat;
elseif(pos==2)
num[2]=dat;
elseif(pos==3)
num[3]=dat;
}
u8getBDisNum()
{
u8disNum=num[2]*10+num[3];
returndisNum;
}
u8getFDisNum()
{
u8disNum=num[0]*10+num[1];
returndisNum;
}
voidTimer0_Server()interrupt1
{
ET0=0;
TH0=45536/256;
TL0=45536%256;
PORT_BYTESEC=PORT_BYTESEC|0x0f;
PORT_SEGSEC=table[num[0]];
PORT_BYTESEC=PORT_BYTESEC&0xfe;
delay_ms
(1);
if(Num_Count>1)
{
PORT_BYTESEC=PORT_BYTESEC|0x0f;
PORT_SEGSEC=table[num[1]];
PORT_BYTESEC=PORT_BYTESEC&0xfd;
delay_ms
(1);
}
if(Num_Count>2)
{
PORT_BYTESEC=PORT_BYTESEC|0x0f;
PORT_SEGSEC=table[num[2]];
PORT_BYTESEC=PORT_BYTESEC&0xfb;
delay_ms
(1);
}
if(Num_Count>3)
{
PORT_BYTESEC=PORT_BYTESEC|0x0f;
PORT_SEGSEC=table[num[3]];
PORT_BYTESEC=PORT_BYTESEC&0xf7;
delay_ms
(1);
}
ET0=1;
}
按键模块:
#include"key.h"
#include"delay.h"
sbitsound=P3^5;//蜂鸣器引脚
/*-----------------------------------------------------------------------
keyxy:
判定硬件编号
输入参数:
xx:
4位二进制;
-----------------------------------------------------------------------*/
u8keyxy(u8xx)
{
u8ans;
switch(xx)
{
case0x07:
ans=3;break;
case0x0b:
ans=2;break;
case0x0d:
ans=1;break;
case0x0e:
ans=0;break;
}
returnans;
}
/*-----------------------------------------------------------------------
lzkeyscan:
矩阵键盘扫描
返回值:
0-15
-----------------------------------------------------------------------*/
u8lzkeyscan(void)
{
u8h=10,l=10,s=ERROR,i,j,a,b[16];
PORT_KEY=0x0f;
while(PORT_KEY==0x0f);
delay_ms(10);//去抖
if(PORT_KEY!
=0x0f)
{
h=keyxy(PORT_KEY);
PORT_KEY=0xf0;
l=keyxy(PORT_KEY/16);
s=4*h+l;
for(i=0;i<200;i++)//让P3.5引脚电平不断取反输出音频
{
sound=0;
a=15;
while(a--);
sound=1;
a=15;
while(a--);
}//延时
}
returns;
}
模式一(即主从机之间单向通信):
#include"ModeOne_Send.h"
#include"key.h"
#include"uart.h"
volatileu8Num_Count=0;//用户变量
externu8num[4];//外部变量
externu8slaver_flag;
externu8rec_flag;
voidSENE_CODE(void)
{
u8key;
key=lzkeyscan();
++Num_Count;
if(Num_Count<1)
Num_Count=1;
if((Num_Count>4))
{
Num_Count=4;
}
switch(key)//矩阵键盘按键数值
{
case0:
movenum(Num_Count);num[0]=0;break;
case1:
movenum(Num_Count);num[0]=1;break;
case2:
movenum(Num_Count);num[0]=2;break;
case3:
movenum(Num_Count);num[0]=3;break;
case4:
movenum(Num_Count);num[0]=4;break;
case5:
movenum(Num_Count);num[0]=5;break;
case6:
movenum(Num_Count);num[0]=6;break;
case7:
movenum(Num_Count);num[0]=7;break;
case12:
movenum(Num_Count);num[0]=8;break;
case13:
movenum(Num_Count);num[0]=9;break;
case15:
SendNum();--Num_Count;Variable_Init();break;//发送
case14:
Num_Count-=2;backnum(Num_Count);break;//退后
default:
--Num_Count;break;
}
}
voidmovenum(u8num_count)//数码管数字向左移动
{
while(--num_count)
{
num[num_count]=num[num_count-1];
}
}
voidbacknum(u8num_count)//删除显示的数字
{
u8i;
for(i=0;i{
num[i]=num[i+1];
}
num[num_count]=0;
}
voidSendNum(void)
{
u8txbuf;
EA=0;
txbuf=num[1]*10+num[0];
UART_sendChar(txbuf);
EA=1;
}
voidVariable_Init(void)//数码管显示初始化
{
Num_Count=0;
num[0]=0;
num[1]=0;
num[2]=0;
num[3]=0;
rec_flag=0;
slaver_flag=0;
}
模式二(即主机与多个从机进行通信):
#include"ModeTwo_Receive.h"
#include"display.h"
externu8rBuf;
externu8rec_flag;
externu8num[4];
externvolatileu8Num_Count;
voidRECEIVE_CODE(void)
{
if(rec_flag)
{
ES=0;//关串口中断
if(num[1]=rBuf/10)
Num_Count=2;
else
Num_Count=1;
num[0]=rBuf%10;
//display(1,rBuf/10);
//display(0,rBuf%10);
rec_flag=0;
ES=1;//开串口中断
}
}
模式三(主机指定某从机发送数字给主机)
#include"ModeThree_MulSend.h"
#include"ModeOne_Send.h"
#include"uart.h"
#include"key.h"
#include"delay.h"
externu8num[4];
externvolatileu8Num_Count;
voidM_Send(void)//发送从机ID
{
u8key;
while((key=lzkeyscan())!
=12)
{
ChooseSlaver(key);
delay_ms(100);
}
UART_sendChar(num[0]);
Variable_Init();
}
voidChooseSlaver(u8key)//按键选择从机
{
switch(key)
{
case0:
num[0]=1;break;
case1:
num[0]=2;break;
case15:
num[0]=0;break;//退后
default:
break;
}
}
模式四
#include"ModeFour_MulReceive.h"
#include"display.h"
#include"uart.h"
#include"delay.h"
u8MyID=2;//从机编号,或者为1
u8slaver_flag=0;
externu8rec_flag;
externu8rBuf;
externu8num[4];
externvolatileu8Num_Count;
externvolatileu8MODE;
sbitTEST=P3^6;//发光二极管,其亮代表被主机选中
voidM_Receive(void)//从机2检验是否与自己的ID相同
{
u8txbuf;
if(rec_flag)
{
ES=0;//关串口中断
if(rBuf==MyID)
{
TEST=0;
Variable_Init();
MODE=1;
}
ES=1;//开串口中断
}
}
通信模块:
#include"uart.h"
#include"reg52.h"
#include"display.h"
u8rBuf=0;
u8rec_flag=0;
voidUART_init()//通信接口初始化
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
voidUART_sendChar(u8dat)//发送单个字符
{
REN=0;
ES=0;
SBUF=dat;
while(!
TI);
TI=0;
ES=1;
REN=1;
}
voidUART_sendStr(u8*str)//发送字符串
{
u8index=0;
while(*(str+index)!
='\0')
{
UART_sendChar(*(str+index));
index++;
}
}
u8UART_getRecBuf()
{
returnrBuf;
}
voidirq_rec()interrupt4//串口接收中断
{
RI=0;
rBuf=SBUF;
rec_flag=1;
}
显示.h文件:
#ifndef_DISPLAY_H
#define_DISPLAY_H
#include"typedef.h"
#definePORT_BYTESECP0//LED位选
#definePORT_SEGSECP2//LED段选
staticu8table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳数码管的0到9数字
voiddisplay_init(void);
voiddisplay(u8pos,u8dat);
u8getFDisNum(void);
u8getBDisNum(void);
#endif
按键.h文件:
#ifndef_KEY_H
#define_KEY_H
#include"reg52.h"
#include"typedef.h"
#definePORT_KEYP1
#defineERROR50
u8keyxy(u8xx);
u8lzkeyscan(void);
#endif
延时.h文件;
#ifndef_DELAY_H
#define_DELAY_H
#include"reg52.h"
#include"typedef.h"
voiddelay_ms(u16ms);
#endif
附录四:
通信模块测试过程:
A.单发单收,在发送状态,能够连续发送从0到99的数字
B.单发单收,在接收状态,能够接收数据,并在数码管上正确地显示出来
主机拨到1模式,从机2拨到2模式:
主机发送88:
从机2接收88:
发送其它数字亦同。
C.单发多收,在AB完成的基础上,接上多个接收设备,能够正确发送和接收
主机拨到1模式,从机1和从机2拨到2模式:
主机发送数字99:
两个从机均接收到数字99:
主机发送其它数字亦可以实现。
D.设定一个为主站,其余为从站,每次数据传输都由主站发起,即主站请求从站1发送数据,主站接收到,并显示在数码管上,主站再请求从站2发数据,从站2要能发送数据,并且主站要能收到并显示出来。
每个站点要在软件中设定站址
主机拨到3模式,从机均拨到4模式:
主机选中数字1并发送:
从机1的发光二极管亮,然后从机1发送数字66给主机:
主机接收到数字66: