学 号: 311008001404
班 级: 自动化10-5班
姓 名: 万 璐 璐
指导老师: 杨 凌 霄
日 期: 20##-1-8
单片机核心板实验要求
一、 流水灯实验
1、实验目的:
1)简单I/O引脚的输出
2)掌握软件延时编程方法
3)简单按键输入捕获判断
2、完成功能要求
1)开机是点亮12发光二极管,闪烁三下
2)按照顺时针循环依次点亮发光二极管
3)通过按键将发光二极管的显示改为顺逆时针方式
二、 定时器或实时时钟实验
1、实验目的
1)数码管动态显示技术
2)定时器的应用
3)按键功能定义
2、完成功能要求
通过按键可以设定定时时间,启动定时器,定时时间到,让12个发光二极管闪烁,完成定时器功能。
三、 双机通信实验
1、实验目的
串行通信接口技术应用
2、完成功能要求
用两片核心板之间实现串行通信,将按键信息互发到对方数码管显示。
四、 交通灯实验
1、实验目的
1)按键、数码管、发光二极管综合应用编程技术
2)定时中断技术
3)按键中断技术
2、完成功能要求
1)对每个路口(主干道、次干道)的绿灯时间,及黄灯时间的设定。
2)紧急按键功能,当按下该键时,所有路口变成红灯,相当于交警指挥特殊车辆通过。再按该键,恢复正常显示。
实验一 流水灯实验
一、实验目的
1.简单I/O引脚的输出
2.掌握软件延时编程方法
3.简单按键输入捕获判断
二、实验实现的功能
1.单片机通电时点亮12个发光二极管,闪烁三下
2.短暂时间后,按照顺时针方式依次点亮12个发光二极管
3.通过按键1改变发光二极管的点亮次序,且每按一次改变都会循环方向
三、系统硬件设计
按键1
12个发光二极管
STC10F08XE
四、系统软件设计
#include "reg52.h"
#define uint unsigned int
#define uchar unsigned char
tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
tab1[]={0xfb,0xf7,0xef,0xdf};
sbit key1=P3^6;
sbit L1=P0^5;
void delay(uint i) //延时程序
{ uint j;
for(;i>0;i--)
{
for(j=300;j>0;j--);
}
}
void shun()
{
uint b,c;
for(b=0;b<8;b++)
{
P3|=0x3c;
P2=tab[b];
delay(500);
}
for(c=0;c<4;c++)
{
P2=0xff;
P3=tab1[c];
delay(500);
}
}
void fan()
{
uint d,e;
for(d=0;d<4;d++)
{
P2=0xff;
P3=tab1[3-d];
delay(500);
}
for(e=0;e<8;e++)
{
P3|=0x3c;
P2=tab[7-e];
delay(500);
}
}
void main()
{
uint a;
char k;
int n=0;
L1=0;
for(a=0;a<3;a++)
{
P2=0x00;
P3=0xc3;
delay(500);
P2=0xff;
P3|=0x3c;
}
while(1)
{
if(key1==0)
{
n++;k=n%2;
}
if(k=n%2)
{
fan();
}
else shun();
}
}
五、实验过程中遇到的问题及解决方法
实现功能一时,让LED闪烁三下,使用for循环,若通过对P2和P3赋值来实现LED的亮灭,则需要赋值多次,使程序较长。后来设定按键自加一通过判断奇偶性选择调用顺时转动程序还是逆时针转动程序,使程序模块化减少程序长度且实现功能。
对于功能三,此程序存在较大的修改空间。本程序目前只能在转完一周后检测到按键是否按下并正确的执行安排好的程序。如果流水灯可以随时转变流动方向就最好了。
实验二 定时器实验
一、实验目的
1、数码管的动态显示技术的应用
2、掌握定时器的应用
3、设置按键扫描,实现操作功能
二、实验实现的功能
1、四位数字的定时器
2、通过按键1选择定时/时钟,按键2进行分钟调时,按键3进行秒针调时。
3、定时不影响时钟运行。当到达定时时间时发光二极管闪烁。
三、系统硬件设计
发光二极管12个;四位数码管;3个按键;STC10F08XE;
四、系统软件设计
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77};
uchar ledyin[]={0xfe,0xfd,0xfb,0xf7};
uchar i,x,k,fen,miao;
uchar df,dm;
sbit h1=P3^6;
sbit h2=P3^7;
sbit k1=P0^5;
sbit k2=P0^6;
sbit k3=P0^7;
sfr P1M0=0x91;
sfr P1M1=0x92;
void delay(uint s)
{
uint m,n;
for(m=0;m<s;m++)
for(n=0;n<2000;n++);
}
void jishu()
{
if(++miao>59) //秒钟
{
miao=0;fen++;
}
if(fen==60) //分钟
{
fen=miao=0;
}
}
void jian123()
{
h1=0;h2=1;
if(k1==0)
{
delay(100);
k++;
}
if(k2==0)
{
delay(100);
df++;
if(df==60){df=0;};
}
if(k3==0)
{
delay(100);
dm++;
if(dm==60){dm=0;};
}
}
void intt1() interrupt 3
{
TL1=0x10;TH1=0xd8;
i++;
jian123();
if(i==100)
{
jishu();
i=1;
}
}
void dingshi()
{
if((dm==miao)&&(df==fen))
{ uint m;
for(m=0;m<3;m++)
{
P2=0x00;
P3=0x80;delay(20);
P2=0xff;
P3=0xbf;delay(20);
}
}
}
void shuxian(uchar cnt,uint shu) //二位参数变量控制显示
{
P1=tab[cnt%10];P0=ledyin[3];delay(1);
P1=tab[cnt/10];P0=ledyin[2];delay(1);
P1=tab[shu%10];P0=ledyin[1];delay(1);
P1=tab[shu/10];P0=ledyin[0];delay(1);
}
void main()
{
TMOD=0x10;TL1=0x10;TH1=0xd8; //设置定时器并启动
TR1=1;ET1=1;EA=1;
P1M0=0x00;
P1M1=0xff;
while(1)
{
switch(k%2)
{
case 0:shuxian(miao,fen);break;
case 1:shuxian(dm,df);break;
}
dingshi(); //如果定时到点,则十二个二极管闪烁
}
}
五、实验过程中遇到的问题及解决方法
问题一:如何使数码管正确显示设定的定时时间长度?
在实验过程中我发现,想要对按键输入数字进行直接的显示,这时应用起来比较繁琐。可以将数码管显示的七段码的16进制形式用数组集合起来,由于数组是从第零个元素开始,所以在对输入数字进行除法和取余运算后,每一位的数字的断码就是数组对应的元素。
问题二:按键不灵敏,偶尔无法出现计数不准确的情况
在调试的过程中,我发现自己的实验板无法正确读取按键按下次数,且只有按下速度快时才能读取。有时候按键后数码管没有正确显示,但过一会又可以正确显示按键次数。后来,决定调整按键扫描延时和数显延时,在按键的时候速度适当,二者都可解决。但在编写后面的实验时发现有更好的程序可以让执行更准确,稳定。
实验三 双机通信实验
一、实验目的
串行通信接口技术应用
二、实验实现的功能
1、在两片单片机课设核心板之间实现串行通信
2、将相应按键信息互发到另一核心板的数码管显示。当实验板A向实验板B发送按键信息时B数码管加一,A中流水灯闪烁提示操作成功。
三、系统硬件设计
1、两片相同的单片机核心板
2、三根杜邦线
四、系统软件设计
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar a,b,p;
void leddisplay(); // 数码管显示
void delayms(uint k); // 延时 n ms
void send(uchar dat); // 串口发送子程序
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0,0xff,0x76};
uchar ledyin[]={0xfe,0xfd,0xfb,0xf7};
sbit h1=P3^6;
sbit h2=P3^7;
sbit k1=P0^5;
sbit k2=P0^6;
sbit k3=P0^7;
sfr P1M0=0x91;
sfr P1M1=0x92;
void smg(uchar cnt)
{
P1=tab[cnt%10];P0=ledyin[3];delayms(3);
P1=tab[(cnt%100)/10];P0=ledyin[2];delayms(3);
P1=tab[(cnt/100)%10];P0=ledyin[1];delayms(3);
P1=tab[cnt/1000];P0=ledyin[0];delayms(3);
}
void leddisplay() // LED显示子程序
{
for(a=0;a<70;a++)
{
smg(p);
delayms(1);
P1=0x00;
}
} //共阴极代码 0-F, 全灭,全亮,H
void main()
{
uchar dat=0;
P1M0=0x00;
P1M1=0xff;
delayms(200);
TMOD=0x20; // 定时器1模式2,8位自动重装
TL1=0xe6;
TH1=0xe6; // 波特率1200
TR1=1;
SCON=0x50; // 串口方式1,接收允许,8位数据,无校验,1位起始位,1位结束位
EA=1; // 开串口中断
ES=1; // 开总中断
while(1)
{ h1=0;h2=1;
for(b=0;b<2;b++)
{ leddisplay(); } // 循环显示60次,延时480ms
send(dat); // 串口发送数据(0-255)
if(k1==0)
{
delayms(100);
P2=0x00;
P3=0xc3;
delayms(200);
P2=0xff;
P3|=0x3c;
dat++;
};
if(dat==10000){ dat=0; };
}
}
void send(uchar dat) // 串口发送子程序
{
SBUF=dat; // 发送数据
while(TI==0); // 等待发送完成
TI=0;
}
void intt1(void) interrupt 4 // 串口接收中断服务程序
{
uchar dat;
if(RI==1) // 判断是否是接收中断
{
RI=0;
dat=SBUF; // 接收数据
p=dat;
// 接收数据转换成16进制显示
}
}
void delayms(uint m)
{
uint i,j;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
{;}
}
五、实验过程中遇到的问题及解决方法
问题一:对于SUBF理解不到位导致程序错误。
经过仔细理解课本知识,认识到:当接收数据时,是从SBUF中取出内容,应是A=SBUF,且应在接收一帧数据完成RI=1后,取走数据。还要利用软件实现对RI的清零才能顺利接收下一帧数据;在发送数据时,应是SBUF=A,当发送完成后TI=1,利用软件清0,才能实现下一帧数据的顺利发送。在对数据和TI、RI进行处理时,应注意先后顺序。
问题二:在开始编写程序实现接收功能时,无法接收到数据。
因为程序较长,关系较多,变量设置时有时候会不小心付错或未释放数值。在写程序时最好先画出程序的流程图,以免漏掉某些关系造成程序无法正常运行。
实验四 交通灯实验
一、实验目的
1.按键、数码管、发光二极管综合应用编程
2.定时器中断技术的应用
3.按键中断技术的应用
二、实验实现的功能
1、区分主干道和次干道,对南北方向和东西方向设定不同时间。
2、最后5S,通行干道上绿灯闪烁频率加快,禁行干道上黄灯闪烁,引起司机行人注意。
3、遇到紧急情况,按下按键3,全部亮红灯禁止通行。再按下按键,交通灯恢复正常。在此过程中,不影响交通灯的正常运行时间。
三、系统硬件设计
12个发光二极管;四位数码管;1个按键;
四、系统软件设计
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit H1=P3^6;
sbit L3=P0^7;
sbit D9=P3^2;
sbit D10=P3^3;
sbit D11=P3^4;
sbit D12=P3^5;
uchar leddata0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 显示0-9数字
uchar leddata1[]={0xfe,0xfd,0xfb,0xf7}; // 位选W1-W4口,选择P0口
uchar leddata2[]={0x6d,0x31,0x3f,0x73}; //紧急情况时显示stop的字形
bit F=1;
int x=20;
uint b=20;
sfr P1M0=0x91;
sfr P1M1=0X92; //声明P1口的软件配置工作类型寄存器地址 ,查表获得
void stop(); //
void delay(uint m)
{
uint i,j;
for(i=0;i<m;i++)
for(j=0;j<m;j++)
{;}
}
void display(int x)
{
int y[4];
uchar i=0;
y[0]=x/1000;
y[1]=(x-y[0]*1000)/100;
y[2]=(x-y[0]*1000-y[1]*100)/10;
y[3]=x-y[0]*1000-y[1]*100-y[2]*10;
for(i=0;i<4;i++)
{
P0=leddata1[i];
P1=leddata0[y[i]];
delay(20);
}
}
void intt0() interrupt 1
{
TH0=(65535-50000)/256; //定时器0选择方式一,计数从0-50000溢出50000*12/11059200=54MS=50MS
TL0=(65535-50000)%256;
b--;
if(b==0)
{
x--;
if(x<0)//if(x%100<0)
{
F=~F;
if(F) x+=20;
else x+=15; //倒计时设值
}
display(x);
delay(50);
b=20;
}
}
void stop()
{
uchar i,J=1;
TR0=0;
P2=0xdb;
D10=D11=1;
D9=D12=0; //全亮红灯
while(J)
{
if(L3==0)
{
delay(150);
{
while(L3==0);
J=0;
D10=1;
TR0=1;
}
}
for(i=0;i<4;i++)
{
P0=leddata1[i];
P1=leddata2[i];
delay(20);
} //紧急亮灯不影响正常交通灯的运行
}
}
main()
{
uint i;
P1M0=0x00;
P1M1=0xff;
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
ET0=1;
EA=1;
TR0=1;
H1=0;
while(1)
{
if(L3==0)
{
delay(150);
if(L3==0)
{
while(L3==0); //当按键未松开时程序不往下执行
stop();
} //检查是否有紧急情况即按键是否按下,重复判断L3是否为0,
}
if(F) //F等于1
{
if(x<6)
{
for(i=0;i<10;i++)
{
delay(50);
display(x);
}
for (i=0;i<2;i++)
{ P2=0xEF;
D11=0;
delay(20);
}
P2=0xdf;
D9=D11=1;
for(i=0;i<10;i++)
{
delay(50);
display(x);
}
}
P2=0x9e;
D10=D9=1;
D12=0;
// D1,D6,D7亮 D12亮,东西通车20s
display(x);
}
else
{
if(x<6)
{
for(i=0;i<10;i++)
{
delay(50);
display(x);
}
for (i=0;i<2;i++)
{ P2=0x7d; //亮D2D8黄灯
delay(20);
}
P2=0xfb;
D9=0;
D10=1;
for(i=0;i<10;i++)
{
delay(50);
display(x);
}
}
P2=0xf3;
D10=D9=0;
D12=1;
display(x); //南北通车15S
}
}
}
五、实验过程中遇到的问题及解决方法
问题一:在开始调试程序时,路口灯控制亮灭紊乱,出现端口设置错误。
绘制交通灯示意图,并把各端口控制的二极管对应列表,注意2、3端口的衔接,形成一个十字路口,给每种灯在每个路口的亮灭情况做0、1标识,就能清楚的看到每个路口的状况了。
问题二:如何提醒行人交通状况,为安全出行提供一些保障。
在倒计时剩下5秒时,调整延时,使绿色和黄色发光二极管闪烁,提醒四面的司机行人注意安全。