标题: 小白菜的学习之路系列之四—欢天喜地摇摇棒 [打印本页]
作者: jiujiu 时间: 2014-12-20 18:22
标题: 小白菜的学习之路系列之四—欢天喜地摇摇棒
一 背景
话说年就要过去了,某人的生日也快到了。送个什么东西好呢?小白菜开始思考了,上次送是一条小白菜自己设计定做的项链(银的,不贵的,同学们可以试一下哦,保证让小女生感动的不得了……咳咳,有点跑题了。),这次嘛,送个什么好,想啊想,要不就送个闪字摇摇棒吧。摇摇棒又好玩,而且能亲手做(表达心意嘛),还能锻炼一下动手能力,最主要的是自己亲手做的东西是天下独一份的哦。恩,说做就做!
小白菜会把这次DIY过程的全部资料无私奉献!鼓掌!!!可是,这是为什么呢?因为现在地里的白菜8分钱一斤没人要啊,还不如白送呐!!!哈哈。开玩笑!不过种白菜的今年吃苦头了,希望他们早日过上好日子……
二 应用需求 做一个摇摇棒!
三 过程分析
手不停的左右摇晃,利用人眼的视觉暂留来显示一幅画面,其原理和数码管、点阵的动态扫描相同。因此需要LED和单片机,还需要一个启动显示的装置,并且在摇到一定的位置时来触发这个装置,这个装置就是惯性开关。别的没了……
四 硬件分析
单片机及外围电路必不可少。单片机就先STC90C52RC,为什么?因为我手上暂时就只有这一片能用的了。16个LED可以显示汉字,通过电阻连接到VCC,另一端接IO口。
难点来了,惯性开关!小白菜手上没有水银开关,就用加了点焊锡的铜线来充当吧。见图4.1.1。
电池?当然要有!省电???需要稍微考虑一下。附录1是较为详细的制作过程。
图4.1.1 DIY“水银开关”示意图
五 软件分析
通过过程分析,小白菜了解了一个重要的地方,触发显示。但小白菜喜欢把功能拆分开,于是就需要两个函数来处理,触发函数和显示函数。
1 司令部——触发函数
通过检测惯性开关来决定是否起动显示,这是发命允显示命令的函数,因此是司令部!既然是允许显示,那就起名App_YYB_Disp_Enable()吧(App是什么?小白菜的应用层函数的前缀)。
2 作战部队——显示函数
显示函数只负责显示。当司令部触发函数发布显示允许命令后,该函数把一幅图片显示出来(就算是汉字,其实也是一幅点阵图片)。这就像作战部队接到命令后进行执行一样。软件起名App_ YYB_Disp()。
3作战内容——显示内容
找个取模软件把要显示的东西取个模,然后把数据放到code区。尽量放在code区哦。
六 代码编写 略
七 成果展示
“谁知盘中餐,粒粒皆辛苦。”成果出来的那一刻,小白菜心里巨激动!毕竟是个人的劳动成果嘛。话不多说,直接上图。
图7.1.1 效果图
八 总结
1 一开始测试时,不要急于显示汉字,因为汉字是相对复杂的图案。可以先点亮一行或一列。循序渐进!延时要自己进行测试。一开始小白菜在显示列时用的是毫秒级延时,后来发现时间太长,于是改用了微秒级延时。
2 由于手在来回摆动的时候不是匀速的,在最边上时速度最慢,所以在触发后要先延时一段时间,待行进到较为匀速区之后再开始显示。当然,你也可以动态的进行延时来处理这个问题。
3惯性开关可以做成双向触发的(类似于单刀双掷开关)。由两个IO口来确定两个边的位置。如图8.3.1所示。软件也要做相应的更改。如左边触发时,正序显示,右边触发时,逆序显示。(两个都触发时?可以忽略或者取一边有效。)要注意显示时把握好延时。
4显示方式可改变。我们一般都是一次送出8位LED数据到Pn口,这是因为我们的硬件支持我们这们做,如图8.4.1所示,各个LED间互不影响。
是否有其他显示方式?其实我们可以每次只送出一个LED的数据,然后把Pn口的8位数据依次送出,之后显示下一字节。既然一次只点亮一个数据,那个我们可以只用一个限流电阻,如图8.4.2所示。此时一定要保证一次只点亮一个LED,否则亮度下降,注意不要烧毁0.25W的电阻。
图8.3.1双向触发惯性开关
图8.4.1 普通LED接线方式
图8.4.2 无实用价值的改进型LED接线方式
九 附件
内有硬件原理图,源代码,以及本文的PDF版本。
十 联系小白菜
QQ = 1062509507
3htech
我是一颗小白菜~
======================================================================
附录1:摇摇棒硬件制作过程,一定要先画原理图。
原理图
1 焊接LED,数目自己定。之后焊接电阻,最好用直插元件,小白菜这里都是贴片的……小白菜又测量了下电阻值(1k,5%精度)。
图F1.1.1 焊接LED
图F1.1.2焊接限流电阻
图F1.1.3 检查电阻焊接质量
2 焊接DIP40座和单片机的复位电路,晶振电路。还是贴片的……
图F1.2.1焊接DIP40座 图F1.2.2焊接复位电路和时钟电路
3 焊接惯性开关。由于怕惯性开关自身质量太小,所以加了个焊锡球。为了不让它上下活动,我加了一个小罩子,这样就能保证只在一定的范围内活动。
图F1.3.1惯性开关
4 用排线连接LED和单片机以及开关。如图F1.4.1。
5 焊接电池座和电源地线。整机焊接完成。如图F1.5.1。这里我强压了一个DIP40座,方便我取下单片机下程序。两个电池串联的,电压6V。正好。效果图如图F1.5.2和图F1.5.3。
图F1.4.1背面连线图 图F1.5.1 整机正面图
图F1.5.2 效果图1 图F1.5.3 效果图2
欢天喜地摇摇棒.rar
(3.34 MB, 下载次数: 2870)
作者: jiujiu 时间: 2014-12-20 18:24
主程序预览:
- #include "Config.H"
- //========================================================================//
- // 惯性开关 //
- //========================================================================//
- sbit InertiaSwitch = P2^7; // 为0时表示开关闭合了。
- //========================================================================//
- // 显示允许函数 (对外提供服务)
- //函数名称:App_YYB_Disp_Enable ()
- //函数功能:检查当前是否允许显示
- //入口参数:无。
- //出口参数:TRUE = 运动到最左边,口线电平被拉低,允许启动显示。FALSE = 其他位置,不允许显示。
- //重要说明:
- //编写日期:2012-11-29
- //测试结果:
- //========================================================================//
- // 函数返回值:
- extern uint8 App_YYB_Disp_Enable(void)
- {
- // 闭合后口线电平为低
- if(0 == InertiaSwitch)
- {
- Delay_MS(30); // 在刚触发时,摇摇棒刚行进到最左边,此时速度很低,因而若立即启动显示,则必然会使字显示的很少,所以延时一段时间。
- // 在摇摇棒速度上来之后再启动显示。
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- //========================================================================//
- // 显示部分 //
- //========================================================================//
- //========================================================================//
- //变量名称:u8Picture
- //变量功能:保存需要显示的数据
- //作用域 :全局变量、仅限本文件
- //重要说明:,仅适用于本程序。
- //========================================================================//
- static uint8 code u8Picture[4][32] =
- {
- 0xFF,0xFF,0xFF,0xEF,0xFF,0xEF,0xFE,0xEF,0x00,0x6F,0x80,0xEF,0xEE,0xEF,0xEE,0xEF, // 与
- 0xEE,0xEF,0xEE,0xEF,0xEE,0xCF,0xEE,0xED,0xEE,0xFC,0xCE,0x01,0xFC,0x03,0xFE,0xFF,
- 0xFF,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xBE,0xFF,0xBE,0xFF,0xBE,0xFD,0xBE,0xFD, // 子
- 0xB8,0x00,0xB0,0x01,0xA6,0xFF,0x8E,0xFF,0x1E,0xFF,0xBE,0xFF,0xFC,0xFF,0xFE,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x80,0x01,0xB7,0xFF,0xB4,0x07,0xB6,0x0F,0xB6,0xEF, // 同
- 0xB6,0xEF,0xB6,0x07,0xA4,0x0D,0xB6,0xFD,0x80,0x00,0x00,0x01,0xBF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFB,0xDF,0xF7,0xBF,0xCE,0x00,0x18,0x01,0xBD,0xFF,0xFF,0xFF,0xFB,0xFF, // 行
- 0xBB,0xFF,0xBB,0xFD,0xBB,0xFD,0xB8,0x00,0xB8,0x01,0x3B,0xFF,0xB3,0xFF,0xFB,0xFF,
- };
- //========================================================================//
- // 显示一列数据函数 (对外提供服务)
- //函数名称:App_YYB_Disp_Colum ()
- //函数功能:显示一列数据。
- //入口参数:u8UpByte为16位的上半部分数据,u8DownByte为下半部分数据
- //出口参数:无。
- //重要说明:
- //编写日期:2012-11-29
- //测试结果:
- //========================================================================//
- static void App_YYB_Disp_Colum(uint8 u8UpByte, uint8 u8DownByte)
- {
- P1 = u8UpByte;
- P0 = u8DownByte;
- Delay_50us(10); // 延时500us,可自行调节
- P1 = 0xFF; // 关闭显示
- P0 = 0xFF;
- }
- //========================================================================//
- // 显示图像函数 (对外提供服务)
- //函数名称:App_YYB_Disp()
- //函数功能:显示一幅图片。汉字点阵实际上也是一幅图片
- //入口参数:u8disp_Enable:是否起动显示。TRUE = 允许起动显示,FALSE = 不允许显示。
- //出口参数:无。
- //重要说明:
- //编写日期:2012-11-29
- //测试结果:
- //========================================================================//
- extern void App_YYB_Disp(uint8 u8disp_Enable)
- {
- uint8 i, k;
- if(FALSE == u8disp_Enable)
- {
- return; // 一个函数最好只有一个出口,显然,这里不符合要求。
- }
- for(i = 0; i < 4; i++) // 要显示的4个汉字
- {
- for(k = 0; k < 16; k++) // 这里,一个汉字有16列
- {
- App_YYB_Disp_Colum(u8Picture[i][2*k], u8Picture[i][2*k + 1]);
- }
- Delay_MS(1);
- }
- Delay_MS(20);
- }
- //========================================================================//
- // 主函数 //
- //========================================================================//
- void main(void)
- {
- uint8 u8State;
- while(1)
- {
- u8State = App_YYB_Disp_Enable();
- App_YYB_Disp(u8State);
- }
- }
复制代码
作者: jiujiu 时间: 2014-12-20 18:26
TypeRedefine.H文件:
- /*
- ********************************************************************************
- * WIT
- * 淄博威特电气有限公司
- *
- * 地址:山东省淄博市张店区淄博市高新技术开发区政通路135号高创中心E座2层
- * (c) Copyright 2012, All Rights Reserved
- * www.weitedq.com
- * 开发环境 : Keil4
- * 文件名 : TypeRedefine.H
- * 程序员 : 3htech
- * 开发时间 : 2012-06-04
- * 描述 : 类型重新定义。
- * 生存条件 : 自由存在。
- *-------------------------------------------------------------------------------
- * 修 改 :
- * 日 期 :
- * 描 述 :
- *-------------------------------------------------------------------------------
- ********************************************************************************
- */
- //------------------------------ 文件开关 ------------------------------//
- // 防止文件包含时多次编本文件,与本文件结尾处的endif对应。
- #ifndef _TYPEREDEFINE_H_
- #define _TYPEREDEFINE_H_
- //----------------------------------------------------------------------------//
- //------------------------------ 系统头文件包含 ------------------------------//
- #include<stdio.H> // 为了使用NULL的定义。
- //----------------------------- 自定义头文件包含 -----------------------------//
- //无
- //-------------------------------- 类型声明 --------------------------------//
- //----------------------------------------------------------------------------//
- //类型名称:
- //类型功能:
- //成员详解:
- //重要说明:
- //----------------------------------------------------------------------------//
- //------------------------------ 全局变量定义 ------------------------------//
- //无
- //--------------------------------------------------------------//
- // 类型重新定义
- //名称:类型重新定义
- //功能:
- // 51系列单片机应用下的类型重新定义。
- // 使用的是8位单片机,因此char是8位,int为16位,long为32位
- //--------------------------------------------------------------//
- typedef bit bdata uint1; // 无符号1 位整型变量需要加前缀u1
- typedef unsigned char uint8; // 无符号8 位整型,前缀u8
- typedef signed char int8; // 有符号8 位整型,前缀i8
- typedef unsigned int uint16; // 无符号16位整型,前缀u16
- typedef signed int int16; // 有符号16位整型,前缀i16
- typedef unsigned long uint32; // 无符号32位整型,前缀u32
- typedef signed long int32; // 有符号32位整型,前缀i32
- typedef float flt32; // 单精度浮点数(32位长度),前缀f32
- //------------------------------- 宏定义 ---------------------------------//
- //----------------------------------------------------------------------------//
- //宏名 :TURE, FALSE
- //功能 :错误标志或操作完成标志。
- //重要说明:无
- //----------------------------------------------------------------------------//
- #ifndef TRUE
- #define TRUE 0
- #endif
- #ifndef FALSE
- #define FALSE 1
- #endif
- //------------------------------ 文件开关 ------------------------------//
- // 防止文件包含时多次编本文件,与本文件开头处的 #ifndef 对应。
- #endif
- //----------------------------------------------------------------------------//
- //------------------------------ 文件结束 ------------------------------//
复制代码
作者: jiujiu 时间: 2014-12-20 18:27
Delay.c文件:
作者: 曼涛1314 时间: 2015-1-8 17:06
不错不错
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |