找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6151|回复: 19
打印 上一主题 下一主题
收起左侧

开源!和你一起用51单片机和点阵打造游戏机、时钟(下)

  [复制链接]
跳转到指定楼层
楼主
ID:53125 发表于 2013-8-16 22:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
分享帖终于和大家在51hei论坛见面了,本来想0点发的,不过……嘿嘿,还是开源分享帖哦~~不过实在太冷了,就没去实验室录专门的技术支持教程给大家。完全靠打字了,手生冻疮,也很辛苦的,大家谅解!!
这“下”帖让大家等了那么久,本人后面发帖也倍感压力啊,如果这“下”帖不给力的话,对不起观众啊。先给大家看看,我共享给大家的资料里,包含哪些东西吧,先看资料给不给力哈。压缩包包含以下内容:

先看视频展示:

大家请结合上帖来看下帖:http://www.51hei.com/bbs/dpj-20607-1.html
我这个分享帖打算分为以下几个部分:

一、晒整体原理图和PCB:
二、整体硬件的介绍
三、整体软件编程技巧
四、各个模块介绍
五、关于手工双面板制作的介绍
六、开源分享的资料

很多都是本人的经验,有不对地方,请大家指正。

一、晒整体原理图和PCB:
主控原理图及PCB:

TEA5767收音机、TDA2822功放原理图及PCB:


PL2303 RS232转TTL下载器原理图及PCB:


对于制作的过程,只保留有以下三个图片,大家可看下:


  
下面是硬件说明图:










硬件介绍在上面的三个图示已标明,看不清的可下我分享的资料!
二、整体硬件的介绍
1、使用STC12C5A60S2:
(1)内部有AD,实现了电压表功能,以及以后扩展作频谱显示屏;
(2)其工作的最低电压是3.3V,所以可以用锂电工作哈(锂电电压为3.7V左右);
(3)内有RC振荡器,所以对时序要求不是很高的场合可以使用。但是由于初始芯片默认是用外部晶振,且STC-ISP下载软件默认使用外部晶振,一不小心就变成外部晶振,如果不接外部晶振的话,很容易不小心选成外部晶振而无法启动芯片。所以后面我还是加了外部晶振,我的程序,可以使用外部12M晶振,也可以使用内部RC振荡器(13M左右)。
(4)该芯片IO口可以拉电流,像AVR单片机一样,可以设置IO口状态,使得灌电流和拉电流都可以达到20mA左右,所以可以IO口直接驱动数码管,但注意加限流电阻,不然很可能烧坏IO口而使芯片无法作用。
(5)有1K的EEPROM,可以掉电存数据,所以可以掉电保存闹铃设置的时间,开关标志位等,但严格的讲,这个根本不是真正的EEPROM,只能说凑合着用吧。而且在使用锂电供电时,会出现电压偏压而无法正常读取该EEPROM区。
(6)该芯片还有P4口,PWM等等功能,而且RAM和ROM都很大。对于该芯片最小系统的连接及使用等等详情请参看其数据手册。
2、显示电路的设计:
为了方便横屏和竖屏的显示,大家看我的硬件原理图就会发现,我的显示电路在点阵的处理方面既可行扫描显示,也可以列扫描显示。
一般点阵的显示都是行扫描显示,特别是只有16行的点阵,很多都会用到两片3-8译码器构成4-16译码器或直接用74LC154做4-16译码器,这种做法优点是控制简单,又比较节约IO,写程序也方便。但这种做法只能固定的用行扫描显示。
而我的行线用的是595串入并出的芯片,竖屏是595控制行线,单片机P0输出每行的数据,竖屏扫描原理如下:

横屏是单片机P0进行每行数据的扫描,而595这时输出每行的数据,如下:

上面所说的行和列,都是相对横屏和竖屏而言的。具体为什么在横屏和竖屏要分不同的扫描方式呢?下面的程序讲解会提到哈~~
3、PL2303下载器:
其实我以前有串口的下载器,是通过USB转串口,再用MAX232芯片把串口转成TTL,感觉那样非常麻烦,而且很容易出问题。所以这一次我自己手工做了PL2303下载器,这个PL2303芯片也难搞,只有贴片的,毛毛脚的,加上我的板是手工转印、烙铁又差,所以焊接还费了不少时间,还好,本人焊贴片的水平不是盖的,还是焊好了。为了方便STM32芯片的下载还对原始电路做了修改,有RESET、和BOOT0。这个帖子的主角不是下载器,因此后面我会另外开帖给大家分享我做的一些常用单片机的下载器。我最后做好的下载器如下:

三、整体软件编程技巧在这里我只简单的说说可能在很多单片机教学视频里不涉及到,而在我这整个工程中用到的编程技巧和注意事项。
1、点阵显示:
(1)一般点阵,特别我们发烧友做的点阵,基本上都是行扫描显示的,为什么要行扫描显示呢?我想还是因为很多点阵都是为了左右滚动的显示,行扫描编程和硬件实现上都比较方便吧。因此,我的硬件设计也是为了迎合软件的编程方便,不管横屏还是竖屏,都是相对的采用行扫描显示。但是,对于旋转屏和“摇摇棒”这种显示是必须要列扫描显示的,为什么要列扫描还想不通的朋友自己揣摩了。
(2)特别还要注意点阵的消影,很多初学者写数码管或点阵扫描程序时会出现“鬼影”,所以消影的这一招也是要必须学会的,最简单可行的办法就是每扫描显示一行或一个数码管后,关闭一次全部的显示。同时注意先传数据码、后点亮当前行或当前位。具体可参考我程序,我的是没有任何鬼影的哈。
(3)为了实现滚动显示,同时滚动显示的数据能实时更新,必须有一个显示缓存区,这个显示缓存区必须是可读可写的。点阵显示指针只是从头到尾一行行的扫描显示缓存中的数据,即“读”的过程,而要实时更新缓存中的数据,还要把相关变量不断的“写”到显示缓存对应的位置。从而需要一个可读、写的缓存区,这里定义为数组是方便扫描指针不断下移读取,这其实跟电脑中说的显卡的显存是一个道理的。而具体滚动显示的编程技巧,大家可以参看我的程序,里面会有备注的,当然方法不是唯一的。
(4)这个可读可写的缓存区,很多人都直接定义为“data”的类型(如果不设置,默认也是这个类型),用这个类型本身没错,在写小程序中还可以用,也不会超RAM空间,但当你定义的全局变量多,而且定义的可读写的数组多时,编译就不过了,会提示你超RAM了,但实际RAM却没满。这是为什么呢?这个要从51单片机硬件原理来讲了,平时我们所说的如51单片机RAM是4K,52单片机RAM是8K,实际它们的内部直接寻址区的大小是一样的,即data区,硬件地址是00H-7FH。而不同的是间接寻址的地址80H及以上不同,所以定义可读写数组时最好定义为“idata”,以节省可直接寻址区。而其它变量要不要也定义为"idata"呢?这个一般就不用了,除了数组外,其它变量最好不要定义为“idata”。下面是我定义的“idata”:


(5)如果只是显示固定字符,可以直接定义为 "code",单片机的内部程序存储区,即ROM区,只可读,显示指针就一直往下读就可以了。
像我开机欢迎画面就是这样写的:

总的来说,这里涉及到KEIL C编译器中定义的几个字节型的变量,这里简单总结如下:
data区(默认):单片机能直接访问的直接寻址RAM区,00H-7FH;
bdata区:可位寻址的片内ram,位于20H-2FH,总共128位;
pdata区:分页寻址片外ram (MOVX @R0) (256 BYTE/页);
idata区:单片机间接防问的RAM区,80H-FFH,也有说法可以理解为前128和data的128完全相同,只是因为访问的方式不同(MOX ACC,@Rx);
code区:单片机的内部程序存储区,也就是单片机内置的FALSH 对应MOVC @DPTR;
xdata区:单片机外部寻址区,一般指片外的存储器,0000H-FFFFH。
还有不理解的,可以百度或翻翻单片机原理方面的书籍。
2、关于break,return,goto等函数的使用
(首先声明一下,我不是电子专业,我的专业没学过C语言,只开了VB课程,我用的C是自学的,有说不当的请批评指正!)很多单片机编程者,特别是刚入门的,很少会用到诸如break,return,goto,do…while,continue的函数,更不要说使用结构体和指针。当然我也很少用,在我这个工程中没用过具体的指针和结构体,为了能让大家都看得懂,用的都是相对简单的语句,而且很多都是很啰嗦一个个拆开使用的,其实很多可以合并的。
Break:是只能在循环语句中使用的,程序执行到它后将退出当前循环。
Return:我的程序中很多用到了return,该语句的作用是退出当前所执行的子函数,是可以在任何函数,任何地方使用的。注意和break区别开,一个只是退出循环,而后者是退出整个函数。所以用return我可以实现在任意地方,哪怕是在死循环函数里面,离开现在的功能,转到另外的一个功能。比如我程序用到的地方:

Goto:我没有在这个工程用到,这个goto只能在同一个子函数中无条件调转,可能以后会对大家有用吧。
还有continue等其它这里不再累述,大家自己查资料吧。
(3)关于STC和经典51单片机的延迟
这个我不想多说了,由于STC执行普通指令的速度是一般51单片机的3-12倍(具体参看芯片手册),因此以前的51单片机延迟函数要修改,大家用STC的参看我的程序就行,我的程序是用12M外部晶振或内部RC振荡器(大概13M)都是能用的,而且我没有分频哦。特别是那个18B20温度传感器的延迟,我测试了好久才把它的延迟搞定了~~~
还有更多的硬件和软件的问题,下面将在各个模块的介绍中有针对性的介绍。
(4)结构化编程
将复杂的程序分成一个模块来写,这是程序员必须要学会的,当然,现在我这里还是比较乱,相信大家会弄得更好。同时,我的程序,很多个子功能已经弄成头文件,如DS0302、18B20、I2C、STC的各类功能等等,大家只要注意一下不同硬件的延迟函数(主要是I2C和18B20比较讲究)就可以直接调用的,以下是我的工程截图:

四、各个模块介绍
在这里,为了减少大家的阅读量,不再累述各个模块的具体功能,大家可以对着上一帖子来看,下面着重讲原理和编程技巧。
1、时钟功能

时钟我用的是DS1302时钟芯片,用钮扣电池续电;农历的计算是通过软件实现的;温度是通过DS18B20实现的;语音报时是通过YF-017语音芯片实现的;最后掉电能保存闹钟时间和开关标志位是通过STC12C5A60S2内置的EEPROM实现的,红外遥控这个就不用说了。

(3)遥控器是用通用车载MP3的,很多开发板都送这个:

附上各个按键的编码:
机器编码:0x00
各个按键键码值: CH-:0x45  CH:0x46  CH+:0x47  PREV:0x44  NEXT:0x40  PLAY:0x43  VOL-:0x07  VOL+:0x15  EQ:0x09  0:0x16  100+:0x19  200+:0x0d  1:0x0c  2:0x18  3:0x5e  4:0x08  5:0x1c  6:0x5a  7:0x42  8:0x52  9:0x4a
2、俄罗斯方块功能

硬件没什么好说的,就是前面的点阵、按键和遥控器,内核全靠软件实现的。
这里着重说下这个的编程原理(程序备注中有):
【特别说明:该俄罗斯方块源程序不是本人的,是网友提供的源码,然后我根据自己的硬件和需要,在充分理解源程序的基础上做了大量的修改和BUG优化。在此向源程序提供者致敬!】
图形方块编码机制介绍:
(1)由于俄罗斯方块图形的宽度和高度最多只有四位,所以要以4X4为基本单元;
(2)硬件采用18行扫描(16行点阵,两个数码管)、8位送显示信号;
(3)各个图形的宽度不一致,所以要人为给图形设定居中位置,若图形宽度为偶数可直接将其居中,若为奇数则靠左居中;
(4)由于图形需要旋转,所以由基本的图形会衍生出另外3种图形;
(5)因此每个图形应该给定4个8位的二进制码,并放入一个二维数组里;
(6)经典俄罗斯方块游戏里有19种不同形状的方块,包括旋转得到的;
(7)数组的第一个下标为该图形的编号。
具体请参看全局定义的头文件及程序内备注。
3、收音机功能

这里的收音机我使用的芯片是TEA5767飞利浦的收音芯片,并使用I2C通讯,实际的效果大家在视频中也看到几乎收不到台。这不是我软件问题,而是我所处的位置问题,我住的是学校宿舍区,是一楼的,由于钢筋水泥等等的屏蔽和影响,加上本身硬件上的各类干扰,收不到电台是否很正常的,我试过拿到室外,还是勉强可以收到台的。而且我这个TEA5767是多另外一块开发板上拆下来的,可能也不太行了吧。但程序与芯片的通讯还是通的。为什么我敢这么说,因为给芯片发数据还是有反应的,而且还可以读出频率及启动自动搜台。
总的来说,这个功能现在看起来只能是“鸡肋”,但程序和硬件连接大家还是可以参考的,还有我用的天线是网上卖的专用耳机天线哈。
这里的功放用的是TDA2822构成单声道功能,效果一般,原理图和网上的一样。但由于收音芯片的声音输出及单片机的P10相接,并和外面的音源输入相连,通过外接音源时,音质很差的,大家在视频中也看到了。加上接YF017语音芯片的喇叭与TDA2822的输出共用一个喇叭,那问题更大了,因此,这里现在的功能只能算“鸡肋”了,后面会再优化吧。
4、“摇摇棒”功能

“摇摇棒”主要是靠水银开关了,这个程序我没有参考别人的,因为之前我写过旋转屏的程序,“摇摇棒”的原理和它几乎如出一辙。旋转屏是靠上下的红外对管控制中断,从而决定从哪播放的,而“摇摇棒”主要是靠水银开关来引发中断,控制要从一个方向开始播放,没有水银开关也可以显示,但由于是来回甩动的,没有水银开关控制方向会出现“镜像字”。特别要注意水银开关的安装方向,如果你软件图形的取模和显示是从左到右扫描一列一列显示的,那么你的水银开关应该面向显示面且相对水平面呈锐角45度安装(引脚朝下);反之,如果你软件图形的取模和显示是从右到左扫描一列一列显示的,那么你的水银开关应该面向显示面且相对水平面呈钝角135度安装(引脚朝下)。大家看我的是从左到右扫描显示的,所以,相对显示正面是呈锐角45度安装的。我编程显示的时候是只选择8列中的一列进行显示,比如我用了P03控制的那一列来显示,然后595传每列的数据,具体程序参看我提供的程序。
5、简单电压表功能

这里的电压表主要是靠STC12C5A60S2内部的AD功能实现的,通过读芯片手册可以知道,该AD功能的参考电压是芯片自身的工作电压。然后问题就来了,我的整个设计是既可用外部5V供电,也可用锂电供电,两个差别很大的参考电压,我是什么处理的呢?其实,实际的话,虽然说芯片本身不提供输入外部基准电压的功能,但是如果采用同时采样两路AD值,其中一路的电压值(作为外接基准电压)是已知的,那么通过两个方程,两个未知数,是不是可以轻易的求出准确的AD值了呢?所谓两个方程如下:
如我在P17引脚输入已知的1.25V作为参考电压,而我要测P10的实际电压,然后我假设芯片电源电压是5V,那么我AD转换后得到P17的电压值为:
AD_C0=(uint)((get_adc(0x07)*5)/1.024);  //“5”为假设的芯片电压。
待测P10的AD电压值为
AD_C1_tmp=(uint)((get_adc(0x00)*5)/1.024);  //“5”为假设的
最后整合这两个方程,就可以消掉“5”即芯片的实际电压可以不用管,最后处理P10实际电压值是:
AD_C1=(uint)( AD_C1_tmp *12.50/AD_C0);
这是一个方法了哈,还不明白的,自己慢慢消化了。
而我在这个东西用的却不是以上方法,因为当初设计的硬件原因,最后我采用最简单的办法,方法就是在主开关那里动手脚。注意看,我用的是按键自锁型的双刀双掷开关,其中的一“刀”我用到了电源的正极上,通过对正极的切换实现内部锂电和外接电源的切换;而另外的一“刀”中我当作接负极的开关接到单片机的P45 IO口,因此,在切换电源的同时,也切换了P45 IO口的电平变化。因此,在精度要求很高的场合,我只要检测P45 IO口的电平,就有选择的在程序里改变了参考电压,在程序中我是这样处理的:
ad_tmp=get_adc(0x01);  //获得P11引脚上的AD值
if(!P45) ad_val=(uint)((ad_tmp*3.85)/1.024);         ///AD值处理,3.85为使用锂电时MCU的电压,最终ad_val单位为mV
else ad_val=(uint)((ad_tmp*4.95)/1.024);                  ///AD值处理,4.95为MCU现在的电压,最终ad_val单位为mV。
终于介绍完了各个模块,很多的技巧也都告诉大家了~~
也许还有一些细节和我DIY的地方没跟大家唠,因为有些大家可以没必要效仿或我觉得大家应该都了解了,还有什么疑问,大家再跟帖问吧。哦,还有,刚才提到了锂电和外接5V的切换开关,有人可能会问,我这个东西可不可以接5V时,一边用一边充电。现在是不可以的,因为我没做或买5V转锂电充电的板子,我的锂电充电是另外引出,用万能充充电的,

五、关于手工双面板制作的介绍(另开帖)
六、开源分享的资料
这里的压缩包包含原理图(当然,只是画有PCB的部分,还有一些我后面自己DIY或修改的地方就没有咯,但上面都有介绍了~)、PCB图、清楚的图片讲解图、总工程程序源码及部分模块程序源码等等。

对于本帖未详尽事项,如“五、关于手工双面板制作的介绍”,请移步到下一帖(链接:),因为这一帖的内容够多了,我打字排版辛苦不要紧,重要的还是让大家看得明白。以及帖子中提到的下载器介绍和PCB打印,打印机设置及注意问题……还有,等等,我之前说过还有语音计算器和频谱展示及分享这两个的程序,由于篇幅和时间问题,还是全部留到后面另开帖吧,大家请期待!感谢你的关注和支持!新年快乐!

“多功能智能玩具”共享资料.rar (3.43 MB, 下载次数: 284)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:45583 发表于 2013-9-4 16:09 | 只看该作者
楼主真强呀!
回复

使用道具 举报

板凳
ID:52286 发表于 2013-10-14 00:15 | 只看该作者
支持支持、、
回复

使用道具 举报

地板
ID:54817 发表于 2013-10-20 12:23 | 只看该作者
不错,想法很好
回复

使用道具 举报

5#
ID:58986 发表于 2014-1-31 16:09 | 只看该作者
楼主辛苦了.......高手啊...功能做得这么好.....
回复

使用道具 举报

6#
ID:60246 发表于 2014-4-3 21:56 | 只看该作者
谢谢分享
回复

使用道具 举报

7#
ID:59170 发表于 2014-4-3 22:10 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

8#
ID:46750 发表于 2014-4-6 14:05 | 只看该作者
楼主真强呀!
回复

使用道具 举报

9#
ID:52249 发表于 2014-4-14 18:03 | 只看该作者
手中还有器材,也想做一个,下来参考一下。
回复

使用道具 举报

10#
ID:61107 发表于 2014-4-25 22:35 | 只看该作者
真吊,不错
回复

使用道具 举报

11#
ID:66181 发表于 2014-9-15 11:39 | 只看该作者
谢谢分享
回复

使用道具 举报

12#
ID:66512 发表于 2014-9-22 20:55 | 只看该作者
楼主真强呀!
回复

使用道具 举报

13#
ID:71584 发表于 2015-1-4 03:40 | 只看该作者
感谢分享!!!!!!!
回复

使用道具 举报

14#
ID:71584 发表于 2015-1-4 03:40 | 只看该作者
感谢分享!!!!!!!
回复

使用道具 举报

15#
ID:63924 发表于 2015-4-30 22:51 | 只看该作者
楼主,厉害啊,谢谢分享!!!!!!!!期待有好的功能 语音计算器和频谱展示
回复

使用道具 举报

16#
ID:63924 发表于 2015-4-30 22:52 | 只看该作者
回复

使用道具 举报

17#
ID:58502 发表于 2015-4-30 23:20 | 只看该作者
你好,我想问下语音报时怎么实现的,我也用这个芯片做了个点阵时钟,我也想加入语音功能
回复

使用道具 举报

18#
ID:21545 发表于 2015-5-30 21:08 | 只看该作者
想学习一下红外的代码
回复

使用道具 举报

19#
ID:111007 发表于 2016-4-9 23:20 | 只看该作者
牛啊,终于找到你
回复

使用道具 举报

20#
ID:125504 发表于 2016-6-8 18:18 | 只看该作者
回帖是一种美德,楼主强大
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表