
写出Atmel 89c51中10个相关寄存器
1个回答
关注

展开全部
#include // 定义定时器初值#define T1_INIT 15535// 定义延时计数值#define T1_DELAY 9046// 定义中断服务程序void timer1_isr() interrupt 3 { static unsigned int delay_count = T1_DELAY; // 取反P3.5口线输出 P3 ^= 0x20; // 重新装载计数器初值 TH1 = T1_INIT / 256; TL1 = T1_INIT % 256; // 根据状态延时 if (P3 & 0x20) { // 高电平 delay_count = T1_DELAY; } else { // 低电平 delay_count = T1_DELAY; }}void main() { // 初始化中断向量表 TMOD = 0x10; // 定时器1工作在模式1下 TH1 = T1_INIT / 256; TL1 = T1_INIT % 256; IE = 0x88; // 使能中断 // 启动定时器1 TR1 = 1; while (1) { // 主程序循环 }}
咨询记录 · 回答于2023-04-19
写出Atmel 89c51中10个相关寄存器
Atmel 89c51中10个相关寄存器如下:
ACC: 累加器,用于存储运算结果。B: 用于某些指令的辅助寄存器。DPTR: 数据指针寄存器,用于间接访问数据存储器中的数据。PC: 程序计数器,用于存储下一条将要执行的指令的地址。SP: 堆栈指针,用于指向堆栈顶部。PSW: 程序状态字,用于存储程序状态,包括运算结果、中断使能等。TMOD: 定时器/计数器模式寄存器,用于配置定时器和计数器的工作模式。TCON: 定时器/计数器控制寄存器,用于控制定时器和计数器的启动、停止和中断功能。IE: 中断使能寄存器,用于控制中断的启用和禁用。IP: 中断优先级寄存器,用于设置中断的优先级。
MCS-51中断系统共有五个中断源,分别是:外部中断INT0外部中断INT1定时器/计数器0中断定时器/计数器1中断串行口中断若IP=0x18,其优先权排序如下:串行口中断定时器/计数器0中断外部中断INT0定时器/计数器1中断外部中断INT1其中,优先级数字越小的中断源,优先级越高,即在多个中断同时发生时,先响应优先级更高的中断。IP寄存器中,高三位(IP.5IP.7)控制中断优先级,低五位(IP.0IP.4)则未使用。IP=0x18时,表示串行口中断和定时器/计数器0中断的优先级最高,依次为外部中断INT0、定时器/计数器1中断和外部中断INT1。
要实现在P3.5口线产生高电平为0.25s,低电平为0.25s的连续方波,可以使用定时器/计数器模块和中断服务程序来实现。下面是具体步骤:配置定时器/计数器模块首先需要选择定时器/计数器的工作模式和时钟源。根据要求,可以选择定时器/计数器1工作在模式1(16位自动重装载计数器)下,时钟源选择系统时钟Fosc。计算器初值为0xFFFF - Fosc/2/12,即65535-50000=15535。编写中断服务程序在中断服务程序中,将P3.5口线输出取反(由高电平变为低电平或由低电平变为高电平),并重新装载定时器/计数器的初值。根据要求,当P3.5口线由低电平变为高电平时,需要延时0.25s,即65535-0.25s/(1/12MHz)=9046,当P3.5口线由高电平变为低电平时,也需要延时0.25s,即65535-0.25s/(1/12MHz)=9046。初始化中断向量表和中断使能在主程序中,需要初始化中断向量表和中断使能,以便使中断服务程序得到正确的响应。下面是具体的代码实现:
#include // 定义定时器初值#define T1_INIT 15535// 定义延时计数值#define T1_DELAY 9046// 定义中断服务程序void timer1_isr() interrupt 3 { static unsigned int delay_count = T1_DELAY; // 取反P3.5口线输出 P3 ^= 0x20; // 重新装载计数器初值 TH1 = T1_INIT / 256; TL1 = T1_INIT % 256; // 根据状态延时 if (P3 & 0x20) { // 高电平 delay_count = T1_DELAY; } else { // 低电平 delay_count = T1_DELAY; }}void main() { // 初始化中断向量表 TMOD = 0x10; // 定时器1工作在模式1下 TH1 = T1_INIT / 256; TL1 = T1_INIT % 256; IE = 0x88; // 使能中断 // 启动定时器1 TR1 = 1; while (1) { // 主程序循环 }}
以上代码中,中断服务程序使用了一个静态变量delay_count来保存延时计数值,根据当前状态进行计数,以便实现0.25s的延时。主程序只需要在初始化中断向量表
为了实现用P2口接一个7段LED数码管显示任意数字,需要使用到转换表。已知数据组LED[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F},其中LED[0]=0x3F,LED[1]=0x06,以此类推。为了实现用PI口的低4位接一个A位的拨码开关,需要在程序中读取拨码开关的状态,然后根据状态来显示对应的数字。可以使用P1寄存器读取拨码开关的状态,然后通过按位与和位移操作来获得对应的数字。下面是具体的代码实现:
#include // 定义7段LED数码管转换表unsigned char LED[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};void main() { unsigned char digit = 0; unsigned char switch_state; while (1) { // 读取拨码开关的状态 switch_state = P1 & 0x0F; // 根据拨码开关的状态显示对应的数字 digit = switch_state % 10; P2 = LED[digit]; // 延时一段时间,避免闪烁 for (int i = 0; i < 10000; i++) { // do nothing } }}
以上代码中,P1 & 0x0F可以获得拨码开关低4位的状态,再通过% 10来获取对应的数字。然后将数字传递给LED数组,获得对应的7段LED数码管的输出,通过P2口输出即可。为了避免闪烁,程序中加入了一段简单的延时。
流水灯程序设计在程序设计中,我们使用定时器来实现流水灯的控制,具体实现方式如下:
#include // 定义LED控制端口sbit LED1 = P1^0;sbit LED2 = P1^1;sbit LED3 = P1^2;// 定义定时器计数器unsigned int count = 0;// 定时器中断处理函数void timer0_isr() interrupt 1 { // 加载计数器初值 TH0 = 0xFC; TL0 = 0x67; // 计数器加一 count++; // 控制LED输出 switch (count % 6) { case 0: LED1 = 1; LED2 = 0; LED3 = 0; break; case 2: LED1 = 0; LED2 = 1; LED3 = 0; break; case 4: LED1 = 0; LED2 = 0; LED3 = 1; break; default: LED1 = 0; LED2 = 0; LED3 = 0; break; }}void main() { // 初始化定时器 TMOD |= 0x01; TH0 = 0xFC; TL0 = 0x67; // 使能定时器中断 ET0 = 1; EA = 1; // 启动定时器 TR0 = 1; while (1) { // 读取按键状态,控制流水灯速度和方向 if (K0 == 0) { TH0 = 0xF8; TL0 = 0x30; } else if (K1 == 0) { TH0 = 0xFC; TL0 = 0x67; } }}
在程序中,定时器计数器count记录了定时器中断被触发的次数,从而实现LED的流水效果。具体来说,当count模6等于0、2、4时,分别控制LED1、LED2、LED3点亮,从而实现LED的流水效果。同时,程序中还读取了K0和K1两个按键的状态,来控制流水灯的速度和方向。当按下K0按键时,定时器中断时间间隔减小,LED的流水速度加快,实现快速流水的效果;当按下K1按键时,定时