单片机综合实验报告
题目: 星形流水灯
2023 年 07 月 10 日
《单片机综合实验》实验报告
第 1 页
一、题目描述和设计要求
1.1 题目描述
星形流水灯,这个题目我认为主要就是两个部分,第一就是画原理图,把 31
个 led 摆成星形,然后连接到 P0-P3 的 31 个管脚上。因为要用到定时器,老师
给的电路里没有连晶振,这个电路也要自己连一下。第二个部分就是软件,五个
以上的花样,有几个花样就编写几个函数,然后利用定时器中断来实现间隔 0.5s。
不用延时函数,因为定时器不会出现误差。
我们也额外加了一个外部中断 k3,按一次可以让变成下一个花样。因为 led
刚好占用了 31 个引脚,剩下一个引脚就可以给到 INT0 管脚。
1.2 技术指标
函数名
目的
技术指标
init()
定时器 1 初始化
TMOD = 0x10;
TH1 = 0x3C; TL1 = 0xBC;定时
50ms 中断 1
T1int( ) interrupt 3
中断函数
int_time++;if(int_time==10)
10*50ms,也就是 0.5s。
利用 count,flag 来区分开不同
花样的演示。
main()
主函数
while(1)空循环和初始化函数
show1—show6
6 个花样的函数
利 用 到 31 个 管 脚 为
P0,P2,P3,P1_0-P1_6
init1()
外部中断 0 初始化
IT0 = 1;IT1 = 1;EX0 = 1;
EX1 = 1;
int0() interrupt 0
外部中断函数
进行 flag 的++操作,能够进入
下一个花样
《单片机综合实验》实验报告
第 2 页
二、实现方案和可行性分析
2.1 实现思路和可行性分析
(1) 实现思路:
首先是电路部分,这里就简单叙述,因为 51 单片机有 P0-P3 共 32 个可用的
I/O 管脚,所以这里就用其中的 31 个来连接 led。又要利用定时器,这里外接一
个 12MHz 的晶振。
然后是软件实现部分。
最简单的一步就是设计好不同的花样,我想的是每一个花样写一个函数,这
样在调用的时候就很方便了。花样的控制是比较繁琐的,因为组成的形状的星形
的,五条引出的线上有 6 个 led,而每一组 I/O 管脚有八个,它们不可能放在一
条路线上,在控制流水灯形状的时候,要区分开哪一个 led 对应的是什么管脚。
每一个子动作的间隔为 0.5s,一个花样里切换子动作的次数越多,对应的子动
作的管脚代码就越多。
本次课设要求是全部使用定时器来实现。那么,如何区分开每一个花样,
然后每一个花样中的子动作也间隔 0.5s 是最为核心的问题。现在已经写好了 6
种花样的函数。那么,我设置一个变量为 flag,当其对应为 0-5 时,分别执行 6
个花样。再设置一个变量为 count,用来区分子动作。具体去实现,也就是把花
样函数放在定时器中断函数里,每执行完一个花样令 flag++,每个花样里的每
一个子动作用 if,else if 判断 count 的数值来区分开执行顺序(或者用 switch
case)。
上述操作,只需要让每一次进入中断执行的时间间隔为 0.5s 即可实现。
最后我们还利用多出来的一个引脚加上了外部中断,也就是 INT0,这里就
比较好理解,通过按键可以实现 flag 的加一,并且重新将 count 赋值为-1,这
样就可以进入下一个花样。
(2) 可行性分析:
首先就是定时器的初始化,这里采用 50ms 的初始化 TMOD = 0x10; TH1 =
0x3C; TL1 = 0xBC;计算如下:
《单片机综合实验》实验报告
第 3 页
然后就是花样的函数,在设计每个灯的控制代码中,我们考虑过用数组来控
制,但是由于星形形状的摆放,使得每一个 led 难以通过整体控制,所以我们就
采用了最简单的处理方式,每一个花样的 led 都单独去赋值,当然,除了第一种
花样控制比较繁琐,其余花样都是可以通过如 P1=0xfc 这样的十六进制数来控制
的。
下面列举一个花样函数例子:
void show1()//第一个花样
{
switch (count) {
case 0: P0_0 = 0; break;//
case 1: P0_1 = 0; break;
case 2: P0_2 = 0; break;
case 3: P0_3 = 0; break;
case 4: P3_0 = 0; break;
case 5: P3_1 = 0; break;
case 6: P1_0 = 0; break;
case 7: P3_3 = 0;P3_5 = 0;P3_7 = 0;P1_1 = 0; break;
case 8: P3_2 = 0;P3_4 = 0;P3_6 = 0;P1_2 = 0; break;
case 9: P0_7 = 0;P2_7 = 0;P2_3 = 0;P1_3 = 0; break;
《单片机综合实验》实验报告
第 4 页
case 10: P0_6 = 0;P2_6 = 0;P2_2 = 0;P1_4 = 0; break;
case 11: P0_5 = 0;P2_5 = 0;P2_1 = 0;P1_5 = 0; break;
case 12: P0_4 = 0;P2_4 = 0;P2_0 = 0;P1_6 = 0;flag=1;count=-1;
break;
default: break;
}
}
这个函数要实现的功能很简单,就是一条边上的灯逐渐亮起,走到中间,中间的
灯亮起,然后剩下四个边从中间开始向外面逐个亮起,直到全部亮起。
当 count==12 时,也就是最后四个灯亮起之后,让 flag 变为 1 下次进中断
可以执行第二个花样,count 变为-1,因为 count 是在中断函数最后自增,每次
中断执行完都要+1,只有让这里变为-1 才可以保证在下一个花样函数中 count
初始为 0。
这个函数采用的是 switch case 实现的,因为子动作较多,后面函数子动作
较少则采用 if else 结构来写。
这里再来举一个花样函数 5 的例子:
void show5()
{
if(count==0)
{
P1=P2=P3=P0=0xff;//首先全部灭
P1=0;//左边的一条边全部亮,包含中间的
}
else if(count==1)
{
P1=P2=P3=P0=0xff;//让上一次的边灭掉
P0=0xf0;P3=0xfc;P1_0=0;//让上一条边顺时针方向的下一条
边亮,同样也包含中间的,后面的同理,顺时针让五条边全部亮一遍。形成一个
类似于指针旋转的花样。