1、单片机,英文Micro Controller Unit,简称MCU
2、内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能
3、单片机的任务是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(例如电机,LED等)的控制
4、单片机跟计算机相比,单片机算是一个袖珍版计算机,一个芯片就能构成完整的计算机系统。但在性能上,与计算机相差甚远,但单片机成本低、体积小、结构简单,在生活和工业控制领域大有所用
5、51单片机详细内容介绍:
所属系列:51单片机系列
公司:STC公司
位数:8位
RAM:512字节
ROM:8K(Flash)
工作频率:12MHz(本开发板使用)
(寄存器中,用十六进制表示各口状态。如P2=0xEF;表示1111 1110)
(电路中排阻的读书:102——10 00;473——47 000即末尾数字表示倍率)
6、编程基本框架:
#include<>
void main()
{}
(先看代码:LED闪烁)
#include
void Delay100ms(unsigned int xms)
{
unsigned char i, j;
while(xms--){
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
}
void main()
{
while(1){
P2=0xFE;
Delay100ms(10);
P2=0xFF;
Delay100ms(10);
}
}
(1)该段代码有三个部分组成,头文件、Delay100ms函数、main主函数。
(2)头文件:#include
(3)Delay100ms函数:(在stc软件界面右上角工具栏中有“软件延时计算器”,选择好延时后,选好指令集——stc-Y1)复制粘贴在void main()前。其起的作用是让单片机执行完任务后停顿xms。注意的是,该函数是修改后的函数,原函数只能停顿固定的时间,而我们为这个函数添加了变量(unsigned int xms),然后再添加一个循环,该循环以xms为条件,非零继续进行,变至零停止(x--),例如主函数中的Delay100ms(10);原本只能停顿100ms,加入变量10后,该函数会进行10次,即为1000ms,也就是1s。
(4)main主函数:while(1){}的括号内为非零数1,表示含义为“真”,因此该循环会一直进行下去不会停止。{}内的P2表示的是八个LED灯,P2有八位数,根据十六进制,P2=0xFE表示1111 1110,我们知道LED在低电频状态下才能工作,也就是L1会工作,其他关闭。后面Delay100ms(10);是引用Delay100ms函数,进行停顿。紧接着P2=0xFF表示1111 1111,即为全部LED关闭。如此循环下去,实现了LED的重复闪烁。
(1)轻触按键,相当于电子开关,通过内部金属弹片来实现接触断开
(注意:RXD为3_1口,TXD为3_0口,下面两个分别为3_2口,3_3口)
(按下按键即为低电频)
(先看代码:独立按键控制LED)
#include
void Delay100ms(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
while(1)
{
if(P3_1==0)
{
Delay100ms(2);
while(P3_1==0);
Delay100ms(2);
P2_0=~P2_0;
}
}
}
(2)要想通过按键实现控制LED,原理就是编写一个判断语句if语句来以按键为条件,达到条件后执行LED亮起的任务
(3)值得注意的事if和while括号里应该是==,表示两个值是否相等的意思
(4)也许会奇怪为什么要在if里添加Delay100ms(2);这里就要讲到按键抖动了
(为了防止抖动产生的影响,我们会在按下按键,和松开按键后,选择停顿20ms左右)
(5)if函数内还有个while语句,括号内是P3_1==0,表达的意思是K1键一直被按着(其实就是想你一直按着K1不工作,直到你松开)。为什么while没有{}?因为程序只想让其不工作,不需要其他任务,所以括号内为空内容,可不添加{}。
(6)P2_0=~P2_0;其中~为取反符号。如下是数据运算的其他符号
而P2_0一开始为暗——0,而~P2_0变为1——亮,并将该值赋给了P2_0。后面再按,执行程序P2_0——1变为~P2_0——0。(注意的是P2有八位,控制八盏LED。P2_0有一位,只控制一盏)
(先看代码:按键控制LED二进制亮起)
#include
void Delay100ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char num=0;//¸ÃÀàÐÍΪ°Ëλһ¿ªÊ¼±íʾ0000 0000
while(1)
{
if(P3_1==0)
{
Delay100ms(2);
while(P3_1==0);
Delay100ms(2);
num++;//¸ÃÀàÐÍ´Ó0000 0000¿ªÊ¼²»¶Ï½øÐжþ½øÖƵؼÓÒ»
//±ä³É0000 0001->0000 0010->0000 0011->0000 0100
P2=~num;//¸ÃÈ¡·´²½ÖèʹÁãÈ«±äΪһ¼
//¼´Îª1111 1110->1111 1101->1111 1100->1111 1011
}
}
}
(1)相对于上一个代码,这里多了unsigned char num=0;num++;从之前C语言学习中我们知道unsigned char是定义字符,其定义的是一位八位字符。且看下面其他的定义以及他们对应的位数
(2)unsigned char num=0;表示的是num这个字符表示0000 0000
(3)num++;表示的是num=num+1。根据二进制的加减法:
0000 0000->0000 0001->0000 0010->0000 0011->0000 0100.......
(4)最后的P2=~num;一下子把八位数给取反,十分方便,实现了LED二进制式地亮起
(先看代码:K1和K2按键控制LED左右移动)
#include
void Delay100ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
xms--;
}
}
void main()
{
unsigned char num=0;//¶¨Òå±äÁ¿Òª·ÅÔÚ×îÇ°Ãæ
P2=~0x01;
while(1)
{
if(P3_0==0)
{
Delay100ms(2);
while(P3_0==0);
Delay100ms(2);
num++;
if(num>=8)
{
num=0;
}
P2=~(0x01<0000 0010
}
if(P3_1==0)
{
Delay100ms(2);
while(P3_1==0);
Delay100ms(2);
if(num==0)
{
num=7;
}
else
{
num--;
}
P2=~(0x01<
(1)首先初始化LED的状态P2=~0x01;
(2)我们设想K1控制LED向左走,K2控制LED向右走。所以需要设立两种条件,两个if来判断按的是那个按键。
(3)先看K2键(P3_0):点击一次K2,进行num++,num从0000 0000二进制式加1,但是我们看最后P2=~(0x01< (4)if语句内还有个if语句,是用来处理满格的情况,也就是当num=8,LED无法进八格,所以就干脆重新开始,num=0,直接P2=~0x01。 (5)再看K1键(P3_1):点击一次K1,这里先是判断了num的数值,若num=0,也就是说LED灯仍处在第一位,那么点击K1,没有位置让LED向左移动,那就让他变为最右边的位置P2=~(0x01< (1)显示器,有多个发光二极管组成 (2)数码管引脚定义: (值得关注的是单个数码管八个LED的字母代号(包括小数点DP) 再看单个数码管的连接方式,共有十个连接口,其中3,8口已经用来连接阴极,还剩下八个口来连接剩下的LED,都是以就近原则来连接的。 ) (3)单个数码位的连接方式 : 该连接方式为共阴极连接(阴极连到一个口)。该连接方式为共阳极连接(阳极连到一个口) (很简单的理解:有电流流过,LED才能亮,电流从高电频流向低电频,就拿共阴极连接来举例:对于数码管,我们要点亮A号LED灯,需要在7号位给高电频,才能使电流流过LED灯。注意区分LED与数码管的区别) (4)四位一体数码管 (为什么四位数码管的口只比一位多了两位?且看他们的连接方式:相同字母序号的LED连接在一条管上,而各位的共阴极分别连在了剩下的四个口) (5)了解完数码管的构造和接线原理,还需要了解控制他的其他外设。 右上角的ABC,是用来选定LED灯的,C为高位,A为低位,按照CBA的顺序赋给它0、1的值,根据二进制来选择右边Y0~Y7的LED灯。由于我们的LED灯是四位一体的,LED的连接线路有些事重复的,因此我们需要通过译码器来选择需要发光的LED灯(看下图演示) ·在译码器和数码管中间下方的外设为双向数据缓冲器。 ·我们通过译码器选择好LED灯后,要通过该外设来控制大LED灯中的八位小LED灯的亮暗(即显示出数字) ·可以看到从数码管下方连接出来的线路abcdefg,刚出来的数字是连接的线路号码,接入双向数据缓冲器后需要注意的是A0-B0,A1-B1.....。再看左边的LE的P0_0,P0_1,P0_2.....。通过双向缓冲器,我们可以控制abcdefg的亮灭(由于是共阴极连接,所以1为亮,0为灭)来展示我们想要的数字。(看下图演示) ·由此,我们可以定义一个数组来显示各个数字 int shuzi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,}; · 0在第一位即shuzi[0],1在第二位即shuzi[1]....... (6)数码管显示数字的过程 ·位选-段选 位选-段选 位选-段选 位选-段选...... ·但是由于过程很快,所以有时候段选还未结束时,下一段位选已经开始了,这时候就会导致产生重影,LED灯模糊难辨 ·因此需要在段选和位选之间加一段延迟——位选-段选 Delay100ms(0.1) 位选-段选,就可以解决这一问题。 (看代码:在四位一体显示数字5201314) 1、该段代码有三部分组成其一为void Delay100ms(unsigned int xms)函数,其二为void num(int location,int number)函数,其三为void main()主函数。 2、void Delay100ms(unsigned int xms)前面介绍过,在这就不做过多赘述。 3、void num(int location,int number)函数中有两个变量location和number,都是int类型 (1)location用作Switch case语句变量。输入location的值,与case对应的值进行配对,如果按顺序来如果符合,就进行case里的程序。注意:记得带case最后添加break。否则会导致整排数码管全部显示出数字。举例:当我们给location的值是2,对应着case 2,进行的操作是P2_4=1;P2_3=1;P2_2=0;break;根据二进制110转化为十进制6,数码管从右开始数六位,我们习惯是从左往右看,所以我们的第二位相当于从右往左的第六位 (2)number用作shuzi[]的变量,即shuzi[number],当我们赋给number的值是0是,数组就位shuzi[0],按照我们前面设立的数组: int shuzi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};可知shuzi[0]就是0x3F,点亮的LED灯就组成0。 (3)接着是进行Delay100ms(0.1);的操作即停顿10ms (4)最后一步将P0=0x00进行全部清零,这一步很关键,否则就会出现重影现象! (其实我们LED灯的循环很快,我们眼睛看到LED灯其实是不停以很快的速度闪烁的,由于我们的视觉暂留,所以我们看到的是完整的数字) 4、 void main()主函数,看到while函数内运用了多个num函数,num(2,5)表达的意思就是,从左往右数第2个格的位置显示出数字5,后面以此类推。(由于第二个while已经在第一个while函数内,所以break跳出循环后继续该循环,break加不加无所谓。) (看最后呈现效果)
三、数码管1、LED数码管:
译码器
双向数据缓冲器
#include