单片机入门学习路线"/>
单片机入门学习路线
目录
- 学习基础电路
- 一、基本的元器件
- 1、电阻
- 2、电容(C)
- 3、电感(L)
- <1>电感滤波
- <2>电感震荡
- <3>延迟
- 4、保险丝(熔断器)
- 5、二极管
- 6、三极管
- 7、MOS管
- 8、按键
- 9、led灯
- 10、LCD
- 11、蜂鸣器
- 二、学习基本外围电路
- 1、三极管开关电路
- 2、led驱动电路
- 3、按键检测电路
- 4、蜂鸣器驱动电路
- 5、存储电路
- 6、LCD驱动电路
- 7、单片机外围电路
- 8、单片机常见外设
- 三、单片机学习
- 51单片机
- 1、点亮LED灯
- 2、LED闪烁
- 3、LED流水灯
- 4、蜂鸣器
- 5、静态数码管实验
- 6、动态数码管显示
- 7、独立按键实验
- 8、矩阵按键实验
- 1、矩阵按键电路图:
- 2、矩阵按键行列式代码实现
- 3、矩阵按键线翻转扫描代码实现:
- 9、IO扩展(串转并)
- STM32
- ARM
学习基础电路
一、基本的元器件
是什么、都有什么作用
1、电阻
- 概念:导体对电流的阻碍作用就叫该导体的电阻(耗能元器件)
- 电阻的表示方法和测量方法
表示方法:直标法和色标发
测量方法:万用表和数字电桥- 万用表调到电阻档将表笔夹到电阻两端可以测出电阻大小
- 电阻在原理图中的表示方法
4、电阻的特性(伏安特性)
什么是伏安特性
纵坐标表示电流,横坐标表示电压,以此画出的I-U图像叫做导体的伏安特性曲线图,常用来研究电阻变化规律。
1、线性 R=U/I
2、非线性电阻:压敏电阻、热敏电阻
- 压敏电阻:当电压特别大的时候,它的电阻会很小,主要用于在并联电路中电路承受过压时进行电压钳位,吸收多余的电流以保护敏感器件。
压敏电阻也称为电冲击(浪涌)抑制器(吸收器)。
热敏电阻:
5、基本参数
标称阻值:
额定功率:P= I2R (限定了功率和电阻,电流就固定)
允许误差: ± \pm ± 0.5%(D) ± \pm ± 1%(F) ± \pm ± 2%(G) ± \pm ± 5%(J) ± \pm ± 10%(K) ± \pm ± 20%(M)
6、电阻的功能
- 分压:分压电阻分压
- 限流:采样电阻限流
- 测温:热敏电阻测温
- 防浪涌:压敏电阻通过吸收多余的电流起到防浪涌的作用,这时总电路的电流会特别大,会迅速熔断熔丝管FU,切断市电输入回路,避免电路设备过压损坏,起到过压保护作用。
7、如何选择电阻
- 功能
- 主要参数:阻值、功率、精度
- 电压
- 电阻一般会有一个耐压值,如果是20Ω、16V的电阻,接入100V的电压中,电阻会被击穿
8、什么是上拉电阻
上拉电阻(Pull-up Resistor)是一种电路元件,常用于数字电路中。
它的作用是将信号线拉高至逻辑高电平,以确保信号的正确传输和识别。
在数字电路中,一个输入端必须要有一个电平,以便输出器件正确地识别输入信号。如果没有连接上拉电阻,输入端就有可能处于浮空状态,即没有电平或者电平不稳定,会导致输出器件无法正确识别输入信号。通过连接上拉电阻,可以将输入端的电平拉高到逻辑高电平,从而确保信号的正确传输和识别。
2、电容(C)
1、 电容的定义
金属电器间夹的一层绝缘电介质,是指在给定电位差下自由电荷的储藏量
电容的一般计算公式:C=Q/U
电容计量单位F法拉的换算关系 F uF nF pF
电容的标示方法 测量方法
电容表达方式:
2、电容的特点和作用
特点:
- 隔直通交
- 电容器上的电压不能突变
作用:
- 储能:储能型电容器通过整流器收集电容,并将存储的能量通过变换器引线传送到电源的输出端
- 滤波:将一定频段内的信号从总信号中去除。大电容(1000uF)滤低频(20pF),小电容滤高频
- 退耦:
- 旁路
- LC谐振
3、如何选择电容
- 功能
- 材质
- 电容容值、电压值
4、思考:生活中的电容
耳机音质特别不好、有噪声的原因是耳机在制作时,滤波没有做好
3、电感(L)
1、电感是什么
电感是一个电磁感应元器件,用于抵制电流的变化(储能元器件)
电感的组成:漆包线或纱包线 骨架或磁芯或铁心
电感用字母L表示
电感的单位是H 通常直接表示电感量是有3R3(3.3uH)
单位的换算关系:1H=1000mH 1mH=1000uH 1uH=1000nH
电感在电路图中的表示方法:
2、电感的特性:通直流阻交流
3、电感的分类
按照封装形式分:贴片电感和插件电感
按照频率分:高频电感、中频电感和低频电感
按照用途分:震荡电感、隔离电感、滤波电感等等
电感的作用:
滤波
震荡
延迟
<1>电感滤波
电感和电容滤波有什么不同:
电感通直流阻交流 电流不突变(电感串联在电路当中,对电流滤波); 电容隔直通交 电压不会突变(电容并联在电路当中,对电压滤波)
当电路中电流增大时,电感就会存储能量;当电路中电流减小时,电感再把存储的能量释放出来;这样经过电感的电流就比较平缓,电感通常适用于电流比较大,而电压比较低的电路,电容适用于电压比较高,而电流比较小的电路
<2>电感震荡
能产生大小和方向都随周期发生变化的电流叫振荡电流,能产生振荡电流的电路叫振荡电路。其中最简单的振荡电路叫LC回路
单管半导体收音机电路:
<3>延迟
4、保险丝(熔断器)
1、保险的作用及工作原理
当电路如果发生短路时瞬间的电流会非常高,同时会使导电线发热。如果电路中没有熔断器来保护,那么很可能就烧坏用电设备了。
其关键部分就是熔点较低的特殊金属导线或导电片,当发生短路、过载等产生的大电流会时熔断器的导电部分升温、达到熔点熔化、断开而失去链接切断了电流。
2、保险的分类
按形式分:过电流保护和过热保护保险丝
按熔断速度分:特慢速、慢速、中速、快速、特快速
按是否可恢复:不可恢复保险和自恢复保险
3、保险的参数及选择
参数:
电压额定值、电流额定值、熔断特性、分断能力
电压额定值是断开后保险两端能承受的最大电压
电流额定值是保险在电路中能工作的最大电流
熔断特性是保险丝在不同过载电流负载下熔断的时间范围
当10被额定电流通过时,熔断时间小于0.001秒熔断的为超快速熔断器,而快速熔断器的是0.001-0.01秒,慢速为0.01-0.1秒。慢断保险丝可以允许暂时的、乌海的浪涌电流通过而不熔断,但是当持续过载或短路时,就会断开
分断能力是最主要的指标,在规定的电压下,能安全切断的最大电流
4、保险在原理图中的表示方法
5、实例:喇叭、电池
5、二极管
二极管是由PN结加上外壳和引线组成的
工作原理:
二极管特性:
- 伏安特性
- 温度特性
分类:
按照半导体材料分:锗二极管和硅二极管
按照不同用途分:检流二极管、整流二极管、开关二极管、稳压二极管
按照管芯结构分:点接触型二极管、面接触性二极管和平面二极管
按照二极管的反向恢复时间分:普通二极管和快速二极管(肖特基二极管和快恢复二极管)
用途:
普通二极管通常用于检波
整流二极管用于功率的整波
开关二极管用于计算机脉冲控制的开关电路
稳压二极管用于稳压电路
发光二极管如LED二极管
点接触二极管用于检波、检频和滤波,由于值点接触,使用语小电流高频电路,如收音机的检波
面接触型二极管用于低频整流电路,由于PN结接触面比较大,电流也比较大,可以使用几安到几十安大电流电路的整流。
二极管的参数及选型:
1、参数:
- 反向饱和和漏电流Is
- 额定整流电流If
- 最大反向工作电压Urm
- 最高工作频率fm(由于PN结结电容的存在,工作频率超过一定值时,单向导电性就变差)
- 反向工作时间trr(指二极管由导通突然方向时,反向电流由很大衰减到接近Is时所需要的时间)
2、选型:
- 依据参数和功能选型
3、二极管的测量
判断二极管的好坏:测量正反向电阻,如果反向电阻远大于正向电阻,则没有问题,如果二者相等或是无穷大或0,则说明二极管坏掉了。
一般发光二极管的测试直接用万用表就可以测试了。
6、三极管
1、三极管的定义及工作原理
基本定义:
半导体三极管又称为双极结型晶体管(BT),是一种具有三个电极的装置。实质上就是一块半导体基片上的两个的N结将其隔成基区、发射区和集电区,从而引出基极、发射机和集电极三个电极。
分类:
按结构可将其分为NPN型和PNP型。
按材质分可以分为硅管和锗管
按照频率分为低频管和高频管
按照功率分为小功率中、功率和大功率管
工作原理
2、三极管的特性曲线
3、三极管的参数及封装形式
4、用万用表判断三极管的类别和极性
5、三极管的放大电路
6、三极管的功能及应用
- 电流放大
- 控制开关
- 稳压
7、MOS管
1、什么是MOS管
mos管是一种半导体器件,其作用是把要传输的信号进行调制和解码;
mos管的作用是将输入的模拟电信号转换成数字电信号或将数字电信号转换回模拟电信号。
2、用法:
- 在电路中作为开关使用
- 作为运算放大器的负反馈使用
然后通过MOSFET(金属-氧化物-半导体场效应晶体管)把信号直接耦合到输出端。
8、按键
9、led灯
1、什么是led灯
led灯是发光二极管
10、LCD
1、什么是LCD
LCD是液晶显示器
11、蜂鸣器
1、什么是蜂鸣器
蜂鸣器是一种一体化结构的电子讯响器,
采用直流电压供电,广泛应用于电子产品中作为发声器件
2、蜂鸣器的分类
有源蜂鸣器(电磁式蜂鸣器),只需要给电源即可
无源蜂鸣器(压电式蜂鸣器),无源发出声音需要一定频率(1.5~5kHZ)的脉冲信号
有源和无源的区别在于蜂鸣器内部是否含有多谐振荡电路
3、控制蜂鸣器的声音大小(调节占控比)只有无源蜂鸣器可以调节
输出高电平时间周期长,声音就大
注:大部分音乐盒里面大部分都是无源蜂鸣器
4、蜂鸣器硬件电路(51单片机的A2-A4系列)
二、学习基本外围电路
1、三极管开关电路
1、三极管的定义和作用
三极管是一种半导体器件,常用放大和开关电路中
它由三个区域组成:基区、发射区和集电区。基区和发射区之间有一个PN结,而基区和集电区之间也有一个PN结。
2、为什么用三极管做开关电路
三极管可被用于开关这是因为它的放大特性。
在三极管的开关电路中,我们将其工作在两个状态之间:饱和和截止。当三极管处于饱和状态时,它完全导通,电流可以从集电极流向发射极。而当三极管处于截止状态时,它完全截断,电流无法从集电极流向发射极。
2、led驱动电路
3、按键检测电路
4、蜂鸣器驱动电路
通过三极管的开关和放大电路电流的功能
5、存储电路
6、LCD驱动电路
在51单片机中LCD通过一个74HC245芯片进行驱动,它可以增大IO口的输出电流
7、单片机外围电路
- 电源管理电路:用于为单片机和其它外围电路提供稳定的电源。这包括稳压电路、滤波电路和电池管理电路等。
- 时钟电路:用于提供单片机所需的时钟信号,包括晶体振荡电路、晶振驱动电路等。
- 外部存储器接口电路:用于连接外部存储器,例如闪存、SRAM、EEPROM等,通常包括地址线、数据线、控制线以及相关的驱动电路和信号调理电路。
- 通信接口电路:用于连接外部通信设备,例如UART、SPI、I2C等串行通信接口电路。
- 模拟输入/输出电路:用于连接模拟传感器或执行器,例如ADC(模数转换器)输入电路和DAC(数模转换器)输出电路。
- 数字输入输出电路:用于连接数字传感器、执行器或外部逻辑电路,例如GPIO(通用输入输出)电路和外部中断电路。
- 显示和用户交互电路:用于连接显示器、按键、LED指示灯等用户界面设备。
8、单片机常见外设
- 时钟电路:用于提供单片机所需的时钟信号。
- 存储器:包括闪存、SRAM、EEPROM等,用于存储程序代码和数据。
- 通信接口:如UART、SPI、I2C等,用于与外部设备进行串行通信。
- 模拟输入/输出:包括模数转换器(ADC)和数模转换器(DAC),用于连接模拟传感器或执行器。
- 数字输入/输出:通用输入输出(GPIO),用于连接数字传感器、执行器或外部逻辑电路。
- 显示设备:如LCD(液晶显示器)、LED数码管、OLED等,用于显示系统信息。
- 用户交互设备:如按键、触摸屏等,用于用户输入与系统交互。
- 电源管理电路:用于为单片机和外设提供稳定的电源。
- 外部中断:用于连接外部触发器,如按钮、传感器等,以便单片机能够实时响应外部事件。
注:大多数都是数字电路
三、单片机学习
51单片机
1、点亮LED灯
1、代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;sbit LED1=P2^0;void main()
{ LED1=0; //点亮while(1){}
}
2、LED闪烁
1、代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;sbit LED1=P2^0;void delay_10us(u16 ten_us) //当ten_us传1时,大约延时10us;
{while(ten_us--);
}
void main()
{ while(1){LED1=0; //点亮delay_10us(50000); //大约延时450ms,可用过软件仿真器测试一下,这是一个大概值LED1=1; //熄灭delay_10us(50000);}
}
3、LED流水灯
1、代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;#define LED_PORT P2 //使用宏定义将P2端口定义void delay_10us(u16 ten_us) //当ten_us传1时,大约延时10us;
{while(ten_us--);
}
void main()
{ u8 i=0;while(1){for(i = 0; i < 8; i++){LED_PORT=~(0x01<<i); //按位左移,其他位依旧为高电平delay_10us(50000); //延时450ms}}
}
2、代码展示,调用库函数(intrins.h)实现:
#include <reg52.h>
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;#define LED_PORT P2 //使用宏定义将P2端口定义void delay_10us(u16 ten_us) //当ten_us传1时,大约延时10us;
{while(ten_us--);
}
void main()
{ u8 i=0;LED_PORT=~0X01;delay_10us(50000);while(1){for(i = 0; i < 7; i++){LED_PORT=_crol_(LED_PORT,1); //左移delay_10us(50000);}for(i = 0; i < 7; i++){LED_PORT=_cror_(LED_PORT,1); //右移delay_10us(50000);}}
}
4、蜂鸣器
51单片机一般使用的是无源蜂鸣器(压电式蜂鸣器),可通过调节脉冲信号占控比(高电位持续时间)来改变蜂鸣器声音大小,改变脉冲周期来调节音色。
1、51单片机蜂鸣器硬件电路(A2-A4系列)
注:51单片机IO口驱动能力较弱,直接连接IO口达不到满足蜂鸣器的驱动电流(一般需要30mA以上),通常会使用三极管(三极管驱动电路)放大电路电流以达到蜂鸣器驱动电流
2、如何控制蜂鸣器发出声音
通过控制上图P2.5管脚输出一定频率的脉冲信号来控制蜂鸣器发出声音,输出脉冲信号频率在1.5~5kHZ,根据T=1/f这个公式可得,脉冲周期大概在1ms左右,如果高低电平占控比为50%,那么循环输出0.5ms的高电平和低电平就可以让蜂鸣器发声了
蜂鸣器发声代码展示:(普中-A2系列,芯片为STC89C52RC)
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;sbit BEEP=P2^5; //根据各自单片机原理图IO口名称命名void delay_10us(u16 ten_us) //当ten_us传1时,大约延时10us;
{while(ten_us--);
}
void main()
{ u16 i=5000;while(1){ while(i--){
// BEEP=!BEEP;
// delay_10us(100);
// 通过控制高电平的占控比来改变蜂鸣器声音大小,高电平占控比越大,声音越大BEEP=0;delay_10us(50);BEEP=1;delay_10us(150);}i=0;BEEP=0; }
}
5、静态数码管实验
1、数码管介绍
分为共阳极数码管和共阴极数码管,数码管其实也是发光二极管
共阳极数码管,阳极端连接在一起,通过对对应端输入低电平点亮
共阴极数码管,阴极端连接在一起连接GND接地端,通过对对应端输入高电平点亮
2、数码管显示原理图:
3、数码管段选和位选
74HC245芯片控制数码管段选,从而控制数码管显示的数字
74HC138译码器通过控制数码管位选,从而控制哪一个数码管显示数字
4、38译码器
看芯片手册时,管脚说明和真值表很重要!!!!
直接决定了芯片的功能和使用控制方法
减少IO口的占用,八个数码管LED口只需要三个IO口就能完成连接
5、推荐使用动态数码管,不推荐使用静态数码管
因为每个动态数码管的段选线并联,八个动态数码管只需要占用八个IO口即可(节约资源),通过人眼视觉差,让人觉得所有数码管都在显示,实际上同一时间只有一个数码管显示
而静态数码管每段端口单独与一个IO口连接,每个数码管八段,四个数码管就需要32个IO口,而51单片机IO口一共才32个,这显然不行。
6、硬件设计
数码管通过74HC245驱动芯片增大IO口电流,驱动电路
7、软件设计
代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;#define SMG_A_DP_PORT P0u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴0-F
void main()
{ SMG_A_DP_PORT=gsmg_code[15]; while(1){ }
}
6、动态数码管显示
1、数码管动态显示原理
动态显示是利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据来实现的
位选控制哪一个数码管显示,段选线控制显示的数字内容
每个动态数码管的段选线是并联在一起的
2、代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;#define SMG_A_DP_PORT P0sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴0-Fvoid delay_10us(u16 ten_us) //当ten_us传1时,大约延时10us;
{while(ten_us--);
}
void main()
{ while(1){ u8 i=0;for(i=0;i<8;i++){switch(i) //控制哪一个LED数码管显示{case 0:LSC=1;LSB=1;LSA=1;break;case 1:LSC=1;LSB=1;LSA=0;break;case 2:LSC=1;LSB=0;LSA=1;break;case 3:LSC=1;LSB=0;LSA=0;break;case 4:LSC=0;LSB=1;LSA=1;break;case 5:LSC=0;LSB=1;LSA=0;break;case 6:LSC=0;LSB=0;LSA=1;break;case 7:LSC=0;LSB=0;LSA=0;break;}SMG_A_DP_PORT=gsmg_code[i]; //控制显示得数字delay_10us(100); //延时一秒,从视觉效果上让人感觉是八个数码管同时显示}}
}
7、独立按键实验
1、独立按键介绍
注意实际波形在按键按下和释放时会有抖动,导致电平信号不稳,可以设置延时
1、代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;sbit LED1=P2^0;sbit KEY1=P3^1; //定义独立按键
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0void delay_10us(u16 ten_us)
{while(ten_us--);
}u8 key_scan(u8 mode)
{static u8 key=1;if(mode)key=1;if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)){delay_10us(1000); //消抖处理key=0; if(KEY1==0)return KEY1_PRESS;else if(KEY2==0)return KEY2_PRESS;else if(KEY3==0)return KEY3_PRESS;else if(KEY4==0)return KEY4_PRESS;}else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1){key=1;}return KEY_UNPRESS;
}void main()
{ u8 key=0;while(1){key=key_scan(1);if(key==KEY1_PRESS)LED1=!LED1;}
}
8、矩阵按键实验
实现功能:矩阵按键按下S1-S16,数码管输出0-F的值
1、矩阵按键电路图:
2、矩阵按键行列式代码实现
通过每次设置按键的某一列位低电平,再判断按键按下是哪一行。
例如:设置第一列为低电平,则P13为低电平0,其他为高电平,即P1这个IO组的二进制为1111 0111对应的16进制为0xf7,当第一列某一行按键被按下,P17-P14某一行就会变成低电平0,P1这个IO组的二进制将不再等于0xf7,根据P1组的二进制可以判断出是第一列的哪一行被按下。以此类推第二列-第四列也是如此
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;#define KEY_MATRIX_PORT P1
#define SMG_A_DP_PORT P0u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴0-Fvoid delay_10us(u16 ten_us)
{while(ten_us--);
}u8 key_matrix_ranks_scan(void) //按键_矩阵_行_扫描
{u8 key_value=0;KEY_MATRIX_PORT=0xf7; //将第一列设置为低电平if(KEY_MATRIX_PORT!=0xf7){delay_10us(1000); //消抖switch(KEY_MATRIX_PORT){case 0x77: key_value=1;break;case 0xb7: key_value=5;break;case 0xd7: key_value=9;break;case 0xe7: key_value=13;break;}}while(KEY_MATRIX_PORT!=0xf7); //等待按键松开KEY_MATRIX_PORT=0xfb; //将第二列设置为低电平if(KEY_MATRIX_PORT!=0xfb){delay_10us(1000); //消抖switch(KEY_MATRIX_PORT){case 0x7b: key_value=2;break;case 0xbb: key_value=6;break;case 0xdb: key_value=10;break;case 0xeb: key_value=14;break;}}while(KEY_MATRIX_PORT!=0xfb); //等待按键松开KEY_MATRIX_PORT=0xfd; //将第三列设置为低电平if(KEY_MATRIX_PORT!=0xfd){delay_10us(1000); //消抖switch(KEY_MATRIX_PORT){case 0x7d: key_value=3;break;case 0xbd: key_value=7;break;case 0xdd: key_value=11;break;case 0xed: key_value=15;break;}}while(KEY_MATRIX_PORT!=0xfd); //等待按键松开KEY_MATRIX_PORT=0xfe; //将第四列设置为低电平if(KEY_MATRIX_PORT!=0xfe){delay_10us(1000); //消抖switch(KEY_MATRIX_PORT){case 0x7e: key_value=4;break;case 0xbe: key_value=8;break;case 0xde: key_value=12;break;case 0xee: key_value=16;break;}}while(KEY_MATRIX_PORT!=0xfe); //等待按键松开return key_value;
}void main()
{ u8 key=0;while(1){key=key_matrix_ranks_scan();if(key!=0)SMG_A_DP_PORT=gsmg_code[key-1];}
}
3、矩阵按键线翻转扫描代码实现:
先设置所有行位低电平,即P1为0x0f;判断按下按键的位置是在哪一列(列扫描),
然后再将所有列位设置为低电平,即P1为0xf0;判断按下按键的位置是在哪一行(行扫描)
最后判断出按下的按键位于哪一行那一列,在控制数码管显示对应的数据
代码展示:
#include <reg52.h>typedef unsigned char u8;
typedef unsigned int u16;#define KEY_MATRIX_PORT P1 //定义矩阵按键
#define SMG_A_DP_PORT P0 //定义数码管IO口u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴0-Fvoid delay_10us(u16 ten_us)
{while(ten_us--);
}u8 key_matrix_flip_scan(void) //线翻转式
{static u8 key_value=0;KEY_MATRIX_PORT=0x0f;if(KEY_MATRIX_PORT!=0x0f) //测试是否有按键按下{delay_10us(1000); //消抖if(KEY_MATRIX_PORT!=0x0f) //测试{KEY_MATRIX_PORT=0x0f; //测试列switch(KEY_MATRIX_PORT){case 0x07: key_value=1;break;case 0x0b: key_value=2;break;case 0x0d: key_value=3;break;case 0x0e: key_value=4;break; }//测试行KEY_MATRIX_PORT=0xf0;switch(KEY_MATRIX_PORT){case 0x70: key_value=key_value;break;case 0xb0: key_value=key_value+4;break;case 0xd0: key_value=key_value+8;break;case 0xe0: key_value=key_value+12;break;}while(KEY_MATRIX_PORT!=0xf0); //等待按键松开} }elsekey_value=0;return key_value;
}void main()
{ u8 key=0;while(1){key=key_matrix_flip_scan();if(key!=0)SMG_A_DP_PORT=gsmg_code[key-1];}
}
9、IO扩展(串转并)
STM32
ARM
更多推荐
单片机入门学习路线
发布评论