利用单片机采集外部模拟量数值,并将此模拟量数值以数码管进行显示。通过按键控制显示的内容的切换,具体内容包括:内部数字量、外部电压值、学号。程序
时间: 2023-06-19 15:08:53 浏览: 99
单片机的数码管显示程序
5星 · 资源好评率100%
以下是一个基于STC89C52单片机的示例程序,可以实现采集外部模拟量并通过数码管显示,通过按键控制显示内容的切换:
```c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1 = P3^0;
sbit key2 = P3^1;
sbit key3 = P3^2;
sbit dula = P2^6;
sbit wela = P2^7;
uchar code table[] = {
0xc0, // "0"
0xf9, // "1"
0xa4, // "2"
0xb0, // "3"
0x99, // "4"
0x92, // "5"
0x82, // "6"
0xf8, // "7"
0x80, // "8"
0x90 // "9"
};
uchar digit[4] = {0}; // 数码管显示缓存
uchar mode = 0; // 显示模式,0:内部数字量,1:外部电压值,2:学号
void delay(uint x) {
uint i, j;
for (i = x; i > 0; i--) {
for (j = 110; j > 0; j--);
}
}
void display() {
uchar i, j;
for (i = 0; i < 4; i++) {
wela = 1; // 打开位选锁存器
P0 = 0xfe << i; // 选择第 i 个数码管
wela = 0; // 关闭位选锁存器
P0 = table[digit[i]]; // 设置段选锁存器的值
dula = 1; // 打开段选锁存器
for (j = 10; j > 0; j--); // 延时
dula = 0; // 关闭段选锁存器
P0 = 0xff; // 清空段选锁存器的值
}
}
void read_adc() {
uchar i;
uint sum = 0;
for (i = 0; i < 8; i++) {
sum += ADC_CONTR << 8; // 高8位
sum += ADC_RES; // 低8位
}
sum >>= 3; // 取平均值
digit[0] = sum / 1000; // 千位
digit[1] = sum / 100 % 10; // 百位
digit[2] = sum / 10 % 10; // 十位
digit[3] = sum % 10; // 个位
}
void main() {
TMOD = 0x01; // 定时器0工作模式1
TH0 = 0xfc; // 定时器0高8位初值
TL0 = 0x66; // 定时器0低8位初值
ET0 = 1; // 打开定时器0中断
TR0 = 1; // 启动定时器0
P1 = 0xff; // 初始化P1口,用于外部电压采集
P2 = 0x00; // 初始化P2口,用于数码管显示
P3 = 0xff; // 初始化P3口,用于按键控制
ADC_RES = 0;
ADC_CONTR = 0x80; // 设置ADC工作模式,选择P1.0作为采样口
delay(1); // 延时等待ADC启动
EA = 1; // 打开总中断
while (1) {
if (!key1) { // 按下按键1,切换显示模式
mode++;
if (mode > 2) mode = 0;
delay(10); // 延时去抖动
}
if (mode == 0) {
// 显示内部数字量
digit[0] = 1;
digit[1] = 2;
digit[2] = 3;
digit[3] = 4;
} else if (mode == 1) {
// 显示外部电压值
read_adc();
} else if (mode == 2) {
// 显示学号
digit[0] = 1;
digit[1] = 8;
digit[2] = 0;
digit[3] = 5;
}
display();
}
}
void timer0_isr() interrupt 1 {
TH0 = 0xfc; // 定时器0高8位初值
TL0 = 0x66; // 定时器0低8位初值
ADC_CONTR |= 0x08; // 启动ADC转换
}
```
在这个示例程序中,我们使用了STC89C52单片机内部的ADC模块来采集外部电压值,并通过数码管进行显示。按键1用于切换显示模式,按键2和按键3暂时没有使用。在每个循环周期中,根据当前的显示模式更新数码管的显示内容,并将其显示出来。定时器0的中断用于定时触发ADC转换。
需要注意的是,由于不同型号的单片机可能具有不同的管脚定义和ADC模块实现方式,需要根据具体的开发板和单片机型号进行适当的修改和调试。
阅读全文