51单片机学习笔记
模块化编程
把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其他.c文件想使用其中的代码时,只需要#include "XXX.h"
文件即可。使用模块化编程可极大地提高代码的可阅读性、可维护性、可移植性等。
- xxx.c给主函数并不需要把所有东西都包含进去,而只需要包含函数的声明;则在各种.h文件中放的是它对应的.c文件需要被外部调用的这些接口;
- Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
- main.h
#include "Delay.h"
void main()
{
Delay(10);
}
注意事项
.c文件:函数、变量的定义;
.h文件:可被外部调用的函数、变量的声明
- 任何自定义的变量、函数在调用前必须有定义或声明(同一个.c)
- 使用到的自定义函数的.c文件必须添加到工程参与编译
- 使用到的.h文件必须要放在编译器可寻找到的地方(工程文件夹根目录、安装目录、自定义)
- <>与“”的区别:
<>是在安装目录里面寻找文件,而""是在自己的程序目录里面寻找
c预编译
-
C语言的预编译以#开头,作用是在真正的编译开始之前,对代码做一些处理
-
此外还有
#ifdef
,#if
,#else
,#elif
,#undef
等
预编译 | 意义 |
---|---|
#include<REGX52.h> | 把REGX52.h文件的内容搬到此处 |
#define PI 3.14 | 定义PI,将PI替换为3.14 |
#define ABC | 定义ABC |
#ifndef XX_H | 如果没有定义__XX_H__ |
#endif | 与#indef,#if相匹配,组成“括号” |
LCD1602调试工具
- 使用LCD1602液晶屏作为调试窗口,提供类似printf函数的功能,可实时观察单片机内部数据的变换情况,便于调试和演示;
- LCD1602代码属于模块化的代码,使用者只需知道所提供函数的作用和使用方法即可使用LCD1602;
- 数码管的一个缺点是需要不断地扫描,一旦扫描不及时数码管就会闪烁;
- 串口把数据发到电脑上让电脑观察 ,缺点是需要不断地打开串口
- P2口的三个引脚与LED的引脚有冲突;则使用液晶屏后无法使用数码管和三个LED
- 头文件:
#include "LCD1602.h"
(不区分大小写)
LCD_ShowNum();
当指定数字长度小于数字长度,则数字不完全显示;当大于时,则高位补0;
矩阵键盘
- 在键盘中案件数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
- 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态
扫描的概念
-
数码管扫描(输出扫描)
原理:显示第一位—>显示第二位—>显示第三位—>……,然后快速循环这个过程,最终实现所有数码管同时显示的效果; -
矩阵键盘扫描(输入扫描)
原理:读取第一行(列)—>读取第二行(列)—>读取第三行(列)—>……,然后快速循环这个过程,最终实现所有按键同时检测的效果; -
以上两种防水的共性:节省I/O口
-
由于P15口连接问题,则逐行扫描时蜂鸣器会响;则逐列扫描
弱上拉模式
具有较弱的拉高电平或电位的能力,虽然弱但够用;
输出1的驱动能力是有限的,输出0驱动能力是比较强的
P0、P1、P2、P3都是一种弱上拉模式
定时器
定时器属于单片机内部资源,其电路连接和运转均在单片机内部完成
- 定时器作用
(1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
(2)替代长时间的Delay,提高Cpu的运行效率
定时器资源
- 定时器个数:3个(T0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源(89C52)
- 定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的
- 定时器根据时钟的输出信号,每隔“一秒”,计数单元数值就会加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生提醒,使程序跳转到中断服务函数中执行
定时器工作模式
- STC89C52的T0和T1均有四种工作模式:
模式0:13位定时器/计数器
模式1:16位定时器/计数器
模式2:8位自动重装模式
模式3:两个8位计数器
模式一
- 计数系统可计两个字节,高字节叫TH,低字节叫TL
- 每一个脉冲使计数系统加一,当加到可存储的最大数时,下一个脉冲会使计数系统溢出变为0,并制一个标志位TF0(time of flag),有这个标志位,就会向中断系统申请中断
- TR0控制时钟启动或暂停
- SYSclk:系统时钟、即晶振周期,本开发板的晶振为12MHz
当由外部引脚来提供时钟时,定时器为一个计数器
- 给1则为计数器,给0为计时器
中断系统
-
是使CPU具有对外界紧急事件的实时处理能力而设置的
当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回来到原来被中断的地方,继续原来的工作 -
中断嵌套
当CPU正在处理一个中断时,发生了另一个优先级更高的中断,则会先执行此中断;
STC89C52中断资源
- 中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、外部中断2、外部中断3)
- 中断优先级个数:4个
- 中断号
定时器相关寄存器
- 寄存器是连接软硬件的媒介
- 在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式
- 寄存器相当于一个复杂机器的“操作按钮”
void Timer0_Init()//1微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xFF; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
串口通信
- 串口是一种通讯接口,可实现两个设备的互相通信
- 51单片机内部自带UART,可实现单片机 的串口通信
硬件电路
- 简单双向串口通信有两根通信线(发送端TXD和接收端RXD)
- TXD和TRD要交叉连接
- 当只需要单向的数据传输时,可以直接一根通信线
- 当电平标准不一致时,需要加电平转换芯片
电平标准
- 电平标准是数据0和1的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准如下:
- TTL电平:+5V表示1,0V表示0;
- RS232电平:-3V~ -15V表示1,+3V~+15V表示0
- RS485电平:两线压差+2~+6V表示1,-2 ~-6V表示0(差分信号 )
常见通信接口比较
名称 | 引脚定义 | 通信方式 | 特点 |
---|---|---|---|
UART | TXD、RXD | 全双工、异步 | 点对点通信 |
I^2C | SCL、SDA | 半双工、同步 | 可挂载多个设备 |
SPI | SCLK、MOSI、MISO、CS | 全双工、同步 | 可挂载多个设备 |
1-Wire | DQ | 半双工、异步 | 可挂载多个设备 |
- 相关术语
全双工:通信双方可以在同一时刻互相传输数据
半双工:通信双方可以互相传输数据,但必须分时复用一根数据线
单工:通信只能有一方发送到另一方,不能反向传输
异步:通信双方各自约定通信速率
同步:通信双方靠一根时钟线来约定通信速率
总线:连接各个设备的数据传输线路(类似于一条马路,把路边各
住户连接起来,使住户可以相互交流)
51单片机的UART
- STC89C52有1个UART
- 有四种模式
模式一:8位UART,波特率可变 - 波特率:串口通信的速率(发送和接收各数据位的间隔时间)
- 检验位:用于数据验证
- 停止位:用于数据帧间隔
- 串口模式图
- SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入是发送寄存器,读操作时,读出的是接收寄存器
- 串口中断用4
void UART_Routine() interrupt 4
- 只要RI>=1或者TI>=1就会触发串口中断。前提是程序打开了总中断和串口中断。
- 串口在接收到数据之后,硬件会自动将RI=1
数据显示模式
- HEX模式/十六进制模式/二进制模式:以原始数据的形式显示
- 文本模式/字符模式:以原始数据编码后的形式显示
LED点阵屏
- LED点阵屏是由若干个独立的LED组成,LED以矩阵的形式排列
- LED点阵屏分类
按颜色:单色、双色、全彩
按像素:8*8等
显示原理
- LED点阵屏的结构类似数码管
- 有共阴共阳两种接法,不同的接法对应的电路结构不同
- LED点阵屏需要进行逐行或逐列扫描,才能使所有LED同时显示3
74HC595
- 74HC595是串行输入并行输出的移位寄存器,可用三根线输入串行数据,8根线输出并行数据,多片级联后,可输出16 、24、32位等,常用于IO口扩展
SER:串行数据
SERCLK:上升沿移位
RCLK:上升沿锁存
QH:多片级联
DS1302
- RTC(real time clock):实时时钟,是一种集成电路通常称为时钟芯片
引脚名 | 作用 | 引脚名 | 作用 |
---|---|---|---|
VCC2 | 主电源 | CE | 芯片使用 |
VCC1 | 备用电池 | IO | 数据输出/输入 |
GND | 电源地 | SCLK | 串行时钟 |
X1、X2 | 32.768kHz晶振 |
内部结构图
- CE为高电平时,I/O口和SCLK才有效
寄存器定义
- WP:置1时其他操作无效
- 命令字有八个字节,最高位7固定为1;
- 要操作RAM的话,第六位给1,给0则不是
- 第0位给1为读(RD),给0为写(wr)
时序定义
- CE:操作时能,操作时给1
- SCLK给一个固定的始终
- 时钟上升沿时要写入数据,下降时读出时钟芯片的数据
BCD码
- 用4位二进制数来表示1位十进制数
例:0001 0011表示13 ,1000 0101表示85, 0001 1010不合法 - 在十六进制中的表现:0x13表示13,0x85表示85,0x1A不合法
- BCD码转十进制:DEC=BCD/16*10+BCD%16(两位BCD)
- 十进制转BCD码:BCD=DEC/10*16+DEC%10(两位BCD)