# 创新设计16个LED灯的摇摇棒,可显示英文、图形及汉字
# 仅需5种元器件(单片机、LED、导线、电池和塑料壳),让DIY简单、快速
# 往返双程扫描,慢速摇动也可清晰显示
# 敲击字幕切换功能,无需按键操作
# 在软件上有很大的升级空间(包括双色显示、LED测光等)
-----------------------------------------------------------------------
[注意事项]
-----------------------------------------------------------------------
# HEX文件烧写时需选择“内部RC时钟”
# 本制作采用STC12C5A60S2单片机,不可以用其他型号单片机替代
# 惯性开关在制作时注意静止时开关柄到左右触点间的距离应尽量相等
# 本制作无开关,不用时需取下电池或在电池间塞入绝缘纸片
单片机采用STC12C5A60S2(1pcs)
- 0805型贴片式LED灯(16pcs)
- CR2032钮扣电池(2pcs)
- 具有一定弹性的导线和废弃的元器件引脚
- 用来包装DIP40脚单片机的塑料壳(1pcs)
- 确保单片机可以放入并有较大余地
- 用钳子将P0、P2接口所在一侧的引脚全部向外弯折
- 目的是保证将单片机放入塑料壳时不会左右乱窜
- 弯折时尽量不断放入塑料壳中比对
- 擦拭弯折后的引脚表面 确保无污物可以顺利上锡
- 用摄子取出贴片LED灯并焊接在单片机引脚上
- 从P2.0引脚开始焊接 左边焊LED负极(P2.0负极、P2.1正极)
- 依次焊接16个LED灯到P0.2引脚为止
- 将一支废弃元器件引脚对折并焊接在弹性导线上
- 弹性导线的另一端焊接在单片机的第20脚上(GND) 注意掌握导线长度
- 将P1.3引脚弯折至芯片底部 再用废弃元器件引脚向上延长P1.2引脚
- 使之形成惯性开关的两个触点 再把P1.4引脚略向内弯曲形成侧撞触点
- 把一支废弃的元器件引脚焊接在单片机的第40脚上(VCC)
- 再取一段导线将一端焊接在单片机的第20脚上(GND)
- 导线另一端的接头处挂大量的锡
- 用胶带固定导线 使之在摇动时不易乱窜
- 此时在单片机一侧形成了电源的正、负极接口
将钮扣电池重叠后放入正、负极接口处
- 最后将单片机连同电池一并塞进塑料壳中
- 用透明胶带把开口处包好 - 因摇动时的离心力向上所以单片机及电池不会向下滑落 无需设计下方固定
- /*********************************************************************************************
- 程序名: SHOOK16摇摇棒控制程序
- 编写人: 杜洋
- 硬件支持: STC12C5A60S2 内部RC时钟
- 接口说明: 单片机P0、P2侧并行排列16个贴片LED(自P2.0开始(-))
- 修改日志:
- [TEST测试版]
- 1-200911122244 在主函数写入简单程序测试惯性开关是否正常,通过测试并备份。(备)
- 2-200911130112 往返摇动双重显示实验成功,目前已经达到摇摇棒功能的基本要求。(备)
- [V1正式版]
- 3-200911130309 加入了3个字幕内容,通过敲击切换字幕。(备)
- 4-200911131910 为网站照片重新设计方案并重定义了IO接口。(备)
- /*********************************************************************************************
- 说明:
- 了解字幕的修改方法,请参考《mini1608字模设计方法》
- V1正式版
- # 硬件制作只需要单片机、LED、电池和导线,制作非常简单。
- # 采用STC增强型单片机。
- /*********************************************************************************************/
- #include <STC12C5A60S2.H> //单片机头文件
- unsigned char MENU;
- #define DY_DELAY 5 //设置每一个点显示的时间长度(1~20)
- sbit KEY1 = P1 ^ 2; //摇动惯性开关
- sbit KEY2 = P1 ^ 3;
- sbit KEY3 = P1 ^ 4; //选择键(大力横向碰击触发)
- sbit LED1 = P0 ^ 3; //LED灯定义,低电平时亮(自上到下)
- sbit LED2 = P0 ^ 4;
- sbit LED3 = P0 ^ 5;
- sbit LED4 = P0 ^ 6;
- sbit LED5 = P0 ^ 7;
- sbit LED6 = P4 ^ 6;
- sbit LED7 = P4 ^ 5;
- sbit LED8 = P4 ^ 4;
- sbit LED9 = P2 ^ 7;
- sbit LED10 = P2 ^ 6;
- sbit LED11 = P2 ^ 5;
- sbit LED12 = P2 ^ 4;
- sbit LED13 = P2 ^ 3;
- sbit LED14 = P2 ^ 2;
- sbit LED15 = P2 ^ 1;
- sbit LED16 = P2 ^ 0;
- /*********************************************************************************************/
- unsigned char code logo[] = { // (取码:从上到下从左到右,纵向8位下高位)
- 0x00,0x00,0x10,0x0E,0xD0,0x01,0xFF,0xFF,//杜
- 0xFF,0xFF,0x90,0x01,0x10,0x43,0x40,0x40,
- 0x40,0x40,0x40,0x40,0xFF,0x7F,0xFE,0x7F,
- 0x40,0x40,0x60,0x40,0x40,0x60,0x00,0x40,
- 0x00,0x00,0x10,0x04,0xE1,0x78,0x4E,0xFE,//洋
- 0x8C,0x63,0x60,0x00,0x00,0x04,0x49,0x04,
- 0x4A,0x04,0x4E,0x04,0xF8,0xFF,0xFC,0xFF,
- 0x4E,0x04,0x6B,0x04,0x4A,0x06,0x00,0x04,
- 0x00,0x00,0x00,0x40,0x04,0x40,0x04,0x40,//工
- 0x04,0x40,0x04,0x40,0x04,0x40,0xFC,0x7F,
- 0xFC,0x7F,0x04,0x40,0x04,0x40,0x04,0x40,
- 0x06,0x40,0x04,0x60,0x00,0x40,0x00,0x00,
- 0x00,0x00,0x80,0x00,0x60,0x00,0xF8,0xFF,//作
- 0xEF,0x7F,0x06,0x00,0x40,0x00,0x30,0x00,
- 0x1C,0x00,0xFF,0xFF,0xFA,0xFF,0x48,0x04,
- 0x48,0x04,0x68,0x04,0x4C,0x06,0x08,0x04,
- 0x00,0x00,0x08,0x00,0x1C,0x80,0x0E,0x81,//室
- 0x94,0x8B,0xD4,0x89,0x75,0x89,0x37,0xFF,
- 0x16,0xFF,0x34,0x89,0xD4,0x89,0x94,0x8B,
- 0x1C,0x81,0x0E,0xC0,0x04,0x80,0x00,0x00
- };
- /*********************************************************************************************/
- unsigned char code logo1[] = { // “DoYoung” (取码:从上到下从左到右,纵向8位下高位)
- 0x04,0x08,0xFC,0x0F,0xFC,0x0F,0x04,0x08, // -D-
- 0x0C,0x0C,0xF8,0x07,0xF0,0x03,0x00,0x00,
- 0xC0,0x07,0xE0,0x0F,0x20,0x08,0x20,0x08, // -o-
- 0x20,0x08,0xE0,0x0F,0xC0,0x07,0x00,0x00,
- 0x00,0x00,0x3C,0x00,0x7C,0x08,0xC0,0x0F, // -Y-
- 0xC0,0x0F,0x7C,0x08,0x3C,0x00,0x00,0x00,
- 0xC0,0x07,0xE0,0x0F,0x20,0x08,0x20,0x08, // -o-
- 0x20,0x08,0xE0,0x0F,0xC0,0x07,0x00,0x00,
- 0xE0,0x07,0xE0,0x0F,0x00,0x08,0x00,0x08, // -u-
- 0xE0,0x07,0xE0,0x0F,0x00,0x08,0x00,0x00,
- 0x20,0x00,0xE0,0x0F,0xC0,0x0F,0x20,0x00, // -n-
- 0x20,0x00,0xE0,0x0F,0xC0,0x0F,0x00,0x00,
- 0xC0,0x27,0xE0,0x6F,0x20,0x48,0x20,0x48, // -g-
- 0xC0,0x7F,0xE0,0x3F,0x20,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //空格
- 0x18,0x06,0x3C,0x0E,0x64,0x08,0x44,0x08, // -S-
- 0xC4,0x08,0x9C,0x0F,0x18,0x07,0x00,0x00,
- 0x20,0x00,0x20,0x00,0xF8,0x07,0xFC,0x0F, // -t-
- 0x20,0x08,0x20,0x0C,0x00,0x04,0x00,0x00,
- 0xE0,0x07,0xE0,0x0F,0x00,0x08,0x00,0x08, // -u-
- 0xE0,0x07,0xE0,0x0F,0x00,0x08,0x00,0x00,
- 0x80,0x07,0xC0,0x0F,0x60,0x08,0x24,0x08, // -d-
- 0xFC,0x07,0xFC,0x0F,0x00,0x08,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x20,0x08,0xEC,0x0F, // -i-
- 0xEC,0x0F,0x00,0x08,0x00,0x00,0x00,0x00,
- 0xC0,0x07,0xE0,0x0F,0x20,0x08,0x20,0x08, // -o-
- 0x20,0x08,0xE0,0x0F,0xC0,0x07,0x00,0x00,
- };
- /*********************************************************************************************/
- unsigned char code logo2[] = { // “与电子爱好者同行” (取码:从上到下从左到右,纵向8位下高位)
- 0x00,0x00,0x00,0x08,0x00,0x08,0x80,0x08,
- 0xFF,0x09,0xFE,0x08,0x88,0x08,0x88,0x08,
- 0x88,0x08,0x88,0x08,0x88,0x0C,0x88,0x48,
- 0x88,0xC0,0x8C,0x7F,0xC8,0x3F,0x80,0x00,
- 0x00,0x00,0x00,0x00,0xF8,0x0F,0xF0,0x07,
- 0x90,0x04,0x90,0x04,0x90,0x04,0xFF,0x7F,
- 0xFE,0xFF,0x90,0xC4,0x90,0xC4,0x90,0xC4,
- 0xF0,0xCF,0xF8,0xC7,0x10,0xF0,0x00,0x40,
- 0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,
- 0x82,0x00,0x82,0x00,0x82,0x40,0x82,0x40,
- 0xE2,0xFF,0xF2,0x7F,0x9A,0x00,0x8E,0x00,
- 0x87,0x00,0x82,0x00,0xC0,0x00,0x80,0x00,
- 0x00,0x00,0x40,0x00,0xE0,0x40,0x74,0x20,
- 0xA4,0x98,0xAC,0x8E,0xFA,0x47,0xE2,0x6F,
- 0xBE,0x3A,0xAA,0x12,0xB2,0x3A,0xBF,0x6E,
- 0xAB,0x67,0xE2,0xC2,0x70,0xC0,0x20,0x40,
- 0x00,0x00,0x20,0x80,0x20,0x63,0xF8,0x37,
- 0xFF,0x1C,0x26,0x0F,0xF0,0x7B,0xE0,0x30,
- 0x82,0x00,0x82,0x20,0x82,0x40,0xF2,0xFF,
- 0xEA,0x7F,0x8E,0x00,0xC7,0x00,0x82,0x00,
- 0x00,0x00,0x40,0x04,0x40,0x04,0x44,0x02,
- 0x44,0xFF,0x44,0x7F,0xC4,0x49,0xFF,0x49,
- 0x7F,0x49,0x64,0x49,0x66,0x49,0x54,0xFF,
- 0xD8,0x7F,0x4E,0x01,0x64,0x00,0x40,0x00,
- 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x7F,
- 0x12,0x00,0xD2,0x1F,0x92,0x0F,0x92,0x08,
- 0x92,0x08,0x92,0x1F,0xDA,0x4F,0x92,0x40,
- 0xFE,0xFF,0xFF,0x7F,0x02,0x00,0x00,0x00,
- 0x00,0x00,0x20,0x04,0x10,0x02,0x8C,0xFF,
- 0xE7,0x7F,0x42,0x00,0x00,0x00,0x20,0x00,
- 0x22,0x00,0x22,0x40,0x22,0x40,0xE2,0xFF,
- 0xE2,0x7F,0x23,0x00,0x32,0x00,0x20,0x00
- };
- /*********************************************************************************************
- 函数名:LED显示用延时函数
- 调 用:delay(?);
- 参 数:1~65535(参数不可为0)
- 返回值:无
- 结 果:占用CPU方式延时与参数数值相同的毫秒时间
- 备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
- /*********************************************************************************************/
- void delay (unsigned int a){ // 用于点扫描的延时
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < 1; i++);
- }
- }
- /*********************************************************************************************/
- /*********************************************************************************************
- 函数名:毫秒级CPU延时函数
- 调 用:DELAY_MS (?);
- 参 数:1~65535(参数不可为0)
- 返回值:无
- 结 果:占用CPU方式延时与参数数值相同的毫秒时间
- 备 注:应用于1T单片机时i<600,应用于12T单片机时i<125
- /*********************************************************************************************/
- void DELAY_MS (unsigned int a){
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < 600; i++);
- }
- }
- /*********************************************************************************************/
- /*********************************************************************************************
- 函数名:关闭所有LED灯(操作硬件)
- 调 用:DISPLAY_OFF();
- 参 数:无
- 返回值:无
- 结 果:所有LED灯熄灭
- 备 注:
- /**********************************************************************************************/
- void DISPLAY_OFF (void){
- delay(DY_DELAY);//显示停留
- P0 = 0xff;
- P2 = 0xff;
- P4 = 0xff;
- }
- /**********************************************************************************************/
- /*********************************************************************************************
- 函数名:单帧数据送入显示(操作硬件)
- 调 用:DISPLAY_PIN(?,?);
- 参 数:16位显示数据(下高位)(d:上面8位,e:下面8位)
- 返回值:无
- 结 果:点亮对应数据的LED灯
- 备 注:
- /**********************************************************************************************/
- void DISPLAY_PIN (unsigned char d,unsigned char e){ //第1列横向显示程序
- unsigned char i;
- i = d & 0x01;
- if(i == 0x01){LED1 = 0;}DISPLAY_OFF();
- i = d & 0x02;
- if(i == 0x02){LED2 = 0;}DISPLAY_OFF();
- i = d & 0x04;
- if(i == 0x04){LED3 = 0;}DISPLAY_OFF();
- i = d & 0x08;
- if(i == 0x08){LED4 = 0;}DISPLAY_OFF();
- i = d & 0x10;
- if(i == 0x10){LED5 = 0;}DISPLAY_OFF();
- i = d & 0x20;
- if(i == 0x20){LED6 = 0;}DISPLAY_OFF();
- i = d & 0x40;
- if(i == 0x40){LED7 = 0;}DISPLAY_OFF();
- i = d & 0x80;
- if(i == 0x80){LED8 = 0;}DISPLAY_OFF();
- i = e & 0x01;
- if(i == 0x01){LED9 = 0;}DISPLAY_OFF();
- i = e & 0x02;
- if(i == 0x02){LED10 = 0;}DISPLAY_OFF();
- i = e & 0x04;
- if(i == 0x04){LED11 = 0;}DISPLAY_OFF();
- i = e & 0x08;
- if(i == 0x08){LED12 = 0;}DISPLAY_OFF();
- i = e & 0x10;
- if(i == 0x10){LED13 = 0;}DISPLAY_OFF();
- i = e & 0x20;
- if(i == 0x20){LED14 = 0;}DISPLAY_OFF();
- i = e & 0x40;
- if(i == 0x40){LED15 = 0;}DISPLAY_OFF();
- i = e & 0x80;
- if(i == 0x80){LED16 = 0;}DISPLAY_OFF();
- }
- /*********************************************************************************************
- 函数名:初始化程序
- 调 用:init();
- 参 数:无
- 返回值:无
- 结 果:设计IO接口为强推方式并全部置1
- 备 注:
- /**********************************************************************************************/
- void init (void){
- P4SW = 0xff; //启动P4接口
- P0M0 = 0xff; //接口设置为强推
- P2M0 = 0xff;
- P4M0 = 0xff;
- P1 = 0xff; //初始IO接口状态
- P0 = 0xff;
- P2 = 0xff;
- P4 = 0xff;
- }
- /**********************************************************************************************/
- /*********************************************************************************************
- 函数名:主函数
- 调 用:无
- 参 数:无
- 返回值:无
- 结 果:程序开始处,无限循环
- 备 注:
- /**********************************************************************************************/
- void main (void){
- unsigned char a,c;
- init();//初始程序
- while(1){
- if(MENU > 2){
- MENU = 0;
- }
- if(MENU == 0){ //字幕1
- if(KEY2 == 0){
- DELAY_MS(20);
- while(KEY2 == 0);
- c = 0;
- for(a=1;a<80;a++){ //这里的“80”是这个字幕需要扫描的列数,修改字幕时必须修改此参数。
- DISPLAY_PIN (logo[c],logo[c+1]); //“LOGO”是第一个字幕的数据表名
- c=c+2;//产生显示行移位
- }
- }
- if(KEY1 == 0){
- DELAY_MS(20);
- while(KEY1 == 0);
- c = 158;
- for(a=1;a<80;a++){
- DISPLAY_PIN (logo[c],logo[c+1]);
- c=c-2;//产生显示行移位
- }
- }
- if(KEY3 == 0){
- DELAY_MS(20);
- while(KEY3 == 0);
- MENU++;
- }
- }
- if(MENU == 1){ //字幕2
- if(KEY2 == 0){
- DELAY_MS(20);
- while(KEY2 == 0);
- c = 0;
- for(a=1;a<108;a++){
- DISPLAY_PIN (logo1[c],logo1[c+1]);
- c=c+2;//产生显示行移位
- }
- }
- if(KEY1 == 0){
- DELAY_MS(20);
- while(KEY1 == 0);
- c = 214;
- for(a=1;a<108;a++){
- DISPLAY_PIN (logo1[c],logo1[c+1]);
- c=c-2;//产生显示行移位
- }
- }
- if(KEY3 == 0){
- DELAY_MS(20);
- while(KEY3 == 0);
- MENU++;
- }
- }
- if(MENU == 2){ //字幕3
- if(KEY2 == 0){
- DELAY_MS(20);
- while(KEY2 == 0);
- c = 0;
- for(a=1;a<128;a++){
- DISPLAY_PIN (logo2[c],logo2[c+1]);
- c=c+2;//产生显示行移位
- }
- }
- if(KEY1 == 0){
- DELAY_MS(20);
- while(KEY1 == 0);
- c = 254;
- for(a=1;a<128;a++){
- DISPLAY_PIN (logo2[c],logo2[c+1]);
- c=c-2;//产生显示行移位
- }
- }
- if(KEY3 == 0){
- DELAY_MS(20);
- while(KEY3 == 0);
- MENU++;
- }
- }
- }
- }
- /**********************************************************************************************
- /**********************************************************************************************/
- /*************************************************************
- * 杜洋工作室 DoYoung Studio
- /*************************************************************/
复制代码
|