编辑推荐: |
本文讲解了51单片机入门基础知识相关内容。希望对您的学习有所帮助。
本文来自于CSDN,由火龙果软件Linda编辑、推荐。 |
|
一、单片机介绍
单片机,英文Micro Controller Unit,简称MCU
内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能
单片机的任务是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(例如电机,LED等)的控制
单片机跟计算机相比,单片机算是一个袖珍版计算机,一个芯片就能构成完整的计算机系统。但在性能上,与计算机相差甚远,但单片机成本低、体积小、结构简单,在生活和工业控制领域大有所用
同时,学习使用单片机是了解计算机原理与结构的最佳选择
51单片机是指80年代Intel开发的8051单片机内核的统称,就是因为这个“8051”有个51,所以凡是与“8051”内核一样的单片机都统称为51系列单片机
二、LED代码
2-1点亮一个LED
这里使用的普中单片机的LED是共阳极,所以将P2寄存器设置值为如下0xFE //1111 1110
2-2LED循环闪烁
通过调用延时函数实现闪烁
2-3LED流水灯
通过进行P2寄存器的不断延时赋值实现流水灯-基础版
2-4LED流水灯Plus
优化含参延时函数,但是会有一定的误差
三、独立按键与LED
轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通和断开
LED发光二极管:Light Emitting Diode
LED正极引脚较长,负极引脚较短
LED正极闪电极较小,负极闪电极较小(在玻璃灯罩里面的)
3-1独立按键控制LED亮灭
通过循环和判断实现按键控制LED亮灭功能
3-2独立按键控制LED状态
按键的抖动
对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动
为了避免误操作,需要进行消抖处理:硬件消抖、软件消抖
硬件消抖: RS触发器、电容充放电滤波等方式
软件消抖:Delay函数延时消抖,定时消抖以及外部中断消抖
void Delay(unsigned int xms)
|
3-3独立按键控制LED显示二进制
通过二进制值的输出来让LED显示
void Delay(unsigned int xms)
|
3-4独立按键控制LED移位
通过C语言移位指令以及对LEDNum变量值的控制来完成LED移位显示操作
void Delay(unsigned int xms)
|
四、数码管
4-1静态数码管显示
注意若用开发板的时候不要接LCD1602显示屏,因为引脚共用原因会导致数字显示异常
voidDelay(unsignedintxms) unsignedcharNixieTable[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; voidNixie(unsignedcharLocation,Number) case1:P2_4=1;P2_3=1;P2_2=1;break; case2:P2_4=1;P2_3=1;P2_2=0;break; case3:P2_4=1;P2_3=0;P2_2=1;break; case4:P2_4=1;P2_3=0;P2_2=0;break; case5:P2_4=0;P2_3=1;P2_2=1;break; case6:P2_4=0;P2_3=1;P2_2=0;break; case7:P2_4=0;P2_3=0;P2_2=1;break; case8:P2_4=0;P2_3=0;P2_2=0;break;
|
4-2动态数码管显示
想要进行多个数码管同时显示,需要进行消影操作
出现串位显示的原因是因为数码管的位选和段选出现了交叉,导致串位:位选-段选-位选-段选-位选-段选
消影:位选-段选-清零-位选-段选-清零
voidDelay(unsignedintxms) unsignedcharNixieTable[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; voidNixie(unsignedcharLocation,Number) case1:P2_4=1;P2_3=1;P2_2=1;break; case2:P2_4=1;P2_3=1;P2_2=0;break; case3:P2_4=1;P2_3=0;P2_2=1;break; case4:P2_4=1;P2_3=0;P2_2=0;break; case5:P2_4=0;P2_3=1;P2_2=1;break; case6:P2_4=0;P2_3=1;P2_2=0;break; case7:P2_4=0;P2_3=0;P2_2=1;break; case8:P2_4=0;P2_3=0;P2_2=0;break;
|
数码管驱动方式:
1.单片机直接扫描:硬件设备简单,但会耗费大量的单片机CPU时间
2.专用驱动芯片:内部自带显存、扫描电路,单片机只需告诉它显示什么即可
以上代码均为针对单片机直接扫描实现的,while(1)不断循环实现
五、LCD1602(模块化编程开始)
5-1模块化编程
模块化编程:
•传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路
•模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include
"XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等
以Delay函数为例
Delay.h
voidDelay(unsignedintxms);
|
Delay.c
voidDelay(unsignedintxms)
|
图示 模块化实现数码管显示
Delay.h
void Delay(unsigned int xms);
|
Nixie.h
void Nixie(unsigned char Location,Number);
|
Delay.c
void Delay(unsigned int xms)
|
Nixie.c
unsigned char NixieTable[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; void Nixie(unsigned char Location,Number) case 1:P2_4=1;P2_3=1;P2_2=1;break; case 2:P2_4=1;P2_3=1;P2_2=0;break; case 3:P2_4=1;P2_3=0;P2_2=1;break; case 4:P2_4=1;P2_3=0;P2_2=0;break; case 5:P2_4=0;P2_3=1;P2_2=1;break; case 6:P2_4=0;P2_3=1;P2_2=0;break; case 7:P2_4=0;P2_3=0;P2_2=1;break; case 8:P2_4=0;P2_3=0;P2_2=0;break;
|
5-2LCD1602调试工具*
LCD1602调试函数模块
不同的LCD1602调试函数代码决定了不同的调试函数以及使用方法
使用时应注意对应的文件函数的异同
函数
作用
LCD_Init();
初始化
LCD_ShowChar(1,1,'A');
显示一个字符
LCD_ShowString(1,3,"Hello");
显示字符串
LCD_ShowNum(1,9,123,3);
显示十进制数字
LCD_ShowSignedNum(1,13,-66,2);
显示有符号十进制数字
LCD_ShowHexNum(2,1,0xA8,2);
显示十六进制数字
LCD_ShowBinNum(2,4,0xAA,8);
显示二进制数字
代码暂略,等后续对头文件以及源代码进行全方面分析之后再复盘补充
六、矩阵键盘
6-1矩阵键盘*
涉及到了施密特触发电路和上拉电阻和下拉电阻,等模电再学一学复盘一下
这里同样使用了前面的LCD1602的调试文件:LCD1602.H、LCD1602.C
编译时会出现WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY
PROCESS的报错,是因为引用的LCD1602的文件中的函数虽然定义了,但是并没有在程序中显式调用到定义过的函数,可以无视,但是会浪费RAM
main.c
lcd1602_show_string(0,0,"MatrixKey:"); case1: lcd1602_show_string(0,1,"1");break; case2: lcd1602_show_string(0,1,"2");break; case3: lcd1602_show_string(0,1,"3");break; case4: lcd1602_show_string(0,1,"4");break; case5: lcd1602_show_string(0,1,"5");break; case6: lcd1602_show_string(0,1,"6");break; case7: lcd1602_show_string(0,1,"7");break; case8: lcd1602_show_string(0,1,"8");break; case9: lcd1602_show_string(0,1,"9");break; case10: lcd1602_show_string(0,1,"10");break; case11: lcd1602_show_string(0,1,"11");break; case12: lcd1602_show_string(0,1,"12");break; case13: lcd1602_show_string(0,1,"13");break; case14: lcd1602_show_string(0,1,"14");break; case15: lcd1602_show_string(0,1,"15");break; case16: lcd1602_show_string(0,1,"16");break;
|
MatrixKey.h
unsigned char MatrixKey();
|
MatrixKey.c
if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;} if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;} if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;} if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;} if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;} if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;} if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;} if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;} if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;} if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;} if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;} if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;} if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;} if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;} if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;} if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
|
6-2矩阵键盘密码锁
所使用的前述模块化列表
LCD1602
Delay
MatrixKey
unsignedintPassword,Count; LCD_ShowString(0,1,"Password:"); LCD_ShowNum(1,1,Password,4); LCD_ShowString(1,14,"OK!"); LCD_ShowNum(1,1,Password,4); LCD_ShowString(1,14,"ERR"); LCD_ShowNum(1,1,Password,4); LCD_ShowNum(1,1,Password,4);
|
七、定时器
7-1定时器
定时器介绍:
51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成
定时器作用:
(1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
(2)替代长时间的Delay,提高CPU的运行效率和处理速度
(3)多任务处理
(…)
STC89C52定时器资源
•定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源
•注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的
定时器框图
定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行 定时器工作模式
STC89C52的T0和T1均有四种工作模式:
工作模式1(16位定时器/计数器)框图:
SYSclk:系统时钟,用来产生固定频率的脉冲(晶振电路)来使后面的计数器的技术值累加,此时作定时器使用,
MCU in 12T/6T mode:分频模式,例如当晶振频率为12MHz,采用MCU in 12T
mode时,产生的脉冲频率就是1MHz
T0 Pin:外部接口,当由外部接口来提供脉冲时,作计数器使用
C/T非:配置寄存器时若其对应的控制字为1,则为Count计数器模式,为0,则为Time定时器模式
TH0和TL0:Time High 0和Time Low 0,代表了定时器的高位和低位,后面的0表示计时器0,计数器共十六位,最大计数值为65535
TF0:Time Flag 0,表示计时器0的标志位,当达到最大技术值后,下一次计数就会溢出,产生脉冲传送到标志位从而影响后面的Interrupt,从而申请中断。
|