以Proteus7.8为硬件仿真平台,以C51语言为设计语言编程实现1000000.0s计时程序设计实验。具体如下:仿真开始运行执行最低位每隔0.1s计数加1,低位计数值满以后向上进位的功能。采用多段数码管(共阴/共阳均可)动态显示秒计时程序。
时间: 2024-03-13 15:46:18 浏览: 33
以下是使用Proteus7.8和C51语言实现1000000.0s计时程序并在多段数码管上动态显示的步骤:
1. 打开Proteus7.8软件
在Proteus7.8软件中,选择"New Project"创建一个新项目,然后在"Sources"选项卡中添加一个C文件,例如"main.c"。
2. 编写程序
将以下代码复制到"main.c"文件中:
```
#include <reg51.h>
// 定义时钟频率,单位Hz
#define FREQ 12000000UL
// 定义定时器中断频率
#define INTERRUPT_FREQ 10UL
// 定义计数器初值
#define COUNT_INIT 0
// 定义计数器终值
#define COUNT_TARGET ((unsigned long)1000000.0 * FREQ / INTERRUPT_FREQ)
// 定义计数器变量
volatile unsigned long count = COUNT_INIT;
// 定义数码管段码
unsigned char code LED_CODE[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90
};
// 定义数码管位码
unsigned char code LED_BIT[] = {
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
};
// 定义数码管显示变量
unsigned char LED_DATA[8] = { 0 };
// 定义定时器中断处理函数
void timer_interrupt() interrupt 1 {
// 计数器加1
count++;
// 判断计数器是否达到终值
if (count >= COUNT_TARGET) {
// 停止定时器
TMOD &= 0xF0;
TR0 = 0;
}
// 更新数码管显示值
unsigned long temp = count / INTERRUPT_FREQ;
for (int i = 0; i < 8; i++) {
LED_DATA[i] = temp % 10;
temp /= 10;
}
}
// 主函数
void main() {
// 初始化定时器
TMOD &= 0xF0;
TMOD |= 0x01;
// 设置定时器初值
TH0 = 0xFC;
TL0 = 0x66;
// 设置定时器中断频率
TH1 = 256 - FREQ / INTERRUPT_FREQ;
TL1 = TH1;
// 启动定时器
TR0 = 1;
ET0 = 1;
EA = 1;
// 初始化数码管
unsigned char i;
for (i = 0; i < 8; i++) {
P0 = LED_BIT[i];
P2 = LED_CODE[0];
P1 = 0xFF;
delay_ms(10);
}
// 循环动态显示数码管
while (1) {
for (i = 0; i < 8; i++) {
P0 = LED_BIT[i];
P2 = LED_CODE[LED_DATA[i]];
P1 = 0xFF;
delay_ms(10);
}
}
}
```
3. 配置仿真环境
在Proteus7.8软件中,选择"Pick Devices",然后选择一个AT89C51芯片和一个多段数码管(共阴/共阳均可),并将它们拖放到工作区中。
在AT89C51芯片的属性窗口中,选择"Program File"并选择刚才生成的"main.hex"文件,然后点击"Apply"保存设置。
4. 运行仿真
启动仿真后,AT89C51芯片会开始执行计时程序,每隔0.1s计数加1,并在多段数码管上动态显示当前的计时值。
注意:由于定时器是通过中断来实现计数的,因此需要在中断处理函数中使用`volatile`关键字修饰计数器变量,以确保计数器变量在中断处理函数和主函数之间的可见性。同时,定时器中断处理函数需要使用`interrupt`关键字声明为中断处理函数,否则会出现编译错误。在程序中使用`EA = 1`启用全局中断,否则定时器中断无法触发。在程序中使用`delay_ms`函数实现延时,以避免数码管显示过快导致闪烁。