单片机综合控制器实验.docx

上传人:b****7 文档编号:10243122 上传时间:2023-02-09 格式:DOCX 页数:25 大小:116.02KB
下载 相关 举报
单片机综合控制器实验.docx_第1页
第1页 / 共25页
单片机综合控制器实验.docx_第2页
第2页 / 共25页
单片机综合控制器实验.docx_第3页
第3页 / 共25页
单片机综合控制器实验.docx_第4页
第4页 / 共25页
单片机综合控制器实验.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

单片机综合控制器实验.docx

《单片机综合控制器实验.docx》由会员分享,可在线阅读,更多相关《单片机综合控制器实验.docx(25页珍藏版)》请在冰豆网上搜索。

单片机综合控制器实验.docx

单片机综合控制器实验

单片机综合性设计性实验报告

 

实验项目名称:

单片机综合控制器实验

实验室(中心):

电子实验室

实验完成时间:

09年11月25日

 

 

一.实验目的与要求

通过仿真搭建和实物搭建相结合,完成灵活可变的单片机最小系统设计,并掌握地址空

间的分配操作。

通过仿真搭建和实物搭建相结合,万用交叉口交通灯控制器系统设计,并掌握C51编程

操作。

2.实验内容

(1)以6264或6116为扩展的存储芯片,8255或8155芯片为键盘显示控制芯片,建立基本

的串行口,普通的I/O口,A/D转换,D/A转换口功能。

(2)用Proteus仿真软件搭建仿真硬件电路图。

验证编制软件。

(3)用protel99s布原理图、建PCB板图。

(4)实物器件焊接搭建。

模拟控制就是以红、绿、黄色4组12个发光二极管表示交通信号灯。

每组灯有两位数

码倒倒计时显示。

假设一个十字路口为东西南北走向。

初始状态0为东西红灯,南北红灯。

然后转状态1,

东西方向的绿灯亮,东西方向可通车,而南北方向的红灯亮,南北方向的车禁止通行。

过一

段时间转状态2,东西绿灯灭后,黄灯亮,延时几秒,南北仍然红灯。

再转状态3,南北方向

的绿灯亮,南北方向可以通车,而东西方向的红灯亮,东西方向禁止车辆通行。

过一段时间

转状态4,南北绿灯灭后亮黄灯,延时几秒,东西方向仍然红灯亮。

最后循环至状态1。

用Proteus仿真软件搭建仿真硬件电路图。

验证编制软件。

三.实验原理及实验线路

 

4.实验器材

表2.5.2最小系统的硬件元件清单:

单片机AT89C52瓷片电容CAP30pF晶振CRYSTAL12MHz

电解电容CAP-ELEC电阻RES按钮BUTTON

发光二极管LED-BIRG发光二极管LED-BIBY开关SWITCH

排阻RESPACK-8发光二极管LED-BIGY发光二极管LED-YELLOW

按键16个8255芯片74LS138芯片74LS373DAC0809

5.系统流程图

开始

延时等待系统准备好

系统初始化初始化

N

N

N

P32==0?

P35==0?

P31==0?

P34==0?

Y

Y

Y

Y

启动键盘扫描

启动波形发生器

启动模拟交通灯

启动AD转换

产生锯齿波

N

‘0’键按下

初始化计数变量

采样频率0.5Hz

Y

N

P32==0?

调用彩灯功能

显示当前计数变量初值

将转化的数字量转换成十进制数

N

Y

产生方波

显示按键值

1秒到了?

显示测量的结果

N

Y

P32==0?

计数变量减1

N

Y

满足下一种状态的条件?

Y

6、硬件设计框图

 

显示

输出

 

AT89C51

键盘

扫描

 

8255A

 

AD

转换

模拟

交通灯

波形

发生器

 

七、软件设计

#include

#include

#defineDAC0832XBYTE[0XDFFF]

#defineCOM8255XBYTE[0X7FFF]

#definePA8255XBYTE[0X7FCF]

#definePB8255XBYTE[0X7FDF]

#definePC8255XBYTE[0X7FEF]

#defineIN0XBYTE[0XBFF8]//设置AD0809的通道0的地址

#defineucharunsignedchar//宏定义

#defineuintunsignedint//宏定义

uintaa,bai,shi,ge,bb;//定义变量

doublejieguo;

unsignedchara0[4];

uchari,j,m,n;//用于循环

sbitP32=P3^2;

sbitP31=P3^1;

sbitP30=P3^0;//ADC0809转换状态

sbitP33=P3^3;//键盘中断

sbitP34=P3^4;

sbitP35=P3^5;

sbitP17=P1^7;//产生AD转换时钟的引脚

unsignedcharcount=-1;//键盘值计数

unsignedcharsta;//读取键盘状态的变量

unsignedcharkey;//功能选择键

staticunsignedcharidataad[1];//AD转换结果存储

codeunsignedchartable[20]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xff,0x00,0xff,0x00};

codeunsignedchartable0[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0E};

unsignedchartablea[6]={0xfe,0xfd,0xfb,0xfF};//用于键盘扫描

unsignedchartableb[4]={0XE0,0XD0,0XB0,0X70};//用于键盘扫描

codeunsignedchartablec[]={0xfe,0xfd,0xfb,0xdf,0xef,0xf7,0xf6,0xf5,

0xf3,0xd7,0xe7,0xe6,0xe5,0xe3,0xc7,0xc6,

0xc5,0xc3,0xc2,0xc1,0xc0,0xc1,0xc2,0xc4,

0xe0,0xd0,0xc8,0xc9,0xca,0xcc,0xe8,0xd8,

0xd9,0xda,0xdc,0xf8,0xf9,0xfa,0xfc,0xfd,

0xfe,0xff,0xfe,0xfd,0xfb,0xdf,0xef,0xf7,

0xf7,0xdf,0xfb,0xfd,0xfe,0xfe,0xfd,0xfb,

0xdf,0xef,0xf7,0xf7,0xef,0xdf,0xfb,0xfd,

0xfe,0xfe,0xfd,0xfb,0xdf,0xef,0xf7,0xfe,

0xfd,0xfb,0xdf,0xef,0xf7,0xfe,0xfd,0xfb,

0xdf,0xef,0xf7,0xfe,0xf7,0xfd,0xef,0xfb,

0xdf,0xde,0xd7,0xdd,0xcf,0xdb,0xda,0xd3,

0xd9,0xcb,0xca,0xc3,0xc9,0xc8,0xc1,0xc0,

0xff,0xf6,0xed,0xdb,0xf6,0xed,0xdb,0xf6,

0xed,0xdb,0xf6,0xed,0xdb,0xf6,0xed,0xdb,

0xf3,0xed,0xde,0xf3,0xed,0xde,0xf3,0xed,

0xde,0xf3,0xed,0xde,0xf3,0xed,0xde,0xfe,

0xfd,0xfa,0xdd,0xea,0xd5,0xea,0xd5,0xea,

0xd5,0xea,0xd5,0xea,0xd5,0xea,0xd5,0xea,

0xd5,0xea,0xd5,0xea,0xd5,0xff,0xc0,0xff,

0xc0,0xff,0xc0,0xff,0xc0,0xff,0xff,0xff};//用于彩灯显示

voiddelay100us(void)//------------------------延时100us

{

unsignedchara,b;

for(b=2;b>0;b--)

for(a=47;a>0;a--);

}

voiddelay6ms(void)//----------------------延时6ms键盘去抖

{

unsignedchara,b,c;

for(c=1;c>0;c--)

for(b=222;b>0;b--)

for(a=12;a>0;a--);

}

voiddelay0(unsignedintz)//----------------------------动态显示LED延时子函数

{

unsignedinti,j;

for(i=0;i

for(j=0;j<110;j++);

}

voidad0809(unsignedcharidata*x)//-------------A/D采样函数

{

unsignedcharxdata*ad_adr;

//unsignedchari;

ad_adr=&IN0;

//for(i=0;i<8;i++)

//{

*ad_adr=0;//启动转换

delay100us();//延时100us等待EOC变低

while(P32==0);//查询等待转换结束

x[0]=*ad_adr;//储存结果

//ad_adr++;//读取下一个通道

//}

}

voidint1(void)//--------------------------------------键值扫描函数

{

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

for(j=0;j<3;j++)

{

P1=tablea[i];

sta=P1&0xf0;

if(sta==tableb[j])

{

delay6ms();

if(sta==tableb[j])

count=i*3+j;

}

}

}

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

/**/

/*第1个状态:

主干道亮绿灯30S、支干道亮红灯*/

/*第2个状态:

主干道绿灯闪3次转亮黄灯、支干道亮红灯3S*/

/*第3个状态:

主干道亮红灯、支干道亮绿灯25S*/

/*第4个状态:

主干道亮红灯、支干道绿灯闪3次转亮黄灯3S*/

/*返回到第1个状态*/

/**/

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

/*--------------显示子函数----------------------------*/

voiddisplay(uinttemp)

{

shi=temp%100/10;//显示十位

ge=temp%10;//显示个位

PC8255=0x01;

PA8255=table[shi];//显示十位

delay0(5);

PC8255=0x02;

PA8255=table[ge];//显示个位

delay0(5);

PC8255=0x04;

PA8255=table[shi];//显示十位

delay0(5);

PC8255=0x08;

PA8255=table[ge];//显示个位

delay0(5);

}

voidinit1()//---------------------第1个状态:

主干道亮绿灯30S、支干道亮红灯

{

uinttemp;

temp=20;//变量赋初值

aa=0;

TMOD=0x01;//定时器0工作于方式1

TH0=0x4C;

TL0=0x00;//定时器赋初值

ET0=1;//开定时中断

TR0=1;//开定时器0

while

(1)

{

PB8255=0XF3;//第二个状态:

主干道亮绿灯30S、支干道亮红灯

if(aa==20)//定时20*50MS=1S

{

aa=0;//定时完成一次后清0

temp--;//变量自增

if(temp==3)//定时

{

break;

}

}

display(temp);

}

}

voidinit2()//----------------------第2个状态:

主干道绿灯闪3次转亮黄灯、支干道亮红灯3S

{

uinttemp;

temp=3;//变量赋初值

aa=0;

TMOD=0x01;//定时器0工作于方式1

TH0=0x4C;

TL0=0x00;//定时器赋初值

ET0=1;//开定时中断

TR0=1;//开定时器0

while

(1)

{

PB8255=0XF5;

if(aa==20)//定时20*50MS=1S

{

aa=0;//定时完成一次后清0

temp--;//变量自增

if((temp+1)==0)//

{

break;

}

}

display(temp);

PB8255=0XF7;

display(temp);

}

}

voidinit3()//-----------------------第3个状态:

主干道亮红灯、支干道亮绿灯25S

{uinttemp;

temp=15;//变量赋初值

aa=0;

TMOD=0x01;//定时器0工作于方式1

TH0=0x4C;

TL0=0x00;//定时器赋初值

ET0=1;//开定时中断

TR0=1;//开定时器0

while

(1)

{

PB8255=0XDE;

if(aa==20)//定时20*50MS=1S

{

aa=0;//定时完成一次后清0

temp--;//变量自增

if(temp==3)//定时100S

{

break;

}

}

display(temp);

}

}

voidinit4()//-----------------------第4个状态:

主干道亮红灯、支干道绿灯闪3次转亮黄灯3S

{

uinttemp;

temp=3;//变量赋初值

aa=0;

TMOD=0x01;//定时器0工作于方式1

TH0=0x4C;

TL0=0x00;//定时器赋初值

ET0=1;//开定时中断

TR0=1;//开定时器0

while

(1)

{

PB8255=0XFE;

if(aa==20)//定时20*50MS=1S

{

aa=0;//定时完成一次后清0

temp--;//变量自增

if((temp+1)==0)//定时100S

{

break;

}

}

display(temp);

PB8255=0XEE;

display(temp);

}

}

voidinit5()//-----------------------第五个状态:

主干道和支干道亮红灯、

{

aa=0;//恢复软件定时初值

PB8255=0XDB;

PA8255=0XFF;

delay6ms();

}

voidxint0()interrupt2//-------------------外部中断1,这里用2是INT1的优先级为0

{

init5();

}

/*-------------定时中断子函数-----------------*/

voidxtimer0()interrupt1

{

TF0=0;

TH0=0x4C;

TL0=0x00;//定时器赋初值

aa++;

}

voidchange(void)//----------------------AD数字量转换成十进制码显示

{

jieguo=ad[0];

jieguo=(jieguo/255.0)*5;

a0[0]=(int)jieguo/10.0;

a0[1]=(int)(jieguo)%10;

a0[2]=(int)(jieguo*10)%10;

a0[3]=(int)(jieguo*100)%10;

PC8255=0X01;

PA8255=table[a0[0]];

delay0(5);

PC8255=0X02;

PA8255=table0[a0[1]];

delay0(5);

PC8255=0X04;

PA8255=table[a0[2]];

delay0(5);

PC8255=0X08;

PA8255=table[a0[3]];

delay0(5);

}

/*voidTimer1Interrupt(void)interrupt3//-----------------中断产生脉冲

{

TH1=0xFF;

TL1=0xFF;

P17=~P17;

}*/

voidsend(void)///////////////////////发送数据子程序

{

unsignedchari;

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

{

TB8=P;

SBUF=a0[i];

while(TI==0);

TI=0;

while(RI==0);

RI=0;

if(SBUF==0xff)

i--;

}

}

voidstart(void)

{

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

{

PC8255=0XFF;

PA8255=table[i];

delay0(200);

}

}

voidintial(void)//------------------------初始化函数

{

delay0(1000);

//TMOD=0x01;

//TH1=0xFF;

//TL1=0xFF;

//ET1=1;

SCON=0x90;

PCON=0X80;

COM8255=0X80;

PB8255=0XFF;

EA=1;//打开外部中断

key=-1;

}

/*---------------------主函数-------------------*/

voidmain(void)

{

intial();

start();

while

(1)

{

count=-1;

PB8255=0XFF;

int1();

PC8255=0XFF;

if(count!

=-1)

PA8255=table[count];

key=-1;

if(count==0)key=0;//0键按下闪烁彩灯

if(count==1)key=1;//AD转换功能

if(count==2)key=2;//交通灯功能

if(count==3)key=3;//DA转换

while(key==3)

{

while

(1)//DA转换

{for(i=0;i<255;i++)//输出锯齿波

{

DAC0832=i;

}

if(P32==0||P35==0)break;

}

while

(1)

{

DAC0832=0X00;

delay0(1000);

DAC0832=0XFF;

delay0(1000);

if(P32==0||P35==0)break;//输出方波

}

if(P35==0)break;

}

while(key==1)

{

PB8255=0XFF;

ad0809(ad);//启动AD转换

change();

if(P32==0)send();

if(P35==0)break;

}

while(key==2)//交通灯功能

{

EX1=1;

IT1=0;//INT0为沿触发方式

if(P35==0)break;

init1();//第1个状态

if(P35==0)break;

init2();//第2个状态

if(P35==0)break;

init3();//第3个状态

if(P35==0)break;

init4();//第4个状态

EX1=0;

ET0=0;//关闭定时中断

}

while(key==0)//0键按下闪烁彩灯,其它键按下显示键值

{

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

{PB8255=tablec[i];

delay0(150);

if(P35==0)break;

}

if(P35==0)break;

}}}

八、实验总结及心得

1、通过这次实验,让我对电路设计有了全新的认识,也对课堂上的知识有了更深的理解和记忆,

2、实验中,我学会了端口地址的概念,原理以及其使用的规则,尤其是端口地址在实际电路中的应用,显得尤为重要,没有端口地址,就不可能实现对外围器件的操作。

3、然就就是软件设计知识,,这个不能在很短的时间内学会,所以要多练习和多思考,慢慢的积累,养成设计计算机语言的习惯,使其具有可读性,且逻辑设计也要合理。

4、在设计程序前都要有大概想好程序设计的步骤和语言的结构,以便于在调试的时候方便,如果在开始编程的时候不注意这些,就会使得下次调试的时候更容易上手。

5、由于这次实验是软结合硬件来实现的,在调试的时候如果能掌握一定的方法就很荣翻译将调试好的成

6、在设计好硬件的时候,可以用万用表的二极管档来测试连线的连通性。

我说说几个自己出现的错误和改正的方法。

在设计交通灯时钟时,在按下紧急红灯之后,交通灯的计数器就停止,无法恢正常,原来是在紧急中断时,定时器还在计数(我采用的软件和硬件结合的定时方式),于是计数值过大,超过了判定计数减一时的范围。

就产生了死循环。

化,也有可能是没有足够的驱动电流,然后考虑怎样才能修改错误。

比如加上拉电阻来增加驱动能力。

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

当前位置:首页 > 高中教育 > 高中教育

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

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