易礼智
( 湖南工程职业技术学院 信息工程系,湖南 长沙 410151 )
本流水灯控制系统由电阻、发光二极管、单片机最小系统(proteus 仿真时省略电源、晶振、复位等电路)和必要的软件。其具体硬件组成如图1 所示。
从硬件中可发现,从p1.0 输出低电平时D1 亮,p1.0输出高电平时D1 熄;同理,接在p1.1~p1.7 口的其他7 个LED 的点亮和熄灭的方法同D1。因此,将D1~D8 依次点亮、熄灭,8 个LED 将一亮一熄实现流水灯。
该代码包含了main()和msec()两个函数[1],main()为主程序,msec()为1s 延时子程序。feH 根据C51单片机硬件连接进行确定,表示给P1 口的p1.0 赋了一个低电平,其他的为高电平。赋值后调用子程序msec(),调用中将实参1000 传递给被调用函数msec的形参x。
该代码的主函数main()中,for 语句的表达式用来描述循环的次数即小灯的个数。在硬件电路中C51 单片机的引脚输出低电平时,灯亮;反之,灯熄。D1~D8 循环亮的过程通过a=0xfe 和p1=~(a<2.3.数组
这段代码定义了一个一维数组{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f},数组中的元素根据流水灯的工作过程来确定。语句 p1=a[i]表示将数组中元素的内容依次送给P1 口。
用二维数组描述代码:语句uint a[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}描述数组元素;在循环嵌套中采用语句p1=a[i][s]将数组中元素的内容依次送给P1 口。
在这个代码中通过指针直接赋值来实现流水灯。在主函数main()中,语句p=&a 表示把a 的地址送给p,经过赋值后指针变量p 就指向了变量a。语句p1=*p 表示把变量a 里面的内容送给p1 口。
用一维数组指针描述代码:用语句 uint a[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}描述依次送给P1 口的各个数据,在函数main()中,采用语句uint *p=a 表示指针变量p 指向数组a 的起始地址,语句p1=*(p+i)表示将数组a 中的数据依次送给P1。
用二维数组指针描述代码,uint a[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}描述依次送给P1 口的各个数据;在主函数main()中,语句uint (*p)[4]表示指针变量p 指向一个包含4 个元素的一维数组;语句p=a 表示指针变量p 指向二维数组的第0 行的首地址,也就是 a[0][0]的起始地址;语句p1=*(*(p+i)+s)描述将二维数组中 a[i][s]的内容传送给P1。
在这个代码中:传送数据的方式采用数组的形式(给 P1 赋值也可采用本文中的其他方式),通过使用C51 单片机的定时/计数器实现流水灯工作中的延时。在晶振为11.0592MHZ 时,C51 单片机的机器周期[2]为 1us。本段代码通过查询 TF0 是否为“1”对重复20 次计数5000us 是否完成进行判断。
在这段代码中,传送数据的方式采用数组[3]的形式(给 P1 赋值也可采用本文中的其他方式)。通过同时使用C51 单片机的定时/计数器与中断系统来实现流水灯工作中的延时。定时/计数器定时50000us后,提出中断请求;在中断服务函数timer0()中,语句if(++i==20)中的i 对中断的次数进行计数。
针对51 单片机实现流水灯的控制,上述编程方法从不同的角度提供了关键的代码;在实际应用中,需将代码完善为完整程序。在实际应用中,“定时+中断”方式可与“直接赋值”、“数据移位”、“数组”、“指针”、“定时计数器”五种方式中的某一种进行组合。通过对一个对象进行多种编程描述,能有效提高电子、编程爱好者的学习兴趣,提高动手能力和解决实际问题的能力。
[1] 谭浩强.C 程序设计[M].北京:清华大学出版社,1991.
[2] 胡汉才.单片机原理及接口[M].北京:清华大学出版社,2004.
[3] 马忠梅,籍顺心,张凯,马岩.单片机的 C 语言应用程序设计[M].北京:北京航空航天大学出版社,2007.