模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

45836查看 | 149回复

[单片机课堂] 第五课:进军!神奇的程序世界

  [复制链接]
发表于 2016-9-6 17:37:51 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 我爱萝丽爱萝丽 于 2016-9-13 01:20 编辑

几天开课后,发现一些问题,,想法也有改变。既然开课,就希望能做成一套成功的课程,几年后能够传为经典的课程,所以课程需要更加系统化。
现在已经调整第一个项目为《七色光芒》,前四课均已重新编辑!


从第五课开始,将真正开启程序世界的大门!


本课主要内容:学习程序的流程、调用等。

评分

参与人数 1牛币 +1 收起 理由
mimiCP + 1 很给力!

查看全部评分

 楼主| 发表于 2016-9-13 02:46:16 | 显示全部楼层
1.1 循环控制


在上一课中我们使用STC软件自动生成了一个延时1秒的函数,如果以后需要延时2秒、延时半秒呢,要是每次都生成一个这个的函数,那将不可想象。
幸好有一个巧妙的办法:函数调用。
如果我们有一个延时1ms的函数,执行1000次不就是1秒了么,执行500次不就是半秒?多么机智的想法。



调用一个函数两次,我们可以写两行,调用三次,可以写三行,那调用1000次呢……
幸好有“while”。在我们的主函数中,所有的程序都在一个无限循环的while(1)里,其实它循环的次数是可以控制的。



知识点(15) while(?)循环
while(?){} 当?的值是“真”的,括号里的程序会一直执行;当?的值是“假”的,括号里的程序程序不再执行。
什么是真?大于0的数都是真的,1是真,1000也是真。什么是假?0就是假。
如果我们想要循环1000次,可以while(1000),循环一次,变成while(999)……到最后,变成while(0),自然循环就停止了。


知识点(16) unsigned int n; 变量定义
想要一个数从1000减到0,就先要定义这个数。
unsigned int   定义变量的关键字,意思是定义一个数,范围是0到65535。
unsigned int n;定义了n这个数。n只是一个名字,你也可以写成abc等都可以。


知识点(17) 1000次循环的程序实例
n=1000;
while(n)
{
    //被循环的程序
    n=n-1;//每循环一次n减小1
}


把前面所讲的组合起来,自己写一个函数吧!


知识点(18) 定义延时n毫秒函数实例
void delay_n_ms(unsigned int n)//括号里面有值代表有参数的函数,在调用这个函数时,可以顺便写n的大小。
{
    while(n)           //注意什么地方有分号,什么地方没分号
    {
        Delay1ms();
        n=n-1;//每循环一次n减小1
    }   
}


知识点(19) 调用带参数的函数
delay_n_ms(1000);    //在调用时,1000这个值就传递给了n


有了能随意控制延时时间的函数,就能让彩灯变化更加灵活,写一个每种色彩亮0.1秒,白色亮1秒的程序吧!
是不是绚丽多了?你还能想到别的变化组合吗?

  1. #include<reg51.h>


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


  5. void Delay1ms()                //@12.000MHz
  6. {
  7.         unsigned char i, j;

  8.         i = 12;
  9.         j = 169;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14. }

  15. void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
  16. {
  17.         while(n)         
  18.         {
  19.                 Delay1ms();
  20.                 n=n-1;//每循环一次n减小1
  21.         }   
  22. }


  23. main()
  24. {
  25.         
  26.         while(1)
  27.         {
  28.                 LED_R=1;
  29.                 LED_G=0;
  30.                 LED_B=0;
  31.                 delay_n_ms(100);//红色亮0.1秒
  32.                                                                         
  33.                 LED_R=1;
  34.                 LED_G=1;
  35.                 LED_B=0;
  36.                 delay_n_ms(100);//黄色亮0.1秒
  37.                
  38.                 LED_R=0;
  39.                 LED_G=1;
  40.                 LED_B=0;
  41.                 delay_n_ms(100);//绿色亮0.1秒
  42.                
  43.                 LED_R=0;
  44.                 LED_G=1;
  45.                 LED_B=1;
  46.                 delay_n_ms(100);//青色亮0.1秒
  47.                
  48.                 LED_R=0;
  49.                 LED_G=0;
  50.                 LED_B=1;
  51.                 delay_n_ms(100);//蓝色亮0.1秒
  52.                
  53.                 LED_R=1;
  54.                 LED_G=0;
  55.                 LED_B=1;
  56.                 delay_n_ms(100);//紫色亮0.1秒
  57.                
  58.                 LED_R=1;
  59.                 LED_G=1;
  60.                 LED_B=1;
  61.                 delay_n_ms(1000);//白色亮1.0秒
  62.         }
  63.         
  64. }
复制代码


回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-15 13:29:21 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-11-9 04:35 编辑

1.2 按键输入

单片机的三要素是什么?我认为是输入、处理、输出。上一节已经学了简单的处理和输出,这一节再学一下输入你就可以毕业啦 ≧▽≦

单片机最普遍的输入就是按键。

知识点(20) 按键的工作原理:
单片机引脚设置为高电平,通过按键接到地。
按键没有按下:单片机引脚还是高电平;
按键被按下:单片机引脚接地,变成低电平。程序读一下引脚电平就可以知道有没有按下。

知识点(21) 为什么通常按键接地
单片机的引脚在默认模式下,引脚内部是串联一个电阻接到正极的,当你的按键导通时,电流很小,不会有什么影响。
但是单片机的低电平是没有串联电阻的,如果你用按键连到正极,相当于将正反短路,可能会损坏引脚。


程序如何读引脚的状态?同样,要想先读引脚,也要先定义才能用,在我们焊接的电路中,一个按键接在P3.0引脚上:
sbit Key1=P3^0;
定义之后,不进可以控制,还可以读。

知识点(22) if判断语句
if(?){ 1 } 如果?是真的,执行括号1里面的程序
else{ 2 } 否则就执行2里面的程序


单片机有哪些语句?循环和判断,无非就这两种,所有复杂的程序都是这两个组合起来的。

现在你已经都学了,是不是感觉单片机其实也没那么复杂?

知识点(23) =和==
等于 和 是否等于。
单片机语言中,有两种等于号,这点务必分清。
n=1000; n等于1000,是向n写入1000
n==1000; n是否等于1000?是对n进行判断。

知识点(24) 判断引脚状态的程序实例
if(Key1==0)  //如果按键按下,引脚读到低电平
{
    LED_R=1;
    LED_G=0;
    LED_B=0;  //亮红灯
}
else
{
    LED_R=0;
    LED_G=1;
    LED_B=0;  //否则亮绿灯
}

赶快写程序试一下吧。


  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;//定义按键


  6. void Delay1ms()                //@12.000MHz
  7. {
  8.         unsigned char i, j;

  9.         i = 12;
  10.         j = 169;
  11.         do
  12.         {
  13.                 while (--j);
  14.         } while (--i);
  15. }

  16. void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
  17. {
  18.         while(n)         
  19.         {
  20.                 Delay1ms();
  21.                 n=n-1;//每循环一次n减小1
  22.         }   
  23. }


  24. main()
  25. {
  26.         
  27.         while(1)
  28.         {
  29.                
  30.                 if(Key1==0)  //如果按键按下,引脚读到低电平
  31.                 {
  32.                                 LED_R=1;
  33.                                 LED_G=0;
  34.                                 LED_B=0;  //亮红灯
  35.                 }
  36.                 else
  37.                 {
  38.                                 LED_R=0;
  39.                                 LED_G=1;
  40.                                 LED_B=0;  //否则亮绿灯
  41.                 }
  42.                
  43.                 delay_n_ms(100);//延时0.1秒 程序每秒检测10次按键

  44.         }
  45.         
  46. }
复制代码



回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2016-9-17 14:01:37 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-9-18 02:34 编辑

1.3 多种模式切换


前面学习的按键检测只能简单的切换两种状态,如果想要通过按键改变七种色彩该怎么做呢?


通常一般的单片机教材在讲按键检测时,都会教你用delay延时等待按键弹起、等待按键稳定……我不会这样给你讲。这样有什么问题吗?
我的导师在喝酒时都会大骂教材中的各种错误,“等待按键弹起?按键坏了弹不起来怎么办?程序死机??!”
而在我看来,教材中的各种错误,影响远不止这么点。很多学生学了delay检测按键,一辈子都只会用delay,容易养成错误的程序思维,走向歧途,缺乏对单片机的“时间片”的概念,日后难以写出复杂、实时性的程序。所以,我要在一开始,就把“时间片”的概念深印在你心中。


知识点(25) 单片机的运行与“时间片”
首先要知道,单片机能干什么?我们的电脑CPU实际上也可以看成是一个速度超快的单片机,它能一边挂QQ、一边看网页、一边打游戏,它是不是可以同时处理很多任务?NO,事实上,单片机同一时间,只能做一件事,CPU只是聪明的划分出了很多很小的“时间片”,一个很短的时间内,只执行QQ,另一个很短的时间内,只执行游戏,一秒钟内“时间片”切换几十次,看起来就像是同时在做多种事了。这种方式是单片机最正确的处理方式,以后在考虑程序时,先从时间片角度出发!




我们现在的任务很简单,检测按键,然后改变颜色,现在还用不到时间片这么高大上的东西,但对检测周期还要有一个概念:人类按一次按键大概需要0.3秒,我们大概每0.15秒检测一下按键就能满足需要。


知识点(26) 如何区分多种状态
我们的七色光芒有七种颜色,如果算上熄灭,至少有8种状态,怎么用程序对应8种状态呢?
你需要先定义一个数据:比如mode;如果mode等于0,代表熄灭,mode等于1,代表红色……mode不同的值就能代表不同状态。


知识点(27) unsigned char mode;
unsigned char 是定义数据的关键字,代表定义一个大小是0~255的数。255种模式,够用了吧。


知识点(28) 全局变量
我们定义的mode在整个程序中都会用到,所以需要定义在程序开头,它就叫做全局变量。
定义在程序开头的变量默认都是0。



想到怎么做了吗?我们每检测一次按键,就改变一下mode的值,指示颜色改变了,再用if判断不同的值显示不同颜色不就可以了么?
本课的主要内容就是这些了,更多精彩下一课再见
  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;//定义按键



  6. unsigned char mode; //定义一个数据,指示不同状态。定义后mode的值是0


  7. void Delay1ms()                //@12.000MHz
  8. {
  9.         unsigned char i, j;

  10.         i = 12;
  11.         j = 169;
  12.         do
  13.         {
  14.                 while (--j);
  15.         } while (--i);
  16. }

  17. void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
  18. {
  19.         while(n)         
  20.         {
  21.                 Delay1ms();
  22.                 n=n-1;//每循环一次n减小1
  23.         }   
  24. }


  25. main()
  26. {
  27.         
  28.         while(1)
  29.         {
  30.                
  31.                 if(Key1==0)  //如果按键按下,引脚读到低电平
  32.                 {
  33.                         mode=mode+1;  //每按一次按键,颜色模式改变
  34.                         if(mode>7)
  35.                         {
  36.                                 mode=0;     //七种颜色切换完,回到0重新开始
  37.                         }
  38.                 }               
  39.                
  40.                 if(mode==0)                //模式0,熄灭
  41.                 {
  42.                                 LED_R=0;
  43.                                 LED_G=0;
  44.                                 LED_B=0;  
  45.                 }             //没有else可以不写
  46.                
  47.                 if(mode==1)  //模式1,红色
  48.                 {
  49.                                 LED_R=1;
  50.                                 LED_G=0;
  51.                                 LED_B=0;
  52.                 }
  53.                
  54.                 if(mode==2)  //模式2,黄色
  55.                 {
  56.                                 LED_R=1;
  57.                                 LED_G=1;
  58.                                 LED_B=0;
  59.                 }
  60.                
  61.                 if(mode==3)  //模式3,绿色
  62.                 {
  63.                                 LED_R=0;
  64.                                 LED_G=1;
  65.                                 LED_B=0;
  66.                 }
  67.                
  68.                 if(mode==4)  //模式4,青色
  69.                 {
  70.                                 LED_R=0;
  71.                                 LED_G=1;
  72.                                 LED_B=1;
  73.                 }
  74.                
  75.                 if(mode==5)  //模式5,蓝色
  76.                 {
  77.                                 LED_R=0;
  78.                                 LED_G=0;
  79.                                 LED_B=1;
  80.                 }
  81.                
  82.                 if(mode==6)  //模式6,紫色
  83.                 {
  84.                                 LED_R=1;
  85.                                 LED_G=0;
  86.                                 LED_B=1;
  87.                 }
  88.                
  89.                 if(mode==7)  //模式7,白色
  90.                 {
  91.                                 LED_R=1;
  92.                                 LED_G=1;
  93.                                 LED_B=1;
  94.                 }
  95.                
  96.                 delay_n_ms(150);//程序每0.15秒检测一次按键

  97.         }
  98.         
  99. }
复制代码



回复 支持 1 反对 0

使用道具 举报

发表于 2018-7-30 23:49:21 | 显示全部楼层
楼主void Delay1ms()                //@12.000MHz
{
        unsigned char i, j;

        i = 12;
        j = 169;
        do
        {
                while (--j);
        } while (--i);
}
这句代码是什么意思
回复 支持 0 反对 1

使用道具 举报

发表于 2018-6-23 04:21:38 | 显示全部楼层
向楼主致敬,学单片机编程
回复 支持 1 反对 0

使用道具 举报

发表于 2018-6-15 06:42:40 | 显示全部楼层

顶一个,争取学会单片机。
回复 支持 0 反对 1

使用道具 举报

发表于 2018-6-3 10:41:43 | 显示全部楼层
延伸的学习情况 都帮初学者考虑了 真的是太nice了
回复 支持 0 反对 1

使用道具 举报

发表于 2018-5-21 16:22:11 | 显示全部楼层
这次系统的学习
回复 支持 1 反对 0

使用道具 举报

发表于 2018-2-27 23:14:31 | 显示全部楼层
没学过编程感觉云里雾里的。感谢楼主,细致的讲解。
回复 支持 0 反对 1

使用道具 举报

发表于 2018-2-5 17:28:54 | 显示全部楼层

赞赞赞一个先 。
回复 支持 1 反对 0

使用道具 举报

发表于 2017-10-27 13:18:35 | 显示全部楼层
支持支持, 楼主辛苦了
回复 支持 0 反对 1

使用道具 举报

发表于 2017-9-14 12:14:10 | 显示全部楼层

666666666666666666666
回复 支持 1 反对 0

使用道具 举报

发表于 2017-9-14 12:13:47 | 显示全部楼层

6666666666666666
回复 支持 0 反对 1

使用道具 举报

发表于 2016-9-6 17:46:48 | 显示全部楼层
我是沙发不?第一次沙发 爽啊哈哈。
发表于 2016-9-6 17:55:41 | 显示全部楼层
板凳站位~~
发表于 2016-9-6 17:57:10 | 显示全部楼层
坐地板听课
发表于 2016-9-6 18:05:53 | 显示全部楼层
顶起来
发表于 2016-9-6 18:06:15 | 显示全部楼层
第一次这么考前
发表于 2016-9-6 18:41:25 | 显示全部楼层
顶一个,争取学会单片机。
发表于 2016-9-6 18:44:13 | 显示全部楼层
顶一个
发表于 2016-9-6 19:56:43 | 显示全部楼层
强烈建议楼主出套件!!!!!!!
可以有多个版本供大伙选择!!!!

点评

多个版本指什么  详情 回复 发表于 2016-9-7 11:29
发表于 2016-9-6 20:20:53 | 显示全部楼层
支持萝莉老大,萝莉做东西想的就是十分周到 支持 支持强烈支持 老大下次做简易遥控器的时候 能加进去遥控或接受能检测动力电池电压 低压报警的功能吗?希望做进去并教给我们源码 谢谢

点评

简易控是单向的,没有回传  详情 回复 发表于 2016-9-7 11:37
发表于 2016-9-6 20:31:44 | 显示全部楼层
顶                                         
发表于 2016-9-6 20:41:48 | 显示全部楼层
加油顶
发表于 2016-9-6 21:21:35 | 显示全部楼层

板凳站位,
板凳站位
发表于 2016-9-6 22:17:37 来自手机 | 显示全部楼层
哈哈,支持,期待更新
发表于 2016-9-7 08:44:58 | 显示全部楼层
学习一下,出个套装,大家买着方便
发表于 2016-9-7 09:42:04 | 显示全部楼层
支持老大,我都保存好了,以后答应出来方便翻阅。
发表于 2016-9-7 11:23:38 | 显示全部楼层
好,这样更一步一步学习,
 楼主| 发表于 2016-9-7 11:29:09 | 显示全部楼层
hmilycheng 发表于 2016-9-6 19:56
强烈建议楼主出套件!!!!!!!
可以有多个版本供大伙选择!!!!

多个版本指什么
 楼主| 发表于 2016-9-7 11:37:55 | 显示全部楼层
郝峰 发表于 2016-9-6 20:20
支持萝莉老大,萝莉做东西想的就是十分周到 支持 支持强烈支持 老大下次做简易遥控器的时候 能加进去遥控或 ...

简易控是单向的,没有回传
发表于 2016-9-7 12:07:14 来自手机 | 显示全部楼层
大哥想得周到
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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