51总结
一般单片机内部有两种类型的存储器,分别是数据存储器(RAM)和程序存储器(ROM),我们用IPS下载线下载的程序存储在ROM空间里,在单片机运行程序的时候,程序中的变量储存在RAM空间里。
存储类型说明表:
存储类型 操作区域 寻址范围
data 字节寻址片内RAM 片内RAM的128B
bdata 可位寻址片内RAM 16B,从0x20到0x2F
idata 所有片内RAM 256B,从0x00到0xFF
pdata 片外RAM 256B,从0x00到0xFF
xdata 片外RAM 64K, 从0x00到0xFFFF
code ROM存储器 64K, 从0x00到0xFFFF
在C语言编程时,每一个常量都放在都会存放在ROM空间,而存放在RAM空间基本是变量
存储类型举例如下:
data unsigned char a; //定义字符类型变量a,变量存放在片内RAM空间
pdata unsigned int b; //定义整型变量b , 变量存放在片外RAM空间
code unsigned char ab[]={}; //数组ab保存在ROM空间
data unsigned char abc[8]; //数组abc定义8个字符类型变量,保存在片内RAM的前128B
8051 单片机内部结构示意图
SFR,特殊功能存储器具有128个字节,每个字节8个位,位于RAM空间的特殊位置。单片机内部所有功能电路,包括I/O接口,UART,ADC,PWM,EEPROM,定时/计数器等都由SFR控制,他是单片机里独一无二的控制台,我们用程序控制SFR的存储状态,这些状态以开关量来控制各种电路工作,SFR是片内RAM的一部分,可是SFR与0x80到0xFF的地址相同,读写SFR需要特殊的语句来操作,下表是3种代表性的操作方法例子
在0x90地址上是中断控制寄存器IE,它由8个开关组成,每一个开关都有自己的功能,都可以独立操作,初始值都是0,既单片机所有中断都是不允许的,EA是单片机的总中断开关,相当于电源的总开关,
当EA位为1时单片机才允许所有中断响应,EA位为0时所有中断都不允许。EADC是A/D转换中断开关,ES是UART串口中断开关,ET1是定时/计数器1中断开关,EX1是外部中断1开关,ET0是定时/计数器0中断开关,EX0是外部中断0开关,假如我们想使用串口中断,我们只要在程序中出现“ES=1; EA=1; ”或“IE=0x90;(10010000)”,串口中断就启动了。
硬件被SFR控制,硬件也可以改变SFR的开关状态,列如I/O接口P1.7写入1对应的开关位为高电平,这时P1.7外接按键与GND短接,开关位也会随P1.7拉低为低电平而变成0,读SFR的状态也就是读取硬件的状态
关键字 功能 举例
sfr[自定义名] = [SFR地址] 按字节定义SFR sfr P1=0x90;
sbit[自定义名] = [SFR位名] 按位定义SFR sbit KEY=P1^7;
单片机I/O接口部分SFR
通过PxM0和PxM1(x表示端口的数字0,1,2,3,4)两个寄存器的组合可以有4种状态,分别对应不同工作方式
在编程时首先要加载STC11Fxx.h的头文件,因为STC单片机官方给出的头文件中有I/O接口工作状态设置的定义
例如我们对1/O接口的工作方式做出如下设置。即表示P1接口中,P1.7到P1.4为标准双向输入/输出接口,P1.3为推挽工作输出接口,
P1.2为高阻态输入接口,P1.1为标准双向输入/输出接口,P1.0为开漏状态接口。具体设置可以对照STC单片机的SFR数据表。注意
P4SW寄存器对应位设置为1时,则此引脚才可作为P4接口使用,否则将作为外部复位或其他功能。
P1MO = 0x09; //00001001
P1M1 = 0x05; //0000 0101
2.中断
5个中断源中有2个是外部中断接口INTO和INT1, 2个定时/计数器TO和T1, 1个UART串口。中断编号在单片机编程时会用到,用编号来区别中断源。
优先级是指在2个或2个以上中断同时出现时,哪一个有优先中断的权力。有一个中断优先级寄存器可以调整优先级关系,可惜不是很常用,因为同
时出现多个中断的时候真的太少了,而CPU-旦进去了中断处理程序就会关闭其他的中断请求,直到处理完成。
实现中断功能需要以下两个条件
打开总中断(EA)和对应功能的中断允许位
编写中断处理程序,确定中断编号和通用寄存器1组
在中断允许寄存器IE中,EA是单片机总中断开关,相当于电源的总开关。当EA位为1时,单片机才允许所有的中断响应;当EA位为0时,
所有的中断都不允许ES是UART串口中断开关,串口收到数据时产生中断:ET1, ET0是定时/计数器中断开关,当定时或计数的值超出素加
存储器的最大值时产生中断:EX1: EX0是外部中断开关,当INT1和INTO引脚(与P3.3和P3.2复用)由高电平跳变为任电平时产生中断。假设
我们想使用UART串口中断,我们只要在程序中出现"ES=1; EA=1:"或"IE = 0x90;( 1001 0000),串口中断功能被允许使用了。
IP是中断优先级寄存器,PS. PT1、 PX1、PT0. PX0分别对应UART串口、定时/计数器1、外部中断1、定时/计数器0.外部中断0。相应位置1,
其优先变成最高优先级。空着的位是为以后扩展预留的,新款的STC单片机占用了一些预留位,实现了ADC和低电压中断功能。在配书资料的
附录B中的SFR表中,还出现了1E2和IP2的寄存器组,这是因为STC新增加的中断已经超过了8个,在SFR表中用另一组寄存器来装载了 。
在main函数开始处加入如下的语句就可以允许或禁止相应的中断源产生中断。
EA = 1; //允许总中断
ES = 1; //允许UART串口的中断
EX1 = 1; //允许外部中断1的中断
ET1 = 1; //允许定时/计数器1的中断
PX1 = 1; //外部中断1为最高优先级
EX1 = 0; //禁止外部中断1的中断
ET0 = 0; //禁止定时/计数器0的中断
中断是一个非正常事件,所以它有特殊的函数形式。
返回值类型 函数名 (参数) interrupt[中断源编号] using[使用的通用寄存器]
void name (void) interrupt 1 using 1{
//处理内容
}
3.定时/计数器
如果计数器寄存器的值只是从0xFFFF,那我们怎么控制定时的时间或计数的次数呢?还有定时/计数器(一下简称T/C)的计数寄存器是可以
由使用者修改的,在我们使用T/C之前,先计算一下我们需要的计数次数(或定时时间),比如我们需要计数到6次时产生T/C中断,就用溢出
值0xFFFF减去6,得到0xFFF9。最后将结果的高8位FF写入计数寄存器高8位TH中,低8位F9写入计数寄存器低8位TL中。再启动T/C时,计数
的开始值就是0xFFF9了,达到了我们控制中断计数次数的目的。
单片机定时/计数器部分SFR
名称 功能 地址 初始值
TCOM T/C控制寄存器 0x88 0000 0000
TMOD T/C方式寄存器 0x89 0000 0000
TH0 T/C0计数寄存器高8位 0x8C 0000 0000
TL0 T/C0计数寄存器低8位 0x8A 0000 0000
TH1 T/C0计数寄存器高8位 0x8D 0000 0000
TL1 T/C0计数寄存器低8位 0x8B 0000 0000
位定义
地址 名称 7 6 5 4 3 2 1 0
0x88 TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IE0
0x89 TMOD GATE C/T M1 M0 GATE C/T M1 M0
T/C1 T/C0
在SFR中,TH0,TL0是T/C0的计数寄存器的高8位和低8位,TH1,TL1是T/C1的计数寄存器的高8位和低8位。这个两个是独立的T/C,可以同时工作在不同方式下。
其中T/C1比较特殊,在使用UART串口的时候,T/C1被指定为UART串口产生波特率,即在启动UART时,T/C1就被绑架了,必须帮助UART串口工作。
TCON是T/C寄存器,包含T/C的启动开关和标志位,可位寻址操作。有趣的是,TCON中还包含外部中断(INT1,INT0)的控制寄存器,而没有把外部中断寄存器
单独放在一个字节里面
名称 说明
TF1 T/C1计数溢出中断请求标志位
计数寄存器的值溢出时TF1被硬件置1,如ET1 = 1(允许T/C1中断)
CPU进入T/C1中断处理程序时会将TF1置0(自动防止重复中断)。
如果ET1 = 0(禁止T/C1中断),CPU可以通过查询TF1的状态判断计数寄存器是否溢出
TR1 T/C1开关(为1时开启T/C1,为0时关闭)
TF0 T/C0计数器溢出中断请求标志
计数寄存器的值溢出时TF0被硬件置1,如ET0 = 1(允许T/C0中断)
CPU进入T/C0中断处理程序时会将TF0置0
如果ET1 = 0(禁止T/C0中断),CPU可以通过查询TF0的状态判断计数寄存器是否溢出
TR0 T/C0开关(为1时开启T/C0,为0时关闭)
IE1 外部中断INT1中断请求标志位
外部中断INT1触发时IE1被硬件置1,如EX1 = 1(允许INT1中断),CPU进入INT1中断
处理程序时会将TF1置0.
如果EX1 = 0(禁止INT1中断),CPU可以通过查询IE1的状态判断是否有外部中断触发
IT1 外部中断INT1触发方式选择。
IT1为1时,单片机的INT1引脚上由高电平向低电平变化的瞬间产生中断(下降沿)。
IT1为0时,单片机的INT1引脚上的电平为低电平时将触发中断(电平触发)
IE0 外部中断INT0中断请求标志位
外部中断INT0触发时IE1被硬件置1,如EX0 = 1(允许INT1中断),CPU进入INT0中断
处理程序时会将TF1置0
如果EX0 = 0(禁止INT0中断),CPU可以通过查询IE0的状态判断是否有外部中断触发
IT0 外部中断INT0触发方式选择。
IT0为1时,单片机的INT0引脚上由高电平向低电平变化的瞬间产生中断(下降沿)。
IT0为0时,单片机的INT0引脚上的电平为低电平时将触发中断(电平触发)
TMOD是T/C方式寄存器,高4位控制T/C1,低4位控制T/C0,T/C具有4种工作方式
T/C寄存器位功能
名称 说明
GATE 门控信号。
为1时,除TR1或TR0为1外,还需要INT1或INT0同时为1才启动T/C1或T/C0。
为0时,不受INT1或INT0控制
C/T 定时器/计数器选择位。
为1时,T/C作为计数器使用,由T1或T0引脚提供计数寄存器计数脉冲。
为0时,T/C作为定时器使用,由时钟震荡器提供计数寄存器计数脉冲
M1 T/C工作方式选择
M0 T/C工作方式选择
T/C工作方式
M1 M0 方式 说明
0 0 0 13位T/C,由TL低5位和TH的8位组成13位计数器
0 1 1 16位T/C,TL和TH共16位计数器
1 0 2 8位T/C,TL用于计数,当TL溢出时将TH中的值自动写入TL
1 1 3 两组8位T/C
4.UART串口
常用串口波特率
串口工作方式 波特率 12MHz时钟 11.0592MHz时钟
方式1或方式3 SMOD TMOD TH1 SMOD TMOD TH1
19200 1 20 0xFD
9600 0 20 0xFD
4800 1 20 0xF3 0 20 0xFA
2400 0 20 0xF3 0 20 0xF4
1200 0 20 0xF3 0 20 0xE8
600 0 20 0xCC 0 20 0xD0
UART串口可以用中断和查询法处理接受到数据,如果允许中断,当串口收到一个字节的数据时便产生中断。也可以用查询法读出接受数据标志位RI的状态
如果为1说明接受到数据。接受的数据存放在一个叫SBUF的8位寄存器里,RI为1时,程序可以读取SBUF的数据存到其他地方,然后让RI = 0。当RI再次为
1时,SBUF又出现了新接收到的数据。如此循环往复,串口可以接受长串的数据。UBFT串口发送也是通过SBUF寄存器。把需要发送的数据写入SBUF,其
他的什么都不用做,数据就发送出去了。不过为了保证发送完成了,我们还要读一下TI的状态,如果TI为0则说明数据还在发送的过程中;如果TI为1,则说明
数据发送完成,在程序中让TI = 0,然后把下一个需要发送的数据写入SBUF中。