模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

48394查看 | 146回复

[单片机课堂] 第七课:扩展课!用掉你的单片机

  [复制链接]
发表于 2016-9-20 03:28:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 我爱萝丽爱萝丽 于 2016-9-23 02:19 编辑

如果你认真跟进学到第七课,你可以回头看看你都收获了什么?
学会了单片机焊接和下载;
学会了Keil编程软件的使用;
学会了C语言的基础语法,循环判断等基础语句;
学会了单片机引脚控制,输入输出;
学会了多种模式切换的程序写法;
学会了新型的按键检测方法;
学会了PWM控制亮度;
……
是不是突然感觉自己会了好多O(∩_∩)O~~


想要做到无基础的人快速入门单片机,首先就要抛弃那些深奥复杂的东西,直接说重点。很多教材上来就讲二进制、十进制、十六进制互相换算,左移右移等,掰着手指头数都绕晕,这里我可以负责的告诉你,只要会加减乘除四则运算,就可以学单片机!大部分情况用的都是十进制。


但是,只学了这些表层的知识是远远不够的,有很多单片机教材都声称“七天学会单片机”,如果真是这样,楼主也可以说“七课学会单片机”。然而实际上只是会背了乘法口诀,应用题还是不会做。
要想真正学会单片机,深入的做项目才是王道。在做项目的过程中,发现问题,解决问题,你才能真正进步。


所以我要提出一句话:“用掉你的单片机!”
这节课作为扩展课,就是要让你潜下心来,把第一个项目深入做好。这也是我的课程的特点:以实际项目为单位进行,而不是以不同知识为单位进行。


第七课:扩展课!用掉你的单片机 扩展课的英文 作者:我爱萝丽爱萝丽 5926

评分

参与人数 3牛币 +28 收起 理由
ludeku + 8 棒棒哒
低调 + 10 大神
飞天狼 + 10 老师辛苦啦,这么晚注意安全

查看全部评分

 楼主| 发表于 2016-9-23 02:17:32 | 显示全部楼层
1.1 联系实际,规划出一个有用的产品


跟做过就忘的单片机实验不同,我的目的是让你的学习历程中能够实际的做出一些东西,留下自豪的回忆,以后用单片机处理类似的问题也能快速应用。


你焊好了《七色光芒》,它能做什么?


第七课:扩展课!用掉你的单片机 扩展课的英文 作者:我爱萝丽爱萝丽 4750


最低要求:
大功率的灯珠有强烈的光芒,所以你至少可以做一个小手电筒;
色彩的控制,让你的手电筒与众不同,随时可以从白色光芒变成彩色,回头率瞬间+1;


中等要求:
不能调节亮度的手电不是好用的手电!


扩展要求:
为了能够引起远方人的注意力,你还需要爆闪模式!
模仿一下警车的闪烁模式,是不是更拉风?
还记不记得晚会上的彩色舞台灯,让你到哪都能嗨起来;
和女友浪漫时,打开彩色的呼吸灯功能,更加温馨……
……


RGB灯光控制器现在还没有普及,这对很多人来说仍然是个新奇的玩意儿,只要发挥你的想象,它还能做更多的事。
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-23 04:40:06 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-9-23 16:58 编辑

1.2 程序模块化思维


看到上面罗列的各种功能,是不是没有想到,原本以为只是是学了一个彩色流水灯,实际上却有那么多用途!
那你想不想把那些功能亲自都实现呢?
其实所有功能的程序,在前六课都已经教给你了,你缺的只是灵活的组合,熟练的运用。


我们在第五课学了控制多种色彩模式,第六课学了PWM控制亮度,把它们组合起来,就能实现一个中等要求的产品。


在我们的电路中,有两个按键,正好分配一下,一个切换模式,一个控制亮度。
那么组合三个功能的程序如何写呢?很多人简单的程序还能写,但复杂一点就懵逼,不是不会,是因为没有学到一套正确的程序思维:


知识点(36) 程序模块化
为了让程序思路更清晰、以后复制写好的程序更方便,你的程序需要模块化。
什么是模块化? 就是实现某个功能的程序尽可能的和其它程序独立,不要杂糅在一起。很多人一想到用按键控制色彩、亮度,自然而然的想到在按键程序里改变引脚、改变PWM等,这样做虽然也能实现,但3个程序被你杂糅成一个复杂的程序,不仅难以理解,改动也困难。


知识点(37) 消息传递机制
如果程序之间独立、模块化了,那怎么发生联系呢?你需要用“消息”喊话,把命令从一个程序传到另一个程序。
“消息”就是你定义的一个变量。比如你定义一个Key1_action,如果检测到按键,就把Key1_action=1,之后所有的程序都可以读一下Key1_action,读到1就知道按键情况了,而不必每个程序都来检测一下按键。




先来模块化两个程序练练手吧,再自己试试把PWM程序也加入

  1. #include<reg51.h>

  2. sbit LED_R=P3^4;//定义红灯
  3. sbit LED_G=P3^3;//定义绿灯
  4. sbit LED_B=P3^2;//定义蓝灯

  5. sbit Key1=P3^0;//定义按键1
  6. sbit Key2=P3^1;//定义按键2


  7. unsigned char Key1_old;    //定义一个数据,记录Key1过去出现低电平
  8. unsigned char Key1_action; //定义一个数据,传递Key1是否动作的消息
  9. unsigned char Key2_old;    //定义一个数据,记录Key2过去出现低电平
  10. unsigned char Key2_action; //定义一个数据,传递Key2是否动作的消息

  11. unsigned char mode;        //定义一个数据,代表不同模式
  12. unsigned char light;       //定义一个数据,代表亮度等级

  13. unsigned char time;        //定义一个数据,记录时间

  14. unsigned char count;       //定义一个数据,PWM循环次数
  15. unsigned char duty_R;      //定义一个数据,传递红色亮度占空比
  16. unsigned char duty_G;      //定义一个数据,传递绿色亮度占空比
  17. unsigned char duty_B;      //定义一个数据,传递蓝色亮度占空比



  18. void Delay1ms()                //@12.000MHz
  19. {
  20.         unsigned char i, j;

  21.         i = 12;
  22.         j = 169;
  23.         do
  24.         {
  25.                 while (--j);
  26.         } while (--i);
  27. }

  28. void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
  29. {
  30.         while(n)         
  31.         {
  32.                 Delay1ms();
  33.                 n=n-1;//每循环一次n减小1
  34.         }   
  35. }


  36. main()
  37. {

  38.         Key1_old=1;   //进入循环前,先初始化标志位。按键还没按下,old是高电平
  39.         Key2_old=1;
  40.         
  41.         while(1)   
  42.         {
  43.                 delay_n_ms(1);   //系统周期,每循环一次1ms
  44.                
  45.                 time=time+1;  //1ms计数
  46.                 if(time>9)    //time加到10ms,从0开始,每10ms检测一次按键
  47.                 {
  48.                         time=0;   
  49.                         
  50.                         if(Key1==1)
  51.                         {
  52.                                 if(Key1_old==0) //如果本次是高电平,上次是低电平,检测到按键
  53.                                 {
  54.                                         Key1_action=1;                                                                        
  55.                                 }
  56.                         }
  57.                         
  58.                         Key1_old=Key1;     //保存高低电平


  59.                         if(Key2==1)
  60.                         {
  61.                                 if(Key2_old==0) //如果本次是高电平,上次是低电平,检测到按键
  62.                                 {
  63.                                         Key2_action=1;                                                                        
  64.                                 }
  65.                         }
  66.                         
  67.                         Key2_old=Key2;     //保存高低电平
  68.                 }
  69.                                 
  70.                 //上面是完全模块化的按键检测程序,只传递出两个action消息
  71.                 ////////////////////////////////////////////
  72.                
  73.                 if(Key1_action==1)  //有按键消息,处理按键功能
  74.                 {
  75.                         Key1_action=0;   //处理过按键后要清0
  76.                         
  77.                         mode++;
  78.                         if(mode>6)        //按键1调节七种色彩
  79.                         {
  80.                                 mode=0;
  81.                         }
  82.                 }
  83.                
  84.                 if(Key2_action==1)  //有按键消息,处理按键功能
  85.                 {
  86.                         Key2_action=0;   //处理过按键后要清0
  87.                         
  88.                         light++;
  89.                         if(light>10)      //按键2控制10级亮度
  90.                         {
  91.                                 light=0;
  92.                         }
  93.                 }
  94.                
  95.                 //上面是模块化的按键执行程序,只传递出mode模式、light亮度两个消息
  96.                 ////////////////////////////////////////////
  97.                
  98.                 if(mode==0)       //模式0红色
  99.                 {
  100.                         duty_R=light;   //红色占空比=亮度
  101.                         duty_G=0;       //绿色、蓝色占空比为0,熄灭,只有红色亮
  102.                         duty_B=0;
  103.                 }
  104.                 if(mode==1)   //模式1橙色
  105.                 {
  106.                         duty_R=light;
  107.                         duty_G=light;
  108.                         duty_B=0;
  109.                 }
  110.                 if(mode==2)   //模式2绿色
  111.                 {
  112.                         duty_R=0;
  113.                         duty_G=light;
  114.                         duty_B=0;
  115.                 }
  116.                 if(mode==3)   //模式3青色
  117.                 {
  118.                         duty_R=0;
  119.                         duty_G=light;
  120.                         duty_B=light;
  121.                 }
  122.                 if(mode==4)   //模式4蓝色
  123.                 {
  124.                         duty_R=0;
  125.                         duty_G=0;
  126.                         duty_B=light;
  127.                 }
  128.                 if(mode==5)   //模式5紫色
  129.                 {
  130.                         duty_R=light;
  131.                         duty_G=0;
  132.                         duty_B=light;
  133.                 }
  134.                 if(mode==6)   //模式6白色
  135.                 {
  136.                         duty_R=light;
  137.                         duty_G=light;
  138.                         duty_B=light;
  139.                 }
  140.                

  141.                 //经过mode模式程序的处理,只剩下三个消息:每个LED的duty占空比
  142.                 //最后只需要按照duty改变PWM,就能实现亮度和色彩控制了
  143.                 //这样看起来,程序的思路是不是非常清晰?

  144.                 //你的发挥时间到了,自己在下面添加一个PWM程序,不然按键不能控制灯光
  145.                
  146.                 //………………
  147.                 //………………
  148.                
  149.                
  150.         }
  151.         
  152. }
复制代码


回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-27 01:27:42 | 显示全部楼层
1.3 添加PWM程序


上一小节中,留了一个小坑让大家自己填。要求实现的功能是:用每个LED的占空比独立的控制三种颜色的亮度。


一共有三位童鞋提交了自己的答案:


第一位:只能亮白色或熄灭,达不到要求;
第二位:能够实现控制亮度、颜色的目的,但逻辑不清晰,引脚只能是0或1,将0~10的duty值赋给引脚没有意义;
第三位:能够实现要求。
为什么要使用三个PWM?独立控制每个LED亮度才能实现更多的色彩,方便接下来更复杂的程序编写。

  1. count=count+1;   //每过1ms计数+1
  2.                 if(count>9)      
  3.                 {
  4.                         count=0;       //计数大于9后又变成0!,0~9十毫秒PWM周期
  5.                 }

  6.                 if(duty_R>count)   //在count 0~9变化中,duty大于count的次数就是占空比
  7.                 {
  8.                         LED_R=1;       //改变duty改变高电平时间,亮度变化
  9.                 }
  10.                 else
  11.                 {
  12.                         LED_R=0;
  13.                 }
  14.                
  15.                 if(duty_G>count)   //绿色LED PWM
  16.                 {
  17.                         LED_G=1;      
  18.                 }
  19.                 else
  20.                 {
  21.                         LED_G=0;
  22.                 }
  23.                
  24.                 if(duty_B>count)   //蓝色LED PWM
  25.                 {
  26.                         LED_B=1;      
  27.                 }
  28.                 else
  29.                 {
  30.                         LED_B=0;
  31.                 }
复制代码


点评

复制PWM程序的时候粘贴到了主程序外面,导致编译时报错,折腾了好久,最后回过头看前面的注解才恍然大悟。  发表于 2017-2-10 22:37
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-27 02:33:37 | 显示全部楼层
1.4 更多模式怎么加


首先你应该注意到,无论什么模式,都是有它的周期性的。
举例说最简单的爆闪模式:亮半秒灭半秒,两个状态不断循环;
双闪模式:亮半秒、灭半秒、亮半秒、灭三秒,四种状态循环;
七色舞台灯的模式:每种颜色亮1秒,7个状态不断循环;
……


举例程序如何实现爆闪模式,学到以后你可以试试自己实现其他功能。


循环程序必定有有一个数据计算时间,所以你要先定义一个数据:
unsigned int delay_time;   //定义一个数据,记录时间
注意数据大于255时,必须使用unsigned int


增加了模式7,所以按键改变模式的最大值也要相应更改。
添加模式7的代码:
更多更复杂的模式程序,就要看每个人的能力自己深入练习了。第一个项目的学习算是结束。
  1. if(mode==7)   //模式7 爆闪
  2.                 {
  3.                         delay_time=delay_time+1;
  4.                         if(delay_time>1000)  //爆闪周期1000ms
  5.                         {
  6.                                 delay_time=0;
  7.                         }
  8.                        
  9.                         if(delay_time<400)   //前0.4秒全亮
  10.                         {
  11.                                 duty_R=10;
  12.                           duty_G=10;
  13.                           duty_B=10;
  14.                         }
  15.                         else                 //后0.6秒熄灭
  16.                         {
  17.                                 duty_R=0;
  18.                           duty_G=0;
  19.                           duty_B=0;
  20.                         }
  21.                 }
复制代码


点评

unsigned int delay_time; //定义一个数据,记录时间 在头文件后加入这一行就可以了,看来遇到问题时再仔细看教程比自己瞎琢磨有效。  发表于 2017-2-10 22:56
把这段程序加到模式6后面,并把"if(mode>6)"改成">7"后还是报错。百思不得其解。  发表于 2017-2-10 22:51
回复 支持 1 反对 1

使用道具 举报

发表于 2022-4-7 13:54:17 | 显示全部楼层
第七课已学完
回复 支持 1 反对 0

使用道具 举报

发表于 2022-4-5 08:16:17 | 显示全部楼层
学习继续中
回复 支持 1 反对 0

使用道具 举报

发表于 2020-12-30 10:49:44 | 显示全部楼层
支持支持第七课:扩展课!用掉你的单片机 扩展课的英文 作者:htlkj2020 8190 第七课:扩展课!用掉你的单片机 扩展课的英文 作者:htlkj2020 4554 第七课:扩展课!用掉你的单片机 扩展课的英文 作者:htlkj2020 1690 {:1_13:}{:1_13:}{:1_13:}{:1_13:}
回复 支持 0 反对 1

使用道具 举报

发表于 2020-10-9 07:35:06 来自手机 | 显示全部楼层
回复 支持 1 反对 0

使用道具 举报

发表于 2020-7-23 13:21:01 | 显示全部楼层
帮顶 萝丽的三代控成功DIY 回头传图给萝丽大大
回复 支持 0 反对 1

使用道具 举报

发表于 2020-1-11 21:31:30 | 显示全部楼层
好教程,谢谢萝莉。慢慢学
回复 支持 1 反对 0

使用道具 举报

发表于 2017-3-11 17:11:55 | 显示全部楼层
好好好非常好
回复 支持 0 反对 1

使用道具 举报

发表于 2017-3-11 08:27:15 | 显示全部楼层
谢谢,学习学习!
回复 支持 1 反对 0

使用道具 举报

发表于 2017-2-18 21:59:33 | 显示全部楼层

定。。。。。。
回复 支持 1 反对 0

使用道具 举报

发表于 2016-9-20 06:53:50 | 显示全部楼层
第七课:扩展课!用掉你的单片机 扩展课的英文 作者:纳尼help 9308 第一次这么近
发表于 2016-9-20 07:30:14 | 显示全部楼层
路过帮顶
发表于 2016-9-20 08:33:36 | 显示全部楼层
第一次排名靠前,顶一下。
发表于 2016-9-20 08:50:52 | 显示全部楼层
支持支持
发表于 2016-9-20 09:01:57 | 显示全部楼层
哇哇哇,不错,说得对!
发表于 2016-9-20 09:19:49 | 显示全部楼层
学习一下
发表于 2016-9-20 10:00:46 | 显示全部楼层
ding
发表于 2016-9-20 10:08:03 | 显示全部楼层
再回头看一遍去
发表于 2016-9-20 10:25:10 | 显示全部楼层
看看


发表于 2016-9-20 11:22:03 来自手机 | 显示全部楼层
楼主说的非常有道理  前6课所学的知识点已经可以做  台灯  手电  或者电机调速  这些都是DIY
比较常见的项目  也非常实用的小玩意
发表于 2016-9-20 11:36:36 | 显示全部楼层
顶起         
发表于 2016-9-20 12:15:15 | 显示全部楼层
顶起来……
发表于 2016-9-20 13:15:51 | 显示全部楼层
用掉你的单片机
发表于 2016-9-20 15:04:53 | 显示全部楼层
我爱学习
发表于 2016-9-20 18:10:11 | 显示全部楼层
“七课学会单片机”.......绝了!
发表于 2016-9-20 19:44:17 | 显示全部楼层
一切跟着老师走。。。
发表于 2016-9-21 00:21:59 | 显示全部楼层
牛掰,简单易懂,已经从一到7课浏览了一遍,等单片机买回来再一步步详细看
发表于 2016-9-21 02:10:33 | 显示全部楼层
等待更新中。。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|关于模吧|APP下载|广告报价|小黑屋|手机版|企业会员|商城入驻|联系我们|模吧 ( 冀公网安备13080502000084号 )

© 2013-2020 Moz8.com 模吧,玩出精彩!