目的:根据光敏电阻电阻值得到光照度的大小
该程序的功能:按下P2.4按键 数码管开始显示光照度 按下P2.6选择P2.5管脚的功能,每按下P2.5引脚对伽马 R E 的增加0.1
但是录入到Proteus中 当改变电阻值时,数码管的数值并不能实时更新,这是为什么?
#include <reg51.h>
#include <intrins.h>
// 按键和控制信号定义
sbit adc_rd = P3^7; // RD 信号
sbit adc_wr = P3^6; // WR 信号
sbit key_start = P2^4; // "开始"按键
sbit add = P2^5; // 增加按键
sbit key_choose = P2^6; // "选择"按键
// 数码管控制定义
sbit s1 = P2^0; // 数码管位选
sbit s2 = P2^1;
sbit s3 = P2^2;
sbit s4 = P2^3;
// 全局变量
unsigned char Disbuf[] = {0, 0, 0}; // 显示缓冲区
unsigned char code tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 数码管编码表
float gamma = 0.5, r = 1.0, e = 1.0; // 参数默认值
unsigned char chooseParam = 0; // 当前选择的增益参数
unsigned char newParam = 0; // 新参量
unsigned char adcValue = 0; // 存储 ADC 转换值
bit measuring = 0; // 实时测量标志
// 延时函数
void delay(unsigned int time) {
unsigned int i, j;
for (i = 0; i < time; i++) {
for (j = 0; j < 120; j++);
}
}
// 数码管显示
void display() {
P1 = tab[Disbuf[2]]; s4 = 0; delay(5); s4 = 1; // 个位
P1 = tab[Disbuf[1]]; s3 = 0; delay(5); s3 = 1; // 十位
P1 = Disbuf[0] ? tab[Disbuf[0]] : 0xff; s2 = 0; delay(5); s2 = 1; // 百位
}
// ADC初始化
void adcInit() {
adc_wr = 0; _nop_(); adc_wr = 1;
}
// 读取ADC值
unsigned char adcRead() {
unsigned char d;
P0 = 0xff; _nop_();
adc_rd = 0; _nop_(); d = P0; _nop_(); adc_rd = 1;
return (d);
}
// 更新显示缓冲区
void updateDisplay(unsigned char dat) {
unsigned int intensity = (int)(dat * gamma * r * e); // 光照度转换
Disbuf[0] = intensity / 100;
Disbuf[1] = (intensity % 100) / 10;
Disbuf[2] = intensity % 10;
}
// 参数调整逻辑
void adjustParameters() {
if (key_choose == 0) { // 切换当前调整的参数
chooseParam = chooseParam + 1; // 循环切换 gamma → r → e → gamma
newParam = chooseParam % 3; // 计算新参量
delay(200); // 防抖
}
if (add == 0) { // 增加当前选择的参数值
if (newParam == 0) {
gamma += 0.1;
if (gamma > 1.0) { // 如果 gamma 大于等于 1,将其重置为 0.5
gamma = 0.5;
}
}
if (newParam == 1) r += 0.1;
if (newParam == 2) e += 0.1;
delay(200); // 防抖
}
}
// 设置测量模式
void setMeasurementMode() {
if (key_start == 0) {
measuring = 1;
delay(200); // 开始实时测量
}
}
// 主函数
void main() {
adcInit(); // 初始化ADC
while (1) {
adjustParameters(); // 调整增益参数
setMeasurementMode(); // 设置测量模式
if (measuring) {
adcValue = adcRead(); // 实时读取 ADC 值
updateDisplay(adcValue); // 更新显示缓冲区
}
display(); // 更新数码管显示
delay(20); // 动态显示延时
}
}

