第五课:进军!神奇的程序世界
本帖最后由 我爱萝丽爱萝丽 于 2016-9-13 01:20 编辑几天开课后,发现一些问题,,想法也有改变。既然开课,就希望能做成一套成功的课程,几年后能够传为经典的课程,所以课程需要更加系统化。
现在已经调整第一个项目为《七色光芒》,前四课均已重新编辑!
从第五课开始,将真正开启程序世界的大门!
本课主要内容:学习程序的流程、调用等。
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秒的程序吧!
是不是绚丽多了?你还能想到别的变化组合吗?
#include<reg51.h>
sbit LED_R=P3^4;//定义红灯
sbit LED_G=P3^3;//定义绿灯
sbit LED_B=P3^2;//定义蓝灯
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
{
while(n)
{
Delay1ms();
n=n-1;//每循环一次n减小1
}
}
main()
{
while(1)
{
LED_R=1;
LED_G=0;
LED_B=0;
delay_n_ms(100);//红色亮0.1秒
LED_R=1;
LED_G=1;
LED_B=0;
delay_n_ms(100);//黄色亮0.1秒
LED_R=0;
LED_G=1;
LED_B=0;
delay_n_ms(100);//绿色亮0.1秒
LED_R=0;
LED_G=1;
LED_B=1;
delay_n_ms(100);//青色亮0.1秒
LED_R=0;
LED_G=0;
LED_B=1;
delay_n_ms(100);//蓝色亮0.1秒
LED_R=1;
LED_G=0;
LED_B=1;
delay_n_ms(100);//紫色亮0.1秒
LED_R=1;
LED_G=1;
LED_B=1;
delay_n_ms(1000);//白色亮1.0秒
}
}
本帖最后由 我爱萝丽爱萝丽 于 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;//否则亮绿灯
}
赶快写程序试一下吧。
#include<reg51.h>
sbit LED_R=P3^4;//定义红灯
sbit LED_G=P3^3;//定义绿灯
sbit LED_B=P3^2;//定义蓝灯
sbit Key1=P3^0;//定义按键
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
{
while(n)
{
Delay1ms();
n=n-1;//每循环一次n减小1
}
}
main()
{
while(1)
{
if(Key1==0)//如果按键按下,引脚读到低电平
{
LED_R=1;
LED_G=0;
LED_B=0;//亮红灯
}
else
{
LED_R=0;
LED_G=1;
LED_B=0;//否则亮绿灯
}
delay_n_ms(100);//延时0.1秒 程序每秒检测10次按键
}
}
本帖最后由 我爱萝丽爱萝丽 于 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判断不同的值显示不同颜色不就可以了么?
本课的主要内容就是这些了,更多精彩下一课再见
#include<reg51.h>
sbit LED_R=P3^4;//定义红灯
sbit LED_G=P3^3;//定义绿灯
sbit LED_B=P3^2;//定义蓝灯
sbit Key1=P3^0;//定义按键
unsigned char mode; //定义一个数据,指示不同状态。定义后mode的值是0
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
{
while(n)
{
Delay1ms();
n=n-1;//每循环一次n减小1
}
}
main()
{
while(1)
{
if(Key1==0)//如果按键按下,引脚读到低电平
{
mode=mode+1;//每按一次按键,颜色模式改变
if(mode>7)
{
mode=0; //七种颜色切换完,回到0重新开始
}
}
if(mode==0) //模式0,熄灭
{
LED_R=0;
LED_G=0;
LED_B=0;
} //没有else可以不写
if(mode==1)//模式1,红色
{
LED_R=1;
LED_G=0;
LED_B=0;
}
if(mode==2)//模式2,黄色
{
LED_R=1;
LED_G=1;
LED_B=0;
}
if(mode==3)//模式3,绿色
{
LED_R=0;
LED_G=1;
LED_B=0;
}
if(mode==4)//模式4,青色
{
LED_R=0;
LED_G=1;
LED_B=1;
}
if(mode==5)//模式5,蓝色
{
LED_R=0;
LED_G=0;
LED_B=1;
}
if(mode==6)//模式6,紫色
{
LED_R=1;
LED_G=0;
LED_B=1;
}
if(mode==7)//模式7,白色
{
LED_R=1;
LED_G=1;
LED_B=1;
}
delay_n_ms(150);//程序每0.15秒检测一次按键
}
}
楼主void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
这句代码是什么意思 向楼主致敬,学单片机编程
顶一个,争取学会单片机。 延伸的学习情况 都帮初学者考虑了 真的是太nice了 这次系统的学习 没学过编程感觉云里雾里的。感谢楼主,细致的讲解。
赞赞赞一个先 。 支持支持, 楼主辛苦了 我爱萝丽爱萝丽 发表于 2016-9-13 02:46
1.1 循环控制
666666666666666666666 我爱萝丽爱萝丽 发表于 2016-9-17 14:01
1.3 多种模式切换
6666666666666666 我是沙发不?第一次沙发 爽啊哈哈。 板凳站位~~
坐地板听课
顶起来
第一次这么考前
顶一个,争取学会单片机。 顶一个
强烈建议楼主出套件!!!!!!!
可以有多个版本供大伙选择!!!! 支持萝莉老大,萝莉做东西想的就是十分周到 支持 支持强烈支持 老大下次做简易遥控器的时候 能加进去遥控或接受能检测动力电池电压 低压报警的功能吗?希望做进去并教给我们源码 谢谢 顶 加油顶
板凳站位,
板凳站位 哈哈,支持,期待更新 学习一下,出个套装,大家买着方便
支持老大,我都保存好了,以后答应出来方便翻阅。 好,这样更一步一步学习, hmilycheng 发表于 2016-9-6 19:56
强烈建议楼主出套件!!!!!!!
可以有多个版本供大伙选择!!!!
多个版本指什么 郝峰 发表于 2016-9-6 20:20
支持萝莉老大,萝莉做东西想的就是十分周到 支持 支持强烈支持 老大下次做简易遥控器的时候 能加进去遥控或 ...
简易控是单向的,没有回传 大哥想得周到