51单片机教程(四)- 点亮LED灯
1、项目分析
- 让输入/输出口的P1.0连接一盏LED灯进行点亮。
2、技术准备
1 LED组成
- 说明
- 二极管有 P型 和 N型材料构成,通常是:硅/锗 掺杂其他元素(硼、磷等)
- 电子是带负电的,是负电荷的载体,电子流是从负极流向正极
- 电流则从正极流向负极。
- 当N型材料连接电源负极(正向连接),则电子会从流向P型材料的空穴,则会有电流流过【正向偏置】;
- 当N型材料连接电源正极(反向连接),由于没有多余的空穴,则不会有电子跃迁至P型材料,则不会有电流流过【反向偏置】;
- 则说明二极管具有单向导电的特性
- 二极管有 P型 和 N型材料构成,通常是:硅/锗 掺杂其他元素(硼、磷等)
- 扩展
- 如果二极管是由 硅 制成,需要一个约 0.7V的电压,才会有电流流过,则即便是二极管正向连接,也不会有电流流过。
- 如果二极管是由 锗 制成,需要一个约 0.3V的电压,才会有电流流过,则即便是二极管正向连接,也不会有电流流过。
- 如果反向链接,则不同材质的二极管所能承受的电压,可以高达 100V,电流可达 1A
2 介绍
-
LED发光二极管
- 它是半导体二极管的一种,可以把电能转化成光能;常简写为LED。发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。
-
LED的工作原理。
-
LED的工作是有方向性的,只有当正级接到LED阳极,负极接到LED的阴极的时候才能工作,如果反接LED是不能正常工作的。
-
-
LED的原理图解析
-
开发板上面LED的原理图如右图,LED的阳极串联一个电阻,然后连接到电源VCC,而LED的阴极连接到单片机的P1口,如果你想点亮一盏LED就对把单片机相对应的IO赋为低电平(0)。
-
3 C语言知识点
1 标识符
-
标识符:
- 用来标识源程序中某个对象的名字,这些对象可以是数据类型名、函数名、变量名、数组名等。
-
组成
- 标识符由字母、数字和下划线组成。
- 第一个字符必须是字母或下划线。
- 不能使用C语言中的关键字。
- 由于C51中有些库函数的标识符是以下划线开头的,所以一般不要以下划线开头命名标识符。
// 正确标识符 name Name num1 oldName // 错误标识符 3ku
2 关键字
- 标准C语言定义了32个关键字
- 常用关键字
- char
- int
- unsigned
- for
- while
- if
- sbit
- interrupt
3 变量与常量
-
常量
-
又称为标量,它的值在程序执行过程中不能改变的量,常量的数据类型有整型、浮点型、字符型和字符串型等。
-
实际使用中用 #define定义(宏定义) 或 const 在程序中经常用到的常量,这样一方面有助于提高程序的可读性,另一方面也便于程序的修改和维护。
#define PI 3.14 //以后的编程中用PI代替浮点数常量3.14,便于阅读 #define SYSCLK 12000000 //长整型常量用SYSCLK代替12MHz时钟 #define TRUE 1 //用字符TRUE,在逻辑运算中代替1 #define STAR '*' //用STAR表示字符 '*' #define uint unsigned int //用uint 代替unsigned int const int MAX_SIZE = 100;
-
-
变量
- 变量是一种在程序执行过程中,其数值不断变化的量。
-
注意
-
C51规定变量必须先定义后使用。
unsigned int i; i = 10; printf("i=%d", i); unsigned int i = 10;
-
4 数据类型
-
变量都有相应的数据类型。
-
char 字符类型
- char 类型的长度是一个字节,通常用于定义处理字符数据的变量或常量。
- 分无符号字符类型 unsigned char 和有符号字符类型 signed char,默认值为 signed char 类型。
- unsigned char 类型用字节中所有的位来表示数值,所能表达的数值范围是 0~255。
- signed char 类型用字节中最高位字节表示数据的符号,“0”表示正数,“1”表示负数,负数用补码表示。所能表示的数值范围是-128~+127。
- unsigned char 常用于处理 ASCII 字符或用于处理小于或等于 255 的整型数。
-
int 整型
- int 整型长度为两个字节,用于存放一个双字节数据。
- 分有符号 int 、整型数signed int 和无符号整型数 unsigned int,默认值为 signed int 类型。
- signed int 表示的数值范围是-32768~+32767,字节中最高位表示数据的符号,“0”表示正数,“1”表示负数。
- unsigned int 表示的数值范围是 0~65535。
-
long 长整型
- long 长整型长度为四个字节,用于存放一个四字节数据。
- 分有符号 long 长整型 signed long 和无符号长整型 unsigned long,默认值为 signed long 类型。
- signed int 表示的数值范围是-2147483648~+2147483647,字节中最高位表示数据的符号,“0”表示正数,“1”表示负数。
- unsigned long 表示的数值范围是 0~4294967295。
-
float 浮点型
- float 浮点型在十进制中具有 7 位有效数字,是符合 IEEE-754 标准的单精度浮点型数据,占用四个字节。
-
指针型
-
指针型是一种特殊的数据类型,其本身就是一个变量,但在其中存放的是另一个数据的地址。
-
在C51中,指针的长度一般是3个字节。根据所指向的变量类型的不同指针变量也有不同的类型,指针变量的类型也就表示了该指针指向的地址中的数据的类型。
-
-
bit 位标量
-
bit 位标量是C51的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。
-
它的值是一个二进制位,不是 0 就是 1,位变量的值可以取0 (false)或1 (true)。对位变量进行定义的语法如下:
bit flag1; bit send_en=1;
-
-
sfr 特殊功能寄存器
-
单片机内的各种控制寄存器、状态寄存器以及I/O端口锁存器、定时器、串行端口数据缓冲器是内部数据存储器的一部分,离散地分布在80H~FFH的地址空间范围内,这些寄存器统称特殊功能寄存器(SFR,Special Function Registers )。
-
sfr类型的长度为一个字节,其定义方式如下:
- sfr 特殊功能寄存器名 = 地址常量;
-
说明
-
“地址常量”就是所定义的特殊功能寄存器的地址。
sfr TMOD=0x89; /*定义定时器/计数器方式控制寄存器TMOD的地址为89H*/ sfr P1=0x90; /*定义P1口的地址为90H*/
-
-
注意
- 在关键字sfr后面必须是一个名字,名字可以任意选取,但应符合一般的习惯。等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H~0FFH)。
-
-
sfr16 16位特殊功能寄存器
-
在新一代的8051单片机中,特殊功能寄存器在功能上经常组合成16位来使用。
-
为了有效地访问这种16位的特殊功能寄存器,可采用关键字sfrl6。
-
sfrl6类型的长度为两个字节,其定义语法与8位SFR相同,但16位SFR的低端地址必须作为sfr16的定义地址.
sfr16 T2=0CCH; //定义TIMER2,其地址为T2L=0CCH、T2H=0CDH。
-
-
sbit 可寻址位
-
sbit 同样是C51中一种扩充数据类型,利用它能访问芯片内部的 RAM 中的可寻址位或特殊功能寄存器中的可寻址位。例如:
// PSW是可位寻址的SFR,其中各位可用sbit定义。 sbit CY=0Xd7; /*定义进位标志CY的地址为D7H* sbit AC=0xD0^6; /*定义辅助进位标志AC的地址为D6H*/ sbit RS0=0XD0^3; /*定义RS0的地址为D3H*/
-
注意
-
sfr和sbit只能在函数外使用,一般放在程序的开头
-
实际上大部分特殊功能寄存器及其可位寻址的位的定义在reg51.h、
reg52.h
等头文件中已经给出,使用时只需在源文件中包含相应的头文件,即可使用SFR及其可位寻址的位;而对于未定义的位,使用前必须先定义。例如:#include<reg52.h> sbit P10=P1^0; sbit P12=P1^2; PSW=0x08;
-
-
3、程序实现
实验1:点亮开发板上的第1个LED灯
- 从LED原理图上看,只要P1.0输出为低电平就可以点亮LED灯。
#include <reg52.h> // 包含头文件,在“reg52.h”上右键单击,并打开,可以看到它里面的定义
sbit led=P1^0; // 定义一个LED 为P1.0 IO口
void main()
{
led=1; // 单片机IO P1.0脚输出一个高电平,发光管不亮
led=0; // 单片机IO P1.0脚输出一个低电平,点亮发光管。 高电平(1)为5V 低电平为0。
while(1);
}
-
实验效果
- 软件设计不用汇编,一律采用C语言,便于理解和扩展。
实验2:点亮开发板上的4个LED灯(第1、3、5、7个灯)
#include "reg52.h"
sbit led1=P1^0;
sbit led3=P1^2;
sbit led5=P1^4;
sbit led7=P1^6;
void main()
{
led1=0; //参照电路图可知,P1^0为低电平,可以让led1点亮。
led3=0;
led5=0;
led7=0;
while(1); //此处设置一个死循环,让程序停留在这里,防止跑飞。
}
#include<reg52.h>
sbit LED0=P1^0; // 用sbit 关键字 定义 LED到P1.0端口,
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit LED3=P1^3;
sbit LED4=P1^4;
sbit LED5=P1^5;
sbit LED6=P1^6;
sbit LED7=P1^7;
/*------------------------------------------------
主函数
------------------------------------------------*/
void main ()
{
//此方法使用bit位对单个端口赋值
LED0=0; //将P1.0口赋值 0,对外输出低电平
LED1=1;
LED2=0;
LED3=1;
LED4=0;
LED5=1;
LED6=0;
LED7=1;
while (1) //主循环
{
//主循环中添加其他需要一直工作的程序
}
}
实验3:点亮开发板上的4个LED灯(第2、4、6、8个灯)
-
定义所有端口: P1、P2、P3、P4,用来表示 P1、P2、P3、P4 的 I/O 口。
IO口 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 取值 0 1 0 1 0 1 0 1 效果 亮 灭 亮 灭 亮 灭 亮 灭 -
思考:P1 数据值转为十六进制是多少? ox55
#include <reg52.h>
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
// 0101 0101 --> 0x55
P1 = 0x55;
while (1) // 主循环中添加其他需要一直工作的程序
{}
}
4、提示
- 为了方便每次程序编译成功后,就自动把 hex 文件烧录到MCU中,则可以勾选图中2个选项。