# 有趣的项目--AVR单片机 **Repository Path**: lsy_zhiyu/funny_avr ## Basic Information - **Project Name**: 有趣的项目--AVR单片机 - **Description**: 本仓库用于存放我制作过的各种与【AVR单片机】有关的有趣项目。 AVR单片机是我接触的第二款单片机,大学课程也是教这个。 欢迎大家来探讨交流,提出更多有趣的项目。 本仓库使用AGPL开源协议,请大家遵循。 - **Primary Language**: C - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 9 - **Forks**: 3 - **Created**: 2021-10-22 - **Last Updated**: 2026-04-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 有趣的项目--AVR单片机 ## 介绍 - 本仓库用于存放我制作过的各种与【AVR单片机】有关的有趣项目。 - AVR单片机是我接触的第二款单片机,大二课程也有教这个。不过我在大一就参加创客协会一起学习了一些,外加自学更多的知识,在大二avr课程上就游刃有余了。 - 其实对比51单片机,虽说一直以来avr比较强,但51也在开发新单片机,最新的STC15系列我觉得就已经可以超过avr的单片机了,而且开发硬件成本低,所以avr估计用得不多,往后开发我也就比较少用avr单片机。 - 欢迎大家来探讨交流,提出更多有趣的项目。 - 本仓库使用AGPL开源协议,请大家遵循。 ### 硬件说明 - 使用ICCV7(ICCAVR)或其他软件编程的,大部分使用ATMEGA16单片机的,少部分使用48、128等型号单片机,有些项目是使用proteus软件进行仿真的。 - 使用progisp1.72及更新版本,使用USBISP烧写器连接就可以烧录了。 - 由于是多年后整理的,可能需要自行在代码中找引脚连接等硬件信息。 ### 视频展示链接(B站) (后续会贴上各个视频地址) 1. 2018.3智能羽毛球捡球机(大学生创新训练项目、校夏令营比赛、第三届创客马拉松大赛):https://b23.tv/eBpFz6M 2. 2018.4七彩频谱旋转屏幕(led显示屏大赛):https://b23.tv/cU0rSQB 3. 简易智能插座1: 4. 简易数字时钟52: 5. 简易交通灯53: 6. 打地鼠游戏54: 7. 简单遥控小车: 8. 点阵+方向键: 9. 控制192个舵机: 10. ADC键盘: 11. 密码锁: 12. 2018初 冬令营大作业: ## 各项目简介 ### 1. 智能羽毛球捡球机 - 这个项目呢,最开始是源于2018年初大一上学期末,跟队友一起讨论参加的,当时有了之前参加科技节比赛、第二届创客马拉松比赛获奖的激动和喜悦,大家就信心满满的决定参加这个大学生创新创业训练项目,这个项目完成时限为2年,题目没有严格规定,只有个大主题(好像是“创新”),然后具体做什么需要队伍里讨论出来,当时队伍中就我有关制作、代码技术方面是比较熟悉的,而其他队友基本还没了解,所以讨论过很多题目,我来分析可行性。最终确定为“智能羽毛球捡球机”,查找资料构思具体内容来写申请书,后续获得省级立项。 - 带入情景:羽毛球作为大众化的运动,适合各个年龄的人们。然而,对于一些体育馆中锻炼羽毛球的人来说,捡羽毛球是比较花费时间的,毕竟一次练习会打几百上千次羽毛球,一地板都是,所以需要有个设备能解决这个痛点。让运动员可以中场休息,而不是花费体力去捡球。 - 市场分析:当时有去网上查找国内外资料,好像暂时还没有类似的,只有辅助工具,辅助人捡球的。而我们的羽毛球又不像那些圆形的,利用有弹性的金属网一压就装起来的,我们这个拾取还需要注意不能损坏到羽毛部分。 - 难点:羽毛球不规则形状,不能像球那样处理,又要保护好羽毛部分,还要收集后能够将羽毛球整齐排列好放在球筒里。后续还计划使用图像识别进行自助找球、自动捡球。 - 整体设计:设计为一个小车厢的外形,使用轮子能够自由走动,对于拾取羽毛球部分,使用大功率暴力风扇抽取箱体内的空气,使得车前端小口能够对羽毛球的吸取,通过一个倾斜的通道吸取到车内部传动带上,倾斜的传送带带动羽毛球往车后方移动,倾斜的设计能够让羽毛球在重力的作用下呈头朝后方,羽毛球朝向前方的姿势,经过塑料板集中到中后方,掉入下方设计的羽毛球筒,检测装满能够转盘切换下个空的球筒。在整体小车运行上,设计使用具有图像识别的板子,对训羽毛球能够识别通知小车控制走向,达到全程自动的效果。后续还设计了利用风机将收集的羽毛球通过管道传送到小车上边,运动员就能直接拿到进行训练。 - 代码设计:整体来看不难,avr单片机控制4个电机运动从而控制小车的各种运动,pwm控制风机的风速、传送带电机速度、转盘运动,以及一些传感器的获取,与图像识别的交互及蓝牙模块命令的执行等。其实整体看大部分时间花费在外壳构造方面。 - 各种测试尝试:虽然现在的我看整体不难,但当时从零做起,就真的很有难度,不没有那么顺利,中间进行了很多次测试。对于能否用暴力风扇对通道吸风来吸羽毛球,通道的大小,风机的风力等,最后测试方案可行,选取合适的一些参数。当时也准备了4个暴力风扇,12v整体电流能到10A,风力贼大,结果测试1个风机全速能吸,保险些就用两个风机。对于构思调整羽毛球方向也想了很久,多种方式,最后我想到用传送带最合适,也简单,经过测试,找到合适的倾斜角度、合适的传送带面料,最后找外商定制了多个,才确定了材料、设计。还有球筒,原版的有些紧,自由落下会卡住,只能自己用塑料制作多个,在底部转盘也用了些机械设计。整体上我负责了整个的供电设计、电路设计,也参与了机械队友的机械设计,探讨更合适的机械结构。经过不断努力,做出了一代二代机,不过有些遗憾的是,图像识别的队友的退出导致图像方面无人研究,最后也就做出了能手机控制版本的。 - **创新点** : - 1.本项目运用摄像头捕获图像及图像处理技术配合超声波传感器和红外传感器,实现智能捡羽毛球机器对羽毛球位置和周围地形的感知,做出相应的动作。 - 2.本项目采用独特的吸风装置,利用风力和风向,实现羽毛球在收集通道的单向移动收集,极大减小对羽毛球的损伤,可以一次性收集多个羽毛球。 - 3.本项目利用倾斜传动带的粗糙表面,使羽毛球在其上能呈现统一的方向,方便后方圆筒的收集。 - **已有专利** : - 1. 一种羽毛球捡球装置(专利号:CN201821405394) - 2. 一种羽毛球捡球装置及其控制方法(专利号:CN201810998276) - **获奖** : 逐步升级改进设备 - 获得大创省级立项,完成了项目做出实物,申报了2项专利。 - 大创顺利结题,评为良好。 - 参加广大17级夏令营比赛获得校级三等奖。 - 参加广大第三届创客马拉松大赛获得校级一等奖 - 实物图: - ![输入图片说明](1%E3%80%81%E6%99%BA%E8%83%BD%E7%BE%BD%E6%AF%9B%E7%90%83%E6%8D%A1%E7%90%83%E6%9C%BA/%E5%AE%9E%E7%89%A9%E5%9B%BE.jpg) - 渲染图: - ![输入图片说明](1%E3%80%81%E6%99%BA%E8%83%BD%E7%BE%BD%E6%AF%9B%E7%90%83%E6%8D%A1%E7%90%83%E6%9C%BA/%E6%B8%B2%E6%9F%93%E5%9B%BE.jpg) ### 2. 七彩频谱旋转屏幕 - 这个项目是2018年4月参加的led显示屏大赛,那时是自己所在学院举办的活动,有了之前参加的比赛经验,那这次“自家”的比赛自然也不能错过了。于是拉上好友报名,最多三人为一个队伍参加。 - 比赛的主题是 led显示屏,需要带有频谱功能的。比赛的准备制作时间大概是一周多,那时我们还要上课,只能在课后抽取时间来制作了。当时我舍友(以前比赛队友)也有参加,另一个队伍,于是那周的宿舍,其他舍友在睡觉玩手机的时候,就只有我们在制作的写代码。因为我以前做过51单片机的旋转屏幕,那这次就用AVR单片机来制作个七彩的显示屏吧,炫酷一些。 - 构思设计过程:7彩led效果,使用RGB的led需要占用很多引脚,网上找了下,有ws2812灯带,内嵌有控制芯片,只需一个引脚即可通信控制七彩,而多颗ws2812可以串联,统一控制。然后主控就选寒假刚学习不久的atmega16单片机。频谱功能自然少不了mic来拾取声音,通过adc功能读取到单片机,经过fft得到各个频谱的量,根据量来控制彩灯效果。旋转屏幕呢就是将灯带圆盘旋转起来,利用人眼视觉暂留效果让人看到完整的圆形屏幕。需要电机驱动,利用底板的霍尔元件来判断固定位置,接下来就是写代码了。旋转屏幕的详情可以看“51单片机”的仓库:https://gitee.com/lsy_zhiyu/funny_51#4%E6%91%87%E6%91%87%E6%A3%92%E5%B9%B3%E9%9D%A2%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95 - 制作过程:根据ws2812来编写引脚控制逻辑,由于其控制的时序很严格,而且精度又比较高(0为0.4us高电平+0.85us低电平;1为0.85us高电平+0.4us低电平),这就导致我测试尝试了很多次,因为主控是使用外部8MHz晶振,理论代码执行的最小周期为0.125us,但c语言下,不一定都是最小的,测试后发现延时函数的最小单位实际花费时间都比us多,于是只能叠加引脚电平控制,将时间累计到通信时间(通信码之间切换的代码也花费时间),最终也实现了控制,编写了整个驱动代码,能控制16个七彩灯的多种特效。先完成任务再增加更多炫酷特效吧。mic使用普通的发现灵敏度不够,还好买了个10多元的mic,灵敏度挺好的,代码上用adc读取电平波动。那时还没接触过数字信号处理,查找原理才知道频谱是要傅里叶变换,公式也挺长,正常写速度运算太慢,最终找到了fft这个适合在单片机上运行的算法,找了网上的移植到avr单片机中,配置好对应的缓存数组,测试在串口打印出频谱各值,简单验证正常后,继续。旋转屏幕上使用霍尔元件+磁铁,让其感知固定位置来更新显示。 整体上由于驱动ws2812、fft、旋转屏幕驱动花费了很多时间,剩下时间就简单的在洞洞板焊接了。 - 代码逻辑:各个驱动的编写完毕之后,来组装了。初始化io、adc、fft、uart后,整体旋转每当检测到霍尔元件扫过之后,进行一次fft运算(试过显示每列的间隙来fft,但花费时间较多影响显示),然后将各个数值转化为灯带距离中心亮的个数,分为16个列进行显示,同时记录转动的圈数,累积一定圈数后,切换显示的特效:7种单色显示切换、16个灯七彩显示、以及最后实现的显示七彩英文字母“welcome”。 - 答辩现场:一等奖的七彩吉他,他们队(准确来说是他的队(1人))喜欢弹吉他,于是给吉他加上了这么炫酷的功能,答辩的时候直接弹了一曲,在吉他好听的情况下有七彩灯加持,帅气十足,赢得了大家的赞美,自然获得第一名。我的话,那时旋转屏幕还不多见,以及特效,显示字母、制作手工被师兄成为“极客”版的(因为全手工制作,连usb头都是自己焊接)获得了二等奖;三等奖是舍友的频谱“电视机”,他制作成小盒子的形状,七彩灯纵向排列,效果挺好的,外壳也算美观。(后来说是打算做完送给某个女生,咳咳,里边充电宝是我做的,也算助力他把);其他队伍作品一般,获得优秀奖。其实前三等奖的人都是我们班的,大家都挺厉害的。最后呢,答辩过后,大家在教室关灯,一起录制了七彩炫酷的led显示屏作品~ - 获奖: 参加led显示屏比赛获得院级二等奖 - 实物效果图: (由于录像的帧率跟led旋转屏幕对不上,所以gif会有断开的感觉,实际能显示全部) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/gif%E6%95%88%E6%9E%9C.gif) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E4%B8%83%E5%BD%A9.jpg) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E5%85%A8%E5%BD%A9.jpg) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E7%99%BD%E8%89%B2.jpg) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E7%B4%AB%E8%89%B2.jpg) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E7%BA%A2%E8%89%B2.jpg) - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E9%9D%92%E8%93%9D%E8%89%B2.jpg) - 一等奖同学的表演 - ![输入图片说明](2%E3%80%81%E4%B8%83%E5%BD%A9%E9%A2%91%E8%B0%B1%E6%97%8B%E8%BD%AC%E5%B1%8F%E5%B9%95(led%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%A4%A7%E8%B5%9B)/%E6%95%88%E6%9E%9C%E5%9B%BE%E7%89%87/%E4%B8%80%E7%AD%89%E5%A5%96%E7%9A%84.jpg) ### 3. 简易智能插座1: - 这个项目是我大二下学期来玩耍练习的,那时大概地自学了仿真、pcb画板,用雕刻机来制作电路板这些技能,也是体验一下全过程吧。打算自制个简单智能插座,来控制一些电器,方便我在宿舍用。先在proteus上进行仿真,验证代码没有问题后,再制作焊接实物测试的。整体是通过检测用电器的电压、电流来计算整体的功率、用电量,同时能够将数据显示出来,有ds1302保证时间的实时性,可以通过按键来设置计划时间,实现定时通断电、超功率断电保护等功能。 - 原理:使用atmega16单片机,用通信协议获得ds1302的实时时间,用扫描的方式驱动4位数码管的显示,引脚输入的方式接有5个按键,用于交互的。电压电流的测量呢,使用非接触安全的电压互感、电流互感元件,接上电阻用adc功能读取电压值,转化为对应的电压电流数值。控制通断电是使用继电器的。而整体的供电5v电压是通过变压器后整流稳压电路得到的。(当时其实可以用降压模块) - 制作过程:设计好后,在proteus中画电路进行仿真,但测交流电部分好像无法仿真,就直接制作实物了。根据事先了解的可行性,(当时电脑和AD软件有问题,库也打不开,就直接搞pcb了)通过仿真图当原理图,在pcb中用通孔,一个一个元件测量引脚间距,绘制出来的,而且走线也是对着电路图来画的,现在想起来确实辛苦。。。(后来立创EDA绘制就方便多了)绘制完成后生成生产文件,在实验室有台雕刻机来雕刻电路板的,请教了师兄,一步一步来操作设置,虽然中途经过2次电源插头被路过的同学不小心踢开,最后守在排插前看着及其完成电路板制作。买来了元件,一个一个焊接上去,检查焊接没问题后,烧录代码,测试各个部分功能,最后再用整体功能的。先完成数码管的控制显示,再按键、ds1302等,最后才是电压电流检测电路,这里买了个插座剪断,通过凤凰头拧上去的,也标注了市电,需要注意防触电。这个测量飘动有些大,我就在代码中增加了滤波、均值的代码,最后校准偏差后,比较准确了。最后测试降压电路,我那时还是有点慌的,怕触电,不过还好,一次性成功。完善代码后,就能显示电压电流时间计划,通过按键设置了,后续也找了个外壳装起来,确保使用安全。 - 实物图: - ![输入图片说明](3%E3%80%81%E7%AE%80%E6%98%93%E6%99%BA%E8%83%BD%E6%8F%92%E5%BA%A71/%E5%AE%9E%E7%89%A9.jpg) - 仿真电路图: - ![输入图片说明](3%E3%80%81%E7%AE%80%E6%98%93%E6%99%BA%E8%83%BD%E6%8F%92%E5%BA%A71/%E4%BB%BF%E7%9C%9F%E7%94%B5%E8%B7%AF%E5%9B%BE.jpg) - pcb图: - ![输入图片说明](3%E3%80%81%E7%AE%80%E6%98%93%E6%99%BA%E8%83%BD%E6%8F%92%E5%BA%A71/pcb%E5%9B%BE.jpg) ### 4. 简易数字时钟52: - 这个是大一寒假自学玩耍的,做了个简单的数字时钟。整体也不复杂,那时锻炼一下功能按键组合控制这些逻辑编程。 - 原理:通过扫描动态显示8位数码管的数值,通过内部的定时器中断走时,累计时间得到时分秒,显示在数码管固定位置上。通过输入引脚接的按键检测来获得按键信息,根据内部逻辑组合,来实现按键下对时间的重新修改,也增加了修改位的闪烁特效,各个位的数值修改限制范围等。整体能像个正常的简易电子表。 - 仿真图: - ![输入图片说明](4%E3%80%81%E7%AE%80%E6%98%93%E6%95%B0%E5%AD%97%E6%97%B6%E9%92%9F52/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 5. 简易交通灯53: - 这个也是大一寒假练习的,简单的交通灯,模拟交通灯的红绿灯和倒计时功能,15绿灯,5s黄灯,20s红灯切换,黄灯每一秒都响一下蜂鸣器。 - 原理:使用avr单片机的io高低电平控制:来控制数码管中led的亮灭,组成数字显示出来;控制三极管的通断,间接控制蜂鸣器这个大电流用电器的是否工作;通过io口控制3个led灯是否亮灭。使用定时器累计得到秒数,显示倒计时在数码管上,配合逻辑代码来实现整个功能。 - 仿真图: - ![输入图片说明](5%E3%80%81%E7%AE%80%E6%98%93%E4%BA%A4%E9%80%9A%E7%81%AF53/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 6. 打地鼠游戏54: - 这个也比较简单,闲来无事干就做了个打地鼠游戏,哪个led亮了就迅速点击其下边的按钮,在时间内点的话就能+1分,没点的话分数不变,闪烁下一个灯,点错的话就扣1分,当分数大于50分时,就恭喜你完成游戏,一切重新开始。打地鼠给你预留打的时间会随着分数增加而减小,来增加难度。 - 原理:就简单的利用单片机io口功能,2组io空控制2个数码管显示内容,一组控制led,一组用于按键输入。剩下的就看逻辑了。 - 设计过程:首先是完成数码管、led灯、按键的驱动。完成后,就跑个流水灯做个开机效果吧。然后等待用户按下任意按键,进入开始游戏,游戏中利用随机函数,然后对8取余,再根据数值控制对应led的亮灭,结果我发现rand()函数不是真正的随机函数,它呈现出一定的规律性,导致玩几下后,我都能预测下一个地鼠的位置了,体验不好。那如何做到随机呢?我想到了利用运行时间,每个人有快有慢,就能不同了,main的循环中累计个变量,通过它可以记录点击按键的间隔量,再对8取余就行啦。但是呢,当用户不点击就没有累计量了,导致一直同一个位置显示,那就叠加上一次结果吧,虽然也是呈现移动规律,好过没有。。。用户按对按键,就加1分,没按时间间隔到了就跳下一个led,按错就扣1分。那全程同一个时间间隔就没有难度挑战了,那就随着分数增大,需要的反应越快吧,也间接让不按按键时的led显示规律打乱(不同分数下随机规律不同,但停留在同一分数下还是相同的)。当分数达到50分时,就闪灯表示顺利通关。 - 其实漏洞也还有,比如利用不按不扣分的规则,找出亮灯规律,再看准点,这样就能很快过关。那时也暂时做到这,没继续优化了。 - 仿真图: - ![输入图片说明](6%E3%80%81%E6%89%93%E5%9C%B0%E9%BC%A0%E6%B8%B8%E6%88%8F54/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 7. 简单遥控小车: - 这个呢,当时玩耍,买了个小车,自己组装焊接电机,用刚自学过的avr单片机驱动,配合蓝牙模块做的蓝牙遥控小车,其实当时是对实物感兴趣,直接实物调试做出来的,后面有空才把仿真图补上,也能仿真。 - 设计过程:使用串口连接蓝牙,配置好就可以跟手机通信,直接发命令给单片机,解析后即可根据命令执行对应的动作。用定时器产生2路pwm波通过引脚硬件输出,接到电机驱动模块(l98n)的两个en脚,再通过各2个引脚来控制驱动模块,来决定两个电机的正反转、或是刹车。接着根据数据手册和实物调试,编写好小车前进、后退、左右转的动作函数。前后走就是电机都往同一个方向转,左右转弯是利用左右两侧电机的差速实现的,或是两侧电机方向相反转即可。那蓝牙指令控制什么呢?首先是整个小车的状态:前进、后退、左转、右转刹车。用手机的SPP软件可以配置按键,按下运动,抬起就刹车,用起来就很好。我也增加了左右轮的pwm占空比控制,可以通过指令增加减小对应的速度,也加了范围限制,防止数值超范围的异常。就这样调试好久能玩耍啦~ - 其实用1个pwm也可以,这里用2个是因为pwm相同,但实物误差下,小车不是走直线,需要软件校正。 - 仿真图: (实物当时忘记拍照了。。想象就好了) - ![输入图片说明](7%E3%80%81%E7%AE%80%E5%8D%95%E9%81%A5%E6%8E%A7%E5%B0%8F%E8%BD%A6/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 8. 点阵+方向键: - 这个是大一寒假练习的小项目,当时就是在自学数码管控制、点阵led控制、矩阵键盘控制等。就想到了用按键控制led点阵亮灯的移动,好像不难,就看逻辑代码了。 - 设计过程:使用avr的io口功能,跟多位数码管类似,使用动态扫描的方式,对点阵对应位置点亮led,不过这里只点亮1个led,那就不用扫描了,直接io口控制。通过几个独立按键检测输入,来执行对应的功能。代码里边对点阵的处理简化到一两行,包括了点阵移动到边缘能够从另一边出来的逻辑。一开始是按理解编写,实现功能后想着按精简代码行数来缩减代码,最后也就不到30行完成,其中的代码有些需要耐心去分析逻辑。 - 仿真图: - ![输入图片说明](8%E3%80%81%E7%82%B9%E9%98%B5+%E6%96%B9%E5%90%91%E9%94%AE/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 9. 控制192个舵机: - 这个小项目是之前创客协会,师兄授课后的小作业,当时讲了舵机控制等知识之后,布置了小作业:使用atmega16控制尽可能多的舵机,每个舵机能控制具体角度。那我就探索玩耍啦,最后搞了192个舵机,其实还能级联来控制更多的,但仿真起来有些卡了,就这样吧。最后呢,师兄说大家作业中我控制的是最多的 :joy: - 设计过程:首先控制单个舵机,需要pwm方波,其占空比根据手册来规定范围,这样就就能控制了。控制多个呢,就需要多路pwm信号了,那32个引脚,顶多控制32个,那就需要io扩展芯片了,这里使用573逻辑芯片,让其输出使能端由单片机1个引脚控制,那么8个引脚就可以控制8个舵机,而剩余的24个引脚可以控制24个573是否输出,这样就可以控制24*8=192个舵机了。思路就是这样,那舵机控制的信号就需要从普通引脚输出,在代码中我用定时器的匹配中断和溢出中断来操作,设置好整体信号周期,其实在仿真中可以小于20ms。到对应的中断中,就控制对应变量0/1切换,就可以让普通io控制舵机。为了体现能各个舵机单独控制,这里我就写了代码让每64个舵机都平均分配角度(-90~90°),分成3组,这样就可以很好的体现出来的。不过呢,由于是中断变量标记,而执行是在main中判断执行,所有会有时间误差,导致控制角度存在误差(测试发送的信号周期个数不能少于4个),当时好像在1°内吧,还算精确的。 - 那时还没学过编码译码器,从我现在积累的经验来看,可以加74LS138等译码器,扩展io数量,能控制更多的573使能端,这样一层下来的话就能从192个增加到512个。其他方法也有很多。如果只能单独使用573芯片的话,其实也可以让2组口控制2列573,剩余的16个引脚控制各个使能端,这样就能(8+8)*16=256个舵机了。也就达到最优分配了,可用高数计算最优分配方式。 - 仿真图: - ![输入图片说明](9%E3%80%81%E6%8E%A7%E5%88%B6192%E4%B8%AA%E8%88%B5%E6%9C%BA/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 10. ADC键盘: - 这个好像也是当时的小作业,就是利用adc功能用1个引脚实现很多个按键的判断输入。当时也是刚学adc不久,数码管控制也学会了,就尝试设计完成一下。 - 设计过程:使用adc功能来判断不同电压,那必定是通过电压的不同来区分的,这就需要按键与电阻进行组合,我设计打算使用正比关系的按键阻值,这样会比较好在程序判断,最后就如仿真图那样设计,按键按下让某部分电路短路,剩下的电路得到不同的电压值,而不同按键按下,对应的电阻值是10k的倍数,很好区分。而基地的电阻设为10k,按键靠近gnd的电压值最小,远离则慢慢增大,可大概计算出来的,分压的电压为5v。按键不按时为0v,有按键按的电压范围为2.5v~0.238v。然后用以前编写好的数码管驱动拿过来用,也就是用动态扫描的方式进行显示的。然后编写adc代码,根据atmega16的数据手册就可以慢慢写出来了,即配置好ADMUX、ADCSRA寄存器,使用单次触发的方式,写好对应的函数,在初始化之后,使用定时器1中断进行adc的读取和数码管的刷新显示。而adc对应按键的判断也使用了for循环对1024分成1~21份,对其附近符合的值即可判断为按键i-1,可直接显示出来,而误差值可以多次测量后进行调整。 - 仿真图: - ![输入图片说明](10%E3%80%81ADC%E9%94%AE%E7%9B%98/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 11. 密码锁: - 这个是冬令营的一个小作业,就是使用lcd1602显示、矩阵键盘作为输入的一个密码锁,规定使用外存、lcd1602等。我设计为具有按键输入密码的交互界面,能输入删除清除确认按键,3次机会输错则有显示缓冲尝试时间,输对则进入系统,可以选择显示总的开机时间、修改开机密码等功能,密码可小于6位的任意长度。 - 设计过程:首先需要写好lcd1602的驱动,这个师兄有教如何根据资料写通信协议,但说明了思路,代码还是需要自己编写的,一步一步来,写好控制类的和显示类的函数,供后续使用。然后需要矩阵键盘的读取,这里使用扫描的方式读取,也是根据我自己的分析理解写好的函数。还有24c02通信的驱动,都是根据数据手册写的。最后就组合起来的逻辑代码了。首先是开机各个功能模块的初始化,(很多字符串、时间都事先存储到24c02中,后续的字符串基本在24c02中读取)从24c02中读取出事先存进去的时间,提示输入密码,这里用数组来缓存一些输入的数据,按键数字则输入对应数字到缓存并显示出来,对应的删除清除按键也是对缓存操作并显示出来,当按下确认按键时,真正密码跟24c02中的对比,完全相同时才认为密码正确,否则尝试次数-1,尝试次数超过3次则显示倒计时30s,不对按键反馈。当过密码正确时进入欢迎界面,使用定时器1累计走时,并及时更新到24c02中。当按下修改密码按键时,需要用户输入旧密码,用的是同一个输入密码的函数,只有验证旧密码正确后才会更改为新输入的密码并存储到24c02,输入错误则返回到界面中。当按下显示使用时间按钮时,则将定时器1中累计的时间直接显示到1602上。利用取余来让显示界面持续4s左右,然后回到主界面。整体的逻辑可能复杂一些。 - 仿真图: - ![输入图片说明](11%E3%80%81%E5%AF%86%E7%A0%81%E9%94%81/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) ### 12. 冬令营大作业: - 这个是2018.3大一寒假的冬令营的大作业,冬令营中跟着师兄开课学习了一些基本知识,以及很多自己探索学习的各个模块的驱动代码编写,最后就布置了个大作业,用来检测之前学到的知识,以及以平时小作业和大作业的总分来评判是否合格入选卓越班成员。所以此刻的大作业当然要把所有学到的知识都用进去,有规定了主要的模块功能使用(128、16等单片机),具备的功能:密码锁、菜单栏、实时时钟、闹钟、温度、马达控制、舵机、两个从机、逻辑加分题等,时间好像是一个星期,提交仿真文件和代码及使用说明。当时我宿舍那队友也有参加,又是两个人奋斗一周,那个时间好像临近开学,我们寒假花了一段时间留校听课自学的。最后呢,有点出乎我的意料,以为自己做得一般,但公布时在优秀的名单里,自然进入了卓越班的名额。后续也通过夏令营比赛进入校级拔尖班成员。 #### **A、功能使用简介** : 1. 开机显示输入密码,初始密码为000000,由矩阵键盘输入,矩阵键盘支持输入密码过程中删除一位已输入密码,或者清空输入密码。密码输入有3次机会,都错误的话会锁住,显示倒计时30s后才能重新输入。显示剩余秒数。(键盘的改密码和使用时间是没设计使用的!) 2. 进入菜单功能: 所有的返回主菜单是 输入 home (在串口调试串口中输入) - 输入clock 进入时钟界面,显示了实时时间(ds1307) - 输入set time进入改时间界面,按提示输入即可,最后finish回到时钟界面- - 输入set alarm进入闹钟设置界面,按提示输入即可,最后finish回到时钟界面,闹钟为每天的 - 输入 home 返回主界面 - 输入 temperature进入温度曲线显示界面,还显示实时温度。 - 输入motor进入马达控制界面,按提示输入motor2+l 回车后就可以控制马达2的低速顺时针转, - 输入reset password进入修改密码界面,输入新密码即可 - 输入communicate with slave1可以控制从机1的舵机,再按提示输入+00.5或-66.6等即可控制,采用传送两位数据的方式,提高精确度,误差+-0.3 - 输入communicate with slave2,与5同理 - 输入logic进入逻辑题,输入10个数据,格式为-001+004+111等。按回车即可得到结果并显示出来,3s后回到子页面,可继续测 #### **B、整体电路接口简介** 主控是atmega128单片机,控制lcd12864进行显示内容,通过4*4矩阵键盘进行输入修改密码的交互,使用IIC接口访问24c02和ds1307,分别来存储非易失数据和获取实时时间,使用串口来进行整体各个功能模块控制交互,通过pwm和引脚连接2块l298n用来控制4个电机的状态,通过ds18b20来获取温度值,用一个io口控制led亮灭(蜂鸣器不响,用led代替)通过SPI接口与从机2通信间接控制舵机转动角度,通过另一个串口与从机1通信间接控制另一个舵机转动的角度。 #### **C、各功能设计简介** 1. 开机输入密码部分:使用的是密码锁项目的(第11点),以前的小作业整理完善代码,移植进来该系统 2. 串口中断中将接收到的命令缓存起来,当检测到删除字符时,也同样对缓存操作,当接收到换行符时,则使用函数与预设的命令进行匹配,匹配上了就做好标记,然后执行对应的功能,匹配不上就提示wrong。很多都封装好了函数,直接调用即可。也有限制一次输入命令的长度,防止指针越界而死机。 3. 时钟界面则读取ds1307时间然后显示在12864上,显示了年月日时分秒。设置时间、闹钟也跟着提示进行即可。输入温度则会读取ds18b20数据然后显示出来,并且会显示出对应的温度变化曲线,图像能整体移动,这个就涉及到12864的具体控制了,像素点的逻辑控制。进入控制电机界面,有4个电机可以控制,根据提示的命令格式即可控制任意电机的转速,这个是通过控制方向引脚和pwm占空比控制的。重新修改密码也是跟着提示来,舵机的话根据格式,可较精确控制,也是通过串口/SPI通信,然后从机收到命令数据转化为pwm占空比变化,控制舵机的。逻辑题是输入10个格式数据,然后在屏幕上打印出数组中出现的数字+每个数字出现的次数。 #### 最后 - 我当时到了快交大作业的时间时还在编写代码,主要是对当时的我来说,整体的功能代码量都很大,花费较多的时间,我也就急匆匆的交完作业,最后师兄说我是一两个完成所有任务的人,其他人基本都完成了部分功能而已。冬令营这段日子也学到了很多知识,虽然牺牲了大半的假期,但值得。 - 仿真图: - ![输入图片说明](12%E3%80%81%E5%86%AC%E4%BB%A4%E8%90%A5%E5%A4%A7%E4%BD%9C%E4%B8%9A/%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg) #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)