摇摇棒制作全过程

来源:互联网 发布:php开源oa系统 知乎 编辑:程序博客网 时间:2024/04/28 21:26

一:基本原理与硬件电路设计:

 

16 只 LED 发光管作为画面每一列的显示,左右摇晃起到了扫描的作用,人眼的视觉暂留现象使得看到的是一幅完整的画面。与 LED 点阵的显示有几分相仿。

 

1.    系统电源 VCC 为 5V,下载程序和调试时一定要保证 5V 电压,实际使用时用 3 节干电池 串联4.5V 即可。

 

2.    STC89C52RC 单片机作为控制器,在它的P0、P2 口接有 16 只以共阳的方式连接的高亮 度LED,由单片机输出低电平点亮。

 

3.     P0 的上拉电阻排不能少,最好10K。上拉电阻可以提高单片机驱动能力。

 

4.    经实测 LED点亮时两端电压为 3V 左右,在 LED 的安全承受范围内。画面切换开关,用 于切换显示不同内容;

 

水银开关的作用:棒在摇动时,只能在朝某一方向摇动时显示,否则会出现镜像字或镜像画面, 所以通过接一只水银开关来控制,使摇摇棒从左向右摇动时将内容显示出来。

 

由于P0口内部无上拉电阻,所以P0口在用作输入输出时必须要接上拉电阻,一般为10K其他口可以不接上拉电阻

protel电路图:

STC89C52RC 实物引脚图:

注意:上电复位电路中的电解电容是 10uF,电阻为 10K,晶振电路中两个瓷片电容最好是:

 

22、30、33、47pF,晶振一般是 11.0592MHz

二:硬件制作:

 

使用的是直径 5mm 的红色高亮 LED,感觉太大了些,远看效果很好但近看时字不够连贯。建议 使用直径为 3mm 的LED颜色可根据个人喜好选择。

水银开关里的水银珠很活跃,导致在接通时容易产生抖动,所以将水银开关斜向上放置(尖尖 朝斜上方45°角),靠水银珠自身重力的作用减少抖动:

IC 座里面隐藏元件,既美观又能保护元件:


关于电源接法:电源用 3 节干电池串联成 4.5V,正极作为 VCC负极作为GND

 

 

 

三:关于开关按钮的接法:

轻触开关/微动开关:

按下去  连通  松开  又断开

相对的两个脚是连在一起的,即 1 2 连一起     3 4 连  一起,

连线时,只需将一端连到 1/2,另一端连到 3/4 即可

 

 

 

自锁开关:

可以中间对应的两个脚    接一端  , 左侧/右侧对应的两个脚  接另一端!

四:程序:

/**********************************************************程序名称:LED摇摇棒显示64*16像素简要说明:外部中断方式INT0显示;取模方式:纵向取模、字节倒序(取点方式:纵向8点下高位,字节排列:上到下左到右)**********************************************************/#include <reg52.h>#define uchar unsigned char#define uint unsigned int    //宏定义sbit KEY=P3^3;  //定义画面切换按键uchar KY;       //防止重影的控制变量     uchar pic=0;     //pic为按切换键次数uchar code love[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x04,0x10,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x04,0x10,0xF8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x10,0x00,0x08,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x3F,0x82,0x20,0x82,0x20,0x82,0x20,0x82,0x20,0x82,0x20,0x82,0x20,0x82,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*LOVE*/};uchar code loveyou[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0xFC,0x00,0xFE,0x01,0xFE,0x03,0xFE,0x07,0xFE,0x0F,0xFE,0x1F,0xFC,0x3F,0xF8,0x7F,0xFC,0x3F,0xFE,0x1F,0xFE,0x0F,0xFE,0x07,0xFE,0x03,0xFE,0x01,0xFC,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*心形图案*/};uchar code hanzi[] = {/*生   CC9FA */0x80,0x40,0xC0,0x40,0x70,0x42,0x3E,0x42,0x1E,0x42,0x10,0x42,0x10,0x42,0xFF,0x7F,0xFF,0x7F,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x40,0x00,0x40,/*日   CC8D5 */0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFE,0xFF,0x82,0x40,0x82,0x40,0x82,0x40,0x82,0x40,0x82,0x40,0x82,0x40,0xFE,0xFF,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,/*快   CBFEC */0x00,0x01,0xE0,0x01,0x00,0x00,0xFF,0xFF,0x10,0x00,0x30,0x81,0x28,0xC1,0x08,0x71,0x08,0x3D,0xFF,0x0F,0xFF,0x0F,0x08,0x3D,0xF8,0x71,0xF8,0xC1,0x00,0x81,0x00,0x81,/*乐   CC0D6 */0x00,0x00,0x00,0x20,0xE0,0x30,0xFC,0x18,0x9C,0x0E,0x84,0x46,0x84,0x80,0xF4,0xFF,0xF6,0x7F,0x82,0x00,0x83,0x02,0x83,0x06,0x82,0x0C,0x80,0x38,0x80,0x30,0x00,0x00};/*函数声明*/void display1(void);void display2(void);void display3(void);void display4(void);/*延时子程*/void DelayUs(uint N){ uint x; for(x=0; x<=N;x++);}/*中断服务程序*/void intersvr0(void) interrupt 0 using 1{KY=~KY;      //每个摇动来回水银开关会在摆幅两端分别产生下降沿中断,只提取其中一次(从左向右摇才显示) //当从右向左摇时,产生中断,KY取反变为1,此时不显示,不运行下面的语句if(KY==0){   switch(pic)      //选择画面   {      case 0:{display1();}break;      case 1:{display2();}break;      case 2:{display3();}break;      default:{display1();}//其他情况   }}}/*显示子程序1(汉字)*/void display1(void){ uchar i,n; DelayUs(4000);     //此处延时时间依各硬件差别而各不相同,试着调整使得显示内容居中即可 for(n=0;n<4;n++)   //每次显示一个字 留点间隔 再显示第二个, 总共显示四个字 { for(i=0;i<16;i++) {     P0=~hanzi[n*32+i*2];//LED灯是置0时亮,故这里要取反,下同     P2=~hanzi[n*32+i*2+1];     DelayUs(70); } }}/*显示子程序2(LOVE)*/void display2(void){ uchar i; DelayUs(4000); for(i=0;i<64;i++) {     P0=~love[i*2];     P2=~love[i*2+1];     DelayUs(70); }}/*显示子程序3(心形图案)*/void display3(void){ uchar i; DelayUs(4000); for(i=0;i<64;i++) {     P0=~loveyou[i*2];     P2=~loveyou[i*2+1];     DelayUs(70); }}/*主函数*/void main(void){IT0=1;EX0=1; EA=1;      //开中断,下降沿中断KY=0;while(1)     //主程序中只检测按键{if(KEY==0)     //画面切换键按下{DelayUs(10000);     //按键去抖if(KEY==0)pic++;if(pic>2)pic=0;}}}