目录
LED
LED灯亮的原理图
LED灯光闪烁
电路设计
keil文件
LED流水灯的实现
keil文件
数码管
显示的基本原理
LED数码管的显示方式
静态显示方式
动态显示方式
具体案例
数码管静态显示
电路图
keil文件
数码管动态显示
电路图
keil文件
74LS138译码器
译码表
译码器案例
电路图
keil文件
单片机之按键
键盘的结构
按键消抖
软件消抖
硬件消抖
键盘的分类
独立式键盘
行列式键盘
键盘的识别
独立按键案例
电路图
keil文件
行列式键盘案例
电路图
对应按键判断
keil文件
LED
前言:中文名为发光二极管,用途为:照明、广告灯、指引灯、屏幕等。
注意:以上分别为LED灯的元器件符号,元器件实物和区分元器件正负极的方法。
LED灯亮的原理图
注意:
- 上面的接法为共阳极接法,左边的接口分别连到单片机的引脚上,若单片机给该引脚低电平,那么就可以形成回路,进而导致LED灯亮。
- 单片机控制引脚的方式为寄存器,寄存器通常每8位为一组;既可以8位一起处理,也可以按位方式使用(CPU通过控制寄存器来控制我们的硬件电路,硬件电路来执行我们想要完成的功能)
- 寄存器对应的脚位顺序:P1=01011101——对应脚位顺序:P1.7,P1.6,P1.5,P1.4,P1.3,P1.2,P1.1,P1.0
LED灯光闪烁
电路设计
keil文件
#include "reg51.h"
#共阳极接法
#P2的0号脚位
sbit LED0=P2^0;
#大概nms的延时
void delay(unsigned int n){
unsigned int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}
void main()
{
#我们要让51单片机一直运行
while(1){
#共阳极接法,那么单片机接口处给低电平,灯方可亮
LED0=0;
delay(5);
LED0=1;
delay(5);
}
}
LED流水灯的实现
电路设计:和上面LED灯泡闪烁的电路一样
keil文件
#include "reg51.h"
#共阳极接法
sbit LED0=P2^0;
#大概nms的延时
void delay(unsigned int n){
unsigned int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}
#流水灯的实现
void led(){
int i=0;
for(i=0;i<8;i++){
P2=~(0x01<<i);//0000 0001
delay(100);
}
}
void main()
{
while(1){
led();
}
}
数码管
LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成的8字型器件
注意:8个LED构成了数码管,数码管的连接方式有共阴极和共阳极连接。
显示的基本原理
LED数码管的显示方式
静态显示方式
特点
- 公共端直接接地或接电源
- 每个数码管的段选线与一组IO接口线相连
- 每个数码管一直在显示
动态显示方式
特点
- 所有的数码管的段选线与一组IO接口线并联在一起
- 每个数码管的公共端由一根IO线控制
- 显示为逐个显示(利用人眼的视觉暂留原理,数码管切换的速度够快就好像多个数码管一起显示)
注意:段码线决定晶体管显示的是什么,位码线决定是哪个晶体管要显示;若想要四个数码管均显示不同的数字那么就需要以很小的时间内不断地切换四个数码管的显示(人眼的视觉暂留)
具体案例
数码管静态显示
需求:共阴极的方式实现0——9的不断循环。
电路图
keil文件
#include "reg51.h"
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void delay(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}
void seg()
{
int i=0;
for(i=0;i<10;i++)
{
P2=s[i];
delay(500);
}
}
void main()
{
while(1)
{
seg();
}
}
数码管动态显示
需求:在数码管上显示hello这个字符串
电路图
注意:英文字母为段码线,数字为位码线;
keil文件
#include "reg51.h"
unsigned char str[]={0x76,0x79,0x38,0x38,0x3F};
unsigned char wei[]={0x01,0x02,0x04,0x08,0x10};
void delay(unsigned int n){
unsigned int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}
void seg(){
int i=0;
for(i=0;i<5;i++){
P3=~wei[i];
P2=str[i];
delay(5);
}
}
void main()
{
while(1)
{
seg();
}
}
74LS138译码器
前言:该译码器可以仅通过3个针脚来决定右面对应针脚的信号(其中一个为0剩下的全是1),进而对数码管的位选断进行选择。
理解:左边的针脚为数字输入端,右边的8个端口为数字输出端;上下两端分别为电源和接地;左下脚3个针脚为使能端(需要把G1接上高电平、G2A和G2B接上低电平)
译码表
- 000——Y0
- 001——Y1
- 010——Y2
- 011——Y3
- 100——Y4
- 101——Y5
- 110——Y6
- 111——Y7
注意:译码表输入端三个字母的排序为CBA
译码器案例
需求:在特定位置显示特定数字。
电路图
keil文件
#include "reg51.h"
sbit P3_0=P3^0;
sbit P3_1=P3^1;
sbit P3_2=P3^2;
#1——9对应的段码
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void show(unsigned char location,unsigned char number){
switch(location)
{
case 1:P3_0=0;P3_1=0;P3_2=0;break;
case 2:P3_0=1;P3_1=0;P3_2=0;break;
case 3:P3_0=0;P3_1=1;P3_2=0;break;
case 4:P3_0=1;P3_1=1;P3_2=0;break;
case 5:P3_0=0;P3_1=0;P3_2=1;break;
case 6:P3_0=1;P3_1=0;P3_2=1;break;
case 7:P3_0=0;P3_1=1;P3_2=1;break;
case 8:P3_0=1;P3_1=1;P3_2=1;break;
}
P2=s[number];
}
void main()
{
while(1){
#展示第三列的数字为8
show(3,8);
}
}
单片机之按键
键盘的结构
按键消抖
前言:对于机械开关,当机械触点断开,闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定的接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随着一连串抖动
软件消抖
注意:这个抖动会有个抖动时间,这个时间大概在10ms到20ms之间;我们可以依据这个原理错开这个时间来实现软件消抖。
硬件消抖
理解:本质上还是利用了延时进行消抖。
键盘的分类
独立式键盘
特点:
- 每个独力健占用一根并口线,键位多时占用的并口线多
- 用于键位较少的情况
- 处理简单,直接判并口线
行列式键盘
特点:
- 键位分布在行列交叉点上
- 占用并口较少,键位越多越明显
键盘的识别
两步:第一步首先检测键盘上是否有键按下;第二部识别是哪一个键按下
- 检测键盘上是否有键按下的处理方法——全扫描
- 识别键盘中的哪一个键按下的方法——逐行逐列扫描
独立按键案例
需求:通过独立式按键控制数码管上的显示(每按下一次按键,数码管中显示的值加一)
电路图
keil文件
#include "reg51.h"
sbit key0=P1^0;
unsigned int num=0,flag=0;
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void key(){
#第一次按下
if(key0==0&flag==0){
flag=1;
}
#已经按下了,但是按键抬起
if(flag==1&key0==1){
num++;
flag=0;
if(num==10){
num=0;
}
}
}
void seg(){
P2=s[num];
}
void main()
{
while(1){
key();
seg();
}
}
行列式键盘案例
需求:按第一个键盘,按键亮1;按第二个键盘,按键亮2;
电路图
对应按键判断
原理:按键按下时,高电平会被低电平拉至低电平。
编码 | H3 | H2 | H1 | H0 | L3 | L2 | L1 | L0 |
初值 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
判断被按下按键的行数:检测第一个按键被按下,L0将H0拉至低电平:1110 0000
编码 | H3 | H2 | H1 | H0 | L3 | L2 | L1 | L0 |
初值 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
判断被按下案件的列数:检测第一个按键被按下,L0被H0拉至低电平:0000 1110
总结:
- 由此观之:行数:0xe0;列数:0x0e。由此观之第一个按键的行列标识为——行数+列数=0xe0+0x0e=0xee。
- 单片机IO口是一种弱上拉,强下拉的工作模式(输出的1驱动能力是有限的,而输出0驱动能力是比较强的)
keil文件
#include "reg51.h"
unsigned char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char num=99;
void delay(unsigned int n){
unsigned int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}
void key_scan()
{
unsigned char temp=0,temp0=0,temp1=0;
P1=0xf0; //为P1置初值,判断被按下按键的行数
//检测按键是否被按下
if(P1!=0xf0){
delay(20); //软件消抖
temp0=P1; //取出P1的值
P1=0x0f; //为P1置初值,判断被按下按键的列数
if(P1!=0x0f){
temp1=P1;
}
}
//取得被按下按键的标识
temp=temp0+temp1;
//被按下对应的按键执行对应的操作
if(temp==0xee){
num=0;
}
if(temp==0xed){
num=1;
}
}
void display(){
P2=s[num];
}
void main()
{
while(1){
key_scan();
display();
}
}