历史上的今天
今天是:2024年11月08日(星期五)
2019年11月08日 | AT89S52单片机16LED摇摇棒设计
2019-11-08 来源:51hei
一、作品说明 摇摇棒是如今流行的一种玩具,在各种聚会、节日中均见得到它的身影。本设计也追随着摇摇棒的原理,利用人眼的视觉暂留特性,通过AT89S52单片机对16只高亮度LED发光二极管进行控制, 配合手的左右摇晃就可呈现一幅完整的画面。 该摇摇棒具有如下功能:1) 显示 “欢迎使用神奇魔幻摇摇棒!”;2) 显示 “o(∩_∩)o”微笑图案;3) 显示 心形图案;4) 显示 “LOVE”;5) 可以通过开关实现转换,轮流显示并循环。
二、系统总体设计
1、总体方案比较与论证所谓的“摇摇棒”,其实就是一个循环的LED显示,利用人的视觉滞留产生静态显示的现象。要实现这个目标,就要求延时部分做的比较小,所以采用石英晶体振荡器。而目前能够实现这种功能的器件有很多种,不同的类型的器件也能够很好的完成。本作品本着方便、价格低廉的原则,采用单片机控制,由水银开关的闭合对单片机产生外部中断,从而对中断进行采集。到达一定数量便进行图象的转换。整个系统由单片机控制模块,开关及电源模块和输出显示模块三个部分构成。2、主要部件原理 (1)单片机控制模块 用单片机想要控制LED显示只需要定时输出就可以,但每个人摇动的速度不一样,如何准确的并稳定的变换图案呢?这就需要用到外部中断。将水银开关的两个引脚一端接VCC,一端接GND,这样的话,当摇棒向一边运动时LED按照程序编辑好的规律显示,而向另一边运动时LED全灭,此时一个周期就会产生一个下跳沿的信号,信号传递给单片机的nINT0产生中断,对中断的数量计数,当计到10时便转换显示的图案,当依次显示完后便回到初始状态进行循环。由于人的视觉滞留时间长达0.1s,所以在每显示完一列LED后加入一段合适的延时,如5ms,每个字之间加入延时如15ms,这样,我们就能看到静态的稳定的字,并且每个字之间是有空隙的。为了让字能够在空间的中部显示,在启动中断显示后延时一段合适的时间,使棒在半圆轨迹的大约1/4处开始显示,这样看到的字方向上才比较正。 (2水银开关 水银开关,又称倾侧开关,是电路开关的一种,以一接著电极的小巧容器储存著一小滴水银,容器中多数注入惰性气体或真空。 仔细观察水银开关,实际上他是一个封闭的玻璃管,里面有两个分开着的导线和一段水银球,当玻璃管的平衡位置变化时,水银球会来回移动,当水银球移动到两根导线时,因水银是金属-导体,故电路变为通路,此时接收器处于工作状态;反之,水银球远离两根导线时为断路,此时接收器处于非工作状态。本设计采用震动开关代替水银开关,试验测试发现,水银开关多次高频率的接通断开后触点会氧化,容易接触不良,因此改用下面的震动开关。
3、系统设计 本系统包括单片机控制模块,开关及电源模块和输出显示模块三个部分。单片机控制模块由Keil C进行编写,实现起来简单,主要有三部分,主程序、中断服务部分还有字符点阵。开关及电源模块采用5V变压器并配合水银开关使用。输出显示模块采用16个LED灯,在版上一字排开。
三、硬件设计硬件连接上用水银开关产生的电平转换引发中断,传递给单片机,再由单片机调用点阵文件输出到LED上。AT89S52单片机作为控制器,在它的P0、P2口接有16只以共阳的方式连接的高亮度LED,由单片机输出低电平点亮。P0口处接上拉电阻RA1。串在LED公共端的二极管D1会产生一定的压降,用来保护LED。K1是画面切换开关,用于切换显示不同内容;S1为水银开关。系统电源VCC为5V,实际使用时用3节干电池串联4.5V即可。16只LED发光管作为画面每一列的显示,左右摇晃起到了扫描的作用,人眼的视觉暂留现象使得看到的是一幅完整的画面。水银开关的作用:棒在摇动时,只能在朝某一方向摇动时显示,否则会出现镜像字或镜像画面,所以通过接一只水银开关来控制,使摇摇棒从左向右摇动时将内容显示出来。
四、软件设计软件部分包括主函数程序、中断服务程序、延时子程序以及四个显示子程序。软件设计流程如下: 五、系统调试与分析主要测试单片机的工作情况,能否正常用LED显示出各图案,并且记录各图案持续的时间和稳定显示度以及一个循环周期所用的时间。并且检查LED的发光亮度,使之可以明显的分辩出来。图 案稳定程序欢迎使用神奇魔幻摇摇棒较稳定心形较稳定笑脸较稳定LOVE较稳定经过测试,当摆动的幅度和速度适当时,各个画面均可以明显的显示出来。整体来说,本方案设计比较成功。
Altium Designer画的原理图和PCB图如下:

单片机源程序如下:
#include #define uchar unsigned char #define uint unsigned int //宏定义 sbit KEY=P1^0; uchar KY; //KY作用在后面说明 uchar disp; //显示汉字指针 uchar pic=0,num=0; //pic为按键次数;num为中断次数 uchar code love[] = { 0x80,0x40,0x40,0x40,0x30,0x42,0x1E,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0xFF,0x7F, 0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x40,0x00,0x40,0x00,0x00,/*"生",0*/ /* (16 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x82,0x40,0x82,0x40,0x82,0x40,0x82,0x40, 0x82,0x40,0x82,0x40,0x82,0x40,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"日",1*/ /* (16 X 16 , 宋体 ) */ 0x00,0x01,0xE0,0x00,0x00,0x00,0xFF,0xFF,0x10,0x00,0x20,0x81,0x08,0x41,0x08,0x31, 0x08,0x0D,0xFF,0x03,0x08,0x0D,0x08,0x31,0xF8,0x41,0x00,0x81,0x00,0x81,0x00,0x00,/*"快",2*/ /* (16 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x20,0xE0,0x10,0x9C,0x08,0x84,0x06,0x84,0x40,0x84,0x80,0xF4,0x7F, 0x82,0x00,0x82,0x00,0x83,0x02,0x82,0x04,0x80,0x08,0x80,0x30,0x00,0x00,0x00,0x00,/*"乐",3*/ /* (16 X 16 , 宋体 ) */ }; uchar code loveyou[] = { 0x00,0x08,0x08,0x08,0x88,0x08,0x88,0x08,0x89,0x08,0x8E,0x08,0x88,0x08,0xF8,0xFF, 0x88,0x08,0x8C,0x08,0x8B,0x08,0x88,0x08,0x88,0x08,0x08,0x08,0x00,0x08,0x00,0x00,/*"羊",0*/ /* (16 X 16 , 宋体 ) */ 0x00,0x04,0x20,0x04,0x18,0x04,0xC7,0x07,0x44,0x04,0x44,0x04,0x44,0x04,0x44,0x04, 0xFC,0xFF,0x44,0x04,0x44,0x04,0x44,0x04,0x44,0x04,0x04,0x04,0x00,0x04,0x00,0x00,/*"年",1*/ /* (16 X 16 , 宋体 ) */ 0x20,0x80,0x20,0x80,0x20,0x40,0x20,0x20,0x20,0x10,0x20,0x0C,0x20,0x03,0xFF,0x00, 0x20,0x03,0x20,0x0C,0x20,0x10,0x20,0x20,0x20,0x40,0x20,0x80,0x20,0x80,0x00,0x00,/*"大",2*/ /* (16 X 16 , 宋体 ) */ 0x08,0x00,0x08,0x00,0x88,0x00,0x88,0xFC,0x88,0x44,0x88,0x44,0x88,0x44,0xFF,0x44, 0x88,0x44,0x88,0x44,0x88,0x44,0x88,0xFC,0x88,0x00,0x08,0x00,0x08,0x00,0x00,0x00,/*"吉",3*/ /* (16 X 16 , 宋体 ) */ }; uchar code hehe[] = { 0x40,0x80,0x48,0x7E,0x48,0x10,0xFF,0x3F,0x48,0x44,0x48,0x44,0x00,0x40,0xF8,0x4F, 0x08,0x44,0x08,0x50,0xFF,0x49,0x08,0x46,0x89,0x49,0x6A,0x5C,0x00,0x40,0x00,0x00,/*"越",0*/ /* (16 X 16 , 宋体 ) */ 0x00,0x21,0x08,0x21,0x08,0x11,0x28,0x11,0xC8,0x09,0x08,0x05,0x08,0x03,0xFF,0xFF, 0x08,0x03,0x08,0x05,0x88,0x09,0x68,0x11,0x08,0x11,0x08,0x21,0x00,0x21,0x00,0x00,/*"来",1*/ /* (16 X 16 , 宋体 ) */ 0x40,0x80,0x48,0x7E,0x48,0x10,0xFF,0x3F,0x48,0x44,0x48,0x44,0x00,0x40,0xF8,0x4F, 0x08,0x44,0x08,0x50,0xFF,0x49,0x08,0x46,0x89,0x49,0x6A,0x5C,0x00,0x40,0x00,0x00,/*"越",2*/ /* (16 X 16 , 宋体 ) */ 0x44,0x00,0x54,0xFF,0x54,0x15,0x7F,0x55,0x54,0x95,0x54,0x7F,0x44,0x00,0x00,0x80, 0xFE,0x63,0x02,0x1C,0xF2,0x03,0x02,0x7C,0x02,0x80,0xFE,0x83,0x00,0xE0,0x00,0x00,/*"靓",3*/ /* (16 X 16 , 宋体 ) */ }; unsigned char code hanzi[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/ /* (8 X 16 , 宋体 ) */ 0x08,0x02,0x08,0x01,0x89,0x00,0xEE,0xFF,0x98,0x80,0x00,0x43,0x7E,0x20,0x42,0x18, 0xC2,0x07,0x42,0x00,0x42,0x00,0xC2,0x3F,0x42,0x40,0x7E,0x40,0x00,0x78,0x00,0x00,/*"祝",1*/ /* (16 X 16 , 宋体 ) */ 0x00,0x08,0x00,0x04,0x7F,0x02,0x55,0xFF,0xD5,0x55,0x55,0x55,0x7F,0x55,0x00,0x55, 0xFF,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x55,0x00,0x41,0x00,0x00,0x00,0x00,/*"瞿",2*/ /* (16 X 16 , 宋体 ) */ 0x82,0x00,0x62,0x00,0x2A,0xF8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xA8,0xFA,0xFB, 0x2A,0xA8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xF8,0xA2,0x00,0x62,0x00,0x00,0x00,/*"蕾",3*/ /* (16 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/ /* (8 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/ /* (8 X 16 , 宋体 ) */ 0x08,0x02,0x08,0x01,0x89,0x00,0xEE,0xFF,0x98,0x80,0x00,0x43,0x7E,0x20,0x42,0x18, 0xC2,0x07,0x42,0x00,0x42,0x00,0xC2,0x3F,0x42,0x40,0x7E,0x40,0x00,0x78,0x00,0x00,/*"祝",1*/ /* (16 X 16 , 宋体 ) */ 0x00,0x08,0x00,0x04,0x7F,0x02,0x55,0xFF,0xD5,0x55,0x55,0x55,0x7F,0x55,0x00,0x55, 0xFF,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x55,0x00,0x41,0x00,0x00,0x00,0x00,/*"瞿",2*/ /* (16 X 16 , 宋体 ) */ 0x82,0x00,0x62,0x00,0x2A,0xF8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xA8,0xFA,0xFB, 0x2A,0xA8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xF8,0xA2,0x00,0x62,0x00,0x00,0x00,/*"蕾",3*/ /* (16 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/ /* (8 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/ /* (8 X 16 , 宋体 ) */ 0x08,0x02,0x08,0x01,0x89,0x00,0xEE,0xFF,0x98,0x80,0x00,0x43,0x7E,0x20,0x42,0x18, 0xC2,0x07,0x42,0x00,0x42,0x00,0xC2,0x3F,0x42,0x40,0x7E,0x40,0x00,0x78,0x00,0x00,/*"祝",1*/ /* (16 X 16 , 宋体 ) */ 0x00,0x08,0x00,0x04,0x7F,0x02,0x55,0xFF,0xD5,0x55,0x55,0x55,0x7F,0x55,0x00,0x55, 0xFF,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x55,0x00,0x41,0x00,0x00,0x00,0x00,/*"瞿",2*/ /* (16 X 16 , 宋体 ) */ 0x82,0x00,0x62,0x00,0x2A,0xF8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xA8,0xFA,0xFB, 0x2A,0xA8,0xAA,0xAA,0xAF,0xAA,0xAA,0xAA,0x2A,0xF8,0xA2,0x00,0x62,0x00,0x00,0x00,/*"蕾",3*/ /* (16 X 16 , 宋体 ) */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",4*/ /* (8 X 16 , 宋体 ) */ }; /*****函数声明*****/ void display1_ltor(void); void display2_ltor(void); void display2_rtol(void); void display3(void); void display4(void); /*****n(us)延时子程序*****/ void DelayUs(uint N) { uint x; for(x=0; x<=N;x++); } /*****中断服务程序*****/ void intersvr0(void) interrupt 0 { ; KY=~KY; //每个摇动来回水银开关会在摆幅两端分别产生下降沿中断,只提取其中一次(从左向右摇才显示) if(KY==0) { num++; //计算中断次数 switch(pic) //选择画面 { case 0:{display1_ltor();}break; case 1:{display2_ltor();}break; case 2:{display3();}break; case 3:{display4();}break; default:{display1_ltor();} } } } /*****显示子程序1(汉字)*****/ void display1_ltor(void) { uchar i; if(num>10){disp++;num=0;} //12个汉字分为3次显示完(每次显示4个),每中断10次切换 if(disp>2)disp=0; DelayUs(5200); //此处延时时间依各硬件差别而各不相同,试着调整使得显示内容居中即可 for(i=0;i<64;i++) { P0=~hanzi[disp*128+i*2]; P2=~hanzi[disp*128+i*2+1]; DelayUs(100); } } /*****显示子程序2(LOVE)*****/ void display2_ltor(void) { uchar i; DelayUs(4000); for(i=0;i<64;i++) { P0=~love[i*2]; P2=~love[i*2+1]; DelayUs(140); } } /*****显示子程序3(心形图案)*****/ void display3(void) { uchar i; DelayUs(4000); for(i=0;i<64;i++) { P0=~loveyou[i*2]; P2=~loveyou[i*2+1]; DelayUs(120); } } /*****显示子程序4(呵呵o(∩_∩)o图案)*****/ void display4(void) { uchar i; DelayUs(4000); for(i=0;i<64;i++) { P0=~hehe[i*2]; P2=~hehe[i*2+1]; ……………………
史海拾趣
|
起因:最近在学习proteus,在最开始编写仿真实例的源程序文件时,为了省事,就没有在主程序中加入while(1)这个无限循环(或者成为死循环)。但是在进行仿真延时的时候,无意间发现程序走到最后并不会停下来,而是会去干一些别的没有让它做的事情。 ...… 查看全部问答> |
|
今天在看一个datasheet of DCDC BUCK过程中,看到反馈端到Vout有一个Cfwd,不知道是做什么用的?请教各位 是不常么?… 查看全部问答> |
|
我在一个对话框上加上一个Date Time Picker后怎么对话框就不能初始化了,用DialogBox之后每一点反应,去掉这个控件之后就可以了,请大侠们帮我分析下。小弟在此先谢了!!… 查看全部问答> |
|
其中环境要求是nasm 0.99 assemble,我在网上没找到这个版本的程序. 如果用高点的版本的话就出现namke fatal error U1045, no error; 如果用nasm 0.98编译就出现fatal error u1077:\'nasm.exe\';return code \'0x1\'. 有谁知道吗? 也可以有相关 ...… 查看全部问答> |
|
文件1: #include sbit PWON=P1^2; typedef unsigned char Byte;// typedef unsigned int ...… 查看全部问答> |
|
我的是IAR MSP430 最新板,并成功破解,破解之后,发现我的debug菜单总是灰的,无论你怎么选择,怎么编译就是灰色,请路过大侠,高手们支招我怎么才能让C-Spy好用。… 查看全部问答> |
|
电子工程师设计必读书籍--这些书籍你看过几本? https://download.eeworld.com.cn/detail/tiankai001/283416… 查看全部问答> |
|
之前也介绍有关的智能学生宿舍的整体框架,这里把总体更加形象的描述出来。 这里介绍下因特网访问控制的方法,就是通过网络编程实现的,在一个具有公网IP地址的编写一个网络 ...… 查看全部问答> |




