1.LED模块
- 发光二极管的作用:指示作用;
- 发光二极管的参数计算:
I R = U i − U o n R \ I_R = \frac{U_i - U_{on} }{ R}\, IR=RUi−Uon, 根据导通电流算出电阻值,根据电阻值算出电流值;(LED 的导通压降为 1.5V)
假设:给定电流值为5mA,电压值为5V,求出电阻的大小。
way:套入公式,R = (5V - 1.5V) / 5mA = 700Ω.
当然,如果题目只给了电压值,那就默认1KΩ.(一般仿真用到给LED的电阻都是1KΩ的)
-
发光二极管的特性:
单向导电性 (正向导通,反向截至); -
发光二极管串联电阻的作用:
限流作用; -
发光二极管的控制类型:
LED 是电流型控制器件,
因为 LED 的照明量是由流过他的电流量决定的; -
用到的门电路:
74HC02 或非门; -
74HC138(译码器)的作用:
- 选中锁存器;
- 低电平有效,CBA (27/26/25) 逻辑排序;
-
74HC537(锁存器)的作用:
- 拓展 IO 口;
- 满足电流大小(其每一个引脚最大能输出 ±35mA 电流);
- 当引脚 LE 为高电平时,输入 D1 ~ D8 传输到 Q1 ~ Q8;
当引脚 LE 为低电平时,输出保持不变,锁存当前输出信号;
(输入或锁存信号)
-
共阴共阳的概念:
共阴:将LED的负极通过电阻并联在一起,靠分别控制LED的正极来点亮模块,LED高电平有效;
共阳,将LED的正极通过电阻并联在一起,靠分别控制LED的负极来点亮模块,LED低电平有效;
- 代码:LED 从左往右,循环点亮,时间间隔 1s:
//从左往右
//char排序:0/1/2/3/4/5/6/7
//LED分布: 7/6/5/4/3/2/1/0
//所以要使得LED从左往右点亮,则要让char从右往左移动————
for(i = 0;i < 8;i ++){
LED_display(0x01<<i);
Delay(1000);
}
- delay 函数:
注意是 628.
void delay(unsigned int num){//最小约1ms@12MHz
unsigned int i;
while(num --)
for(i = 0;i < 628;i ++);
}
2.数码管
- 共阴共阳数码管编写:
给出共阳段码值,推出共阴段码值;
给定共阳数码管显示'0' 的段码值为 0xC0 (1100 0000)(说明a-dp的排列顺序),求出其对应共阴段码值。
//所以数码管char排序为:dp,g,f,e,d,c,b,a.
答:共阴0为0x3F(0011 1111)(按位取反)
- 静态显示和动态显示的区别:
静态,数码管的笔画点亮后,这些笔画就一直处于点亮状态,而不是处于周期性点亮状态,直到新的字形码送入才会发生变化
动态,通过分时轮流送出字形码和相应的位选,使各个数码管轮流受控显示。在轮流显示过程中,每位元数码管的点亮时间为 1~2ms,由于人的视觉暂留现象及发光二极体的余晖效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示资料,不会有闪烁感;
- 段选和位选的概念:
位选,选中不同数码管;
段选,使数码管点亮不同字型; - 四位一体数码管:
四位数码管,段码值共享,每位都有位选值; - sprintf 函数:
将数据(char/int/string 等等)以字符串的形式打印到指定数组中。
#include<stdio.h>
int main()
{
char str [40];
sprintf (str,"%s%d%c","date",1,'2'); /* 第一个参数就是指向要写入的那个数组的指针,剩下的就和 printf () 一样了
}
- switch 语句
switch(i){
case 1:j = 1;break;
default:j = 0;
}
3.按键
- 按键的工作特性:
按键一般在电路中作为输入器件;
按键有两种状态:按下和弹起; - 按键工作原理:
通过实现线路的导通和断开来判断是否按下;
对于一组键或一个键盘,总有一个接口电路与 CPU 相连。
CPU 可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,
将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,
执行完成后再返回主程序。
@码农小范 ——51 单片机之独立按键和矩阵键盘(概念及原理)
- 独立按键与矩阵按键区别(优缺点,适用场景,检测方法):
独立按键:
(优点:电路配置灵活,软件结构简单,占用时间少,每个按键的工作不会影响其他 I/O 口线的状态,单片机只需要检测IO状态就能识别出按键是否按下)
(缺点:每个按键必须占用一个 I/O 口线,占用IO口资源多)
(适用场景:按键较少的场景)
(检测方法:查询法和中断法)
矩阵按键:
(优点:利用8个单片机的IO口资源实现16个按键键码的识别,极大提高了单片机IO口的利用率)
(缺点:编程复杂,占用时间多,当同时按下超过两个按键,就会按键判断错误的情况。)
(适用场景:按键较多的场景)
(检测方法:扫描法)
-
独立按键与矩阵按键的选择:
J5 通过跳线帽连接 (1,2),选中矩阵按键;
J5 通过跳线帽连接 (2,3),选中独立按键; -
掌握识别矩阵按键的原理
原理:
当无按键闭合时,P3.0~P3.3 与 P3.4~P3.7 之间开路。当有键闭合时,与闭合键相连的两条 I/O 口线之间短路。
判断有无按键按下的方法是:- 第一步,置列线 P3.4 ~ P3.7 为输入状态,从行线 P3.0 ~ P3.3 输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。
- 第二步,行线轮流输出低电平,从列线 P3.4~P3.7 读入数据,若有某一列为低电平,则对应行线上有键按下。综合一二两步的结果,可确定按键编号。
注意:
STC89C52 系列单片机 WR 和 RD 引脚为 P36 和 P37;
IAP15 系列单片机 WR 和 RD 引脚为 P42 和 P44; - 第一步,置列线 P3.4 ~ P3.7 为输入状态,从行线 P3.0 ~ P3.3 输出低电平,读入列线数据,若某一列线为低电平,则该列线上有键闭合。
-
按键消抖原因与原理:
原因:防止误触发;
原理:延时一段时间再做一次按键判断;
4.蜂鸣器
- 蜂鸣器的工作原理:
当电磁式蜂鸣器在接通电源以后,振荡器所产生的音频信号电流就会通过电磁线圈,使得电磁线圈产生磁场,那么这时振动膜片就会在电磁线圈和磁铁的相互作用下,周期性地发生振动了。
@jiangchao3392—— 蜂鸣器详解 - 蜂鸣器的有源和无源的区别:
是否自带震荡电路,有则直接给低电平,无源要用方波驱动; - ULN2003 (非门) 的工作方式:
非门,输入高电平,输出低电平; - 蜂鸣器驱动:
低电平有效;
(要让 P06 = 1,通过非门,使得 N BUZZ 为 0)
5.外部中断
-
中断执行流程
-
中断方式与查询方式的区别
- 查询方式:响应较慢,可能会由于延时而漏掉事件;
- 中断方式:优先响应,响应更快,更及时,不会漏掉任何事件;
-
开启外部中断的代码顺序
void INT0_Init(void){ //这个函数名其实可以随便写啦,只是这样更好看
IT0 = 1; //只能下降沿触发 或IT0 = 0;//上升沿或下降沿均可触发
EX0 = 1; //开启外部中断0中断
EA = 1; //开启总中断
}
-
中断优先级、中断嵌套
默认优先级由高到低为:
外部中断 0,定时器 0,外部中断 1,定时器 1,串行中断 0;
中断嵌套(举例):
执行外部中断 1 时,若外部中断 0 满足条件,则先去执行外部中断 0 的代码,再回来执行外部中断 1,最后回到主函数; -
外部中断管脚复用:
- 外部中断 0:与 P3.2 管脚复用,对应按键 S5;
- 外部中断 1:与 P3.3 管脚复用,对应按键 S4;
-
设计外部中断服务函数的要点
i. 无输入参数和返回值;(都为 void 类型)
ii. 中断号;
6.定时器
- 定时器与计数器的区别
内部脉冲计数还是外部脉冲计数; - 定时器的计算方式
假设设置初始值为 64536,需要一个定时器时钟加入中断;
- 设置初值:
65536 - count,count 为计数次数,65536-count 为寄存器设置值;
要设置的寄存器的值为 64536,算出 TH0 和 TL0;
way1:64536 / 256 整数部分为 TH0,小数部分为 TL0;
way2:64536 转换为二进制,然后高八位为 TH0,低八位为 TL0;) - 定时 1ms:
分频值(1、12,选择 12 分频)与重装值(1000),默认工作频率为 12MHz,分频后为 1MHz,1us 记一次数.count 设为 1000.
- 设置初值:
void Timer0(void){//1us@12MHz
AUXR |= 0x80;//设置12分频
TMOD &= 0xF0;//软件启动,定时器模式,工作模式1
TH0 = (65536 - 1000) / 256;//1us
TL0 = (65536 - 1000) % 256;
TF0 = 0;//清除溢出位
TR0 = 1;//开启计数
ET0 = 1;//开启定时器中断
EA = 1; //开启总中断
}
-
定时器最大定时时间: 1 u s ∗ 65536 \ 1us*65536\, 1us∗65536(@1MHz)
推导过程:
因为定时器的计数溢出为 65536 (int 最大值为 65535),计数从 65536 - count 计到 65536,要使得定时时间最大,则 65536 - count 最小,则只要让 count 为 65536,此时计数范围为 0 到 65536, 则计数 65536 次;
因为系统时钟为 1MHz,则每秒产生 1M 个脉冲信号,则每个脉冲信号所需的时间为 1 1000000 s = 1 u s \ \frac{1 }{1000000} s= 1us\, 10000001s=1us ,则最大定时时间为 65536 ∗ 1 u s \ 65536*1us\, 65536∗1us. -
如何输出脉冲信号 (定时器功能,周期,占空比)
输出周期 100ms,占空比 50% 的信号,P00 输出;
way: 设置 10us 进一次中断,进 10 次,if(count < 5 )P00 = 1;else P00 = 0;
if(++count == 10)count = 0;
输出周期 100ms,占空比 56% 的信号,P00 输出;
way: 设置 1ms 进一次中断,进 100 次,if(count < 56 )P00 = 1;else P00 = 0;
if(++count == 100)count = 0;
输出周期 100ms,占空比 56.9% 的信号,P00 输出;
way: 设置 100us 进一次中断,进 1000 次,if(count < 569 )P00 = 1;else P00 = 0;
if(++count == 1000)count = 0;
-
如何测量脉冲信号(计数功能,频率计)
两个定时器,一个定时,一个计数;
思路:
把其中一个定时 / 计数器设置为计数器模式,另外一个设置为定时器模式。一个读取外部脉冲数,另外一个确定 1s 时间,每过一秒钟读取当前的计数值,计数值就是频率值。 -
寄存器作用:
- TMOD(工作模式寄存器):
作用:控制定时器 / 计数器的模式(启动模式、定时器 / 计数器模式、工作模式);
不可位寻址; - TCON(中断控制寄存器):
作用:控制定时器的启动、停止,标志定时器溢出和中断情况;
可位寻址; - IE(中断允许寄存器):
作用:开启中断;
可位寻址; - TH,TL(计数值寄存器):
记录当前定时器的计数值;
@ab6326795—— 单片机定时器 TMOD 与 TCON 详解! - TMOD(工作模式寄存器):
-
定时器的两大功能:
1. 产生定时器中断;
2. 不利用定时器中断,P3.5 引脚输出脉冲波; -
例题:产生定时器时间为 50ms 时间,请写出程序设计思路,并推导出 TH 和 TL 的值。
思路:要产生定时器时间为 50ms,假定系统时钟为 1MHz,则每个脉冲为 1us,要产生定时器时间 50ms,只需要计数 50 000 次,即 count = 50 000,
则 TH = (65536 - 50 000) / 256;
TL = (65536 - 50 000) % 256;
若要产生 1s 定时器时间,则只要设置初值为 1*10^n ms, 然后在服务函数里计数就行了。
注意:
服务函数里的变量最好设置为unsigned int
类型,因为unsigned char
类型最大值只有 255.
void Timer0(void) interrupt 1{//前提:定时器设置初值为1ms
unsigned int t;
if(++ t == 1000){
******//要执行的代码
t = 0;//注意把这步写后面,可以更精确
}
}
- 例题:使用定时器,但不使用定时器中断,输出频率为 100MHz 的方波信号,写出逻辑设计思路。
思路:
设置 TH、TL,在主函数里判断溢出,若溢出则将输出方波信号的 I/O 引脚上的电平翻转即可。
#include<reg52.h>
void main() //10毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xF0; //设置定时初值 10ms
TH0 = 0xD8; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
P3^5 = 1;
while(1){
if(TF0 == 1){
P3^5 = ~P3^5;
TH0 = 0xF0;
TL0 = 0xD8;
TF0 = 0;
}
}
7.串口
- 串行通信与并行通信的区别
串行:控制复杂,传输速度慢,运用管脚少,适用有距离通信;
并行:控制简单,传输速度快,传输线多,适用短距离通信; - 同步通信与异步通信的区别
1. 同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节。
2. 同步通信效率高;异步通信效率较低。
3. 同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。
4. 同步通信可用于点对多点;异步通信只适用于点对点。 - 通信传输方式:单工,半双工,全双工;
- 串口通信协议格式
起始位 1bit、数据位 8bit(先发低位)、校验位(奇偶)1bit、停止位 1bit;
69页引导问题2,第二问————
发送数据为100,低位在前,高位在后,采用偶校验,写出发送二进制数,并画出波形。
100 ->(二进制) 0110 0100 -> (低位在前)0010 0110
二进制数: 0 00100110 1 1
起始位 数据位 校验位 停止位
- 波特率
4800bps(bit per second 每秒传输位数)
1 4800 s \ \frac{1}{4800}s\, 48001s(每位所需时间)
计算公式: 溢 出 率 = 65536 − 3 ∗ 1 0 6 波 特 率 \ 溢出率 = 65536 - \frac {3*10^6}{波特率} \, 溢出率 =65536−波特率 3∗106 - CH340 的作用:
把 USB 协议数据转化成串口协议数据 - 串口的配置
void Uart_Init(unsigned int baud)
{
SCON = 0x50;//8位数据,可变波特率
T2H = (65536 - 3E6/baud) / 256; //设定定时初值 0xFD
T2L = (unsigned int)(65536 - 3E6/baud) % 256; //设定定时初值 0x8F
AUXR &= 0xF7;
AUXR |= 0x15;
/*
允许定时器2开始计数
不分频
选择定时器2作为波特率发生器
*/
ES = 1;//允许串口中断
EA = 1;//允许总中断
}
- 小题目:接收 0xAA,发送 0x55
void uart_1(void) interrupt 4
{
unsigned char dat;
if(RI){
RI = 0;
dat = SBUF;
if(dat == 0xAA){
SBUF = 0x55;
while(TI == 0);//等待发送完毕
TI = 0;
}
}
}
8.ADC的概念
- ADC 和 DAC:
模拟量转换成数字量,数字量转换成模拟量; - ADC 位数与精度:
10 位(0-1023),测量的是 5V 电压,位数是 10 位,精度为 5/1024 = 0.00488v - 模数转换公式:
10 位,A/5.0 = D/1024
9.复位电路
- 硬件复位:
RST 外部复位,上电复位; - 单片机最小单元:
单片机、晶振电路、复位电路