单片机与ADC连接采用IO方式,采用中断方式采集模拟电压(0~5V),送到数码管显示。0~5V的被测电压加到ADC0808芯片的IN3通道,进行A/D转换,输入电压的大小可通过手动调节RV1来实现。生成代码
时间: 2023-12-06 21:45:02 浏览: 98
以下是基于51单片机的代码:
```
#include <reg52.h>
#define ADC0808_DATA P0
sbit ADC0808_SC = P1^0; // 定义ADC0808的启动转换控制端
// 数码管显示的位选信号
sbit digit1 = P2^2;
sbit digit2 = P2^3;
sbit digit3 = P2^4;
sbit digit4 = P2^5;
unsigned char code table[] = {
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
unsigned char adc_result = 0; // 存储ADC转换结果
unsigned int voltage = 0; // 存储转换后的电压值,单位是mV
// 延时函数
void delay(unsigned int t) {
unsigned int i, j;
for (i = 0; i < t; i++) {
for (j = 0; j < 125; j++);
}
}
// 将数码管的位选信号全部置低
void clear_digit() {
digit1 = 0;
digit2 = 0;
digit3 = 0;
digit4 = 0;
}
// 在数码管上显示一个数字
void display(unsigned char num) {
clear_digit();
switch (num) {
case 0:
ADC0808_DATA = table[0];
digit1 = 1;
break;
case 1:
ADC0808_DATA = table[1];
digit2 = 1;
break;
case 2:
ADC0808_DATA = table[2];
digit3 = 1;
break;
case 3:
ADC0808_DATA = table[3];
digit4 = 1;
break;
case 4:
ADC0808_DATA = table[4];
digit1 = 1;
break;
case 5:
ADC0808_DATA = table[5];
digit2 = 1;
break;
case 6:
ADC0808_DATA = table[6];
digit3 = 1;
break;
case 7:
ADC0808_DATA = table[7];
digit4 = 1;
break;
case 8:
ADC0808_DATA = table[8];
digit1 = 1;
break;
case 9:
ADC0808_DATA = table[9];
digit2 = 1;
break;
}
}
// ADC0808的初始化函数
void ADC0808_Init() {
ADC0808_SC = 0;
ADC0808_DATA = 0xff;
}
// 启动ADC转换
void ADC0808_Start() {
ADC0808_SC = 1;
ADC0808_SC = 0;
}
// 读取ADC转换结果
unsigned char ADC0808_Read() {
return ADC0808_DATA;
}
// ADC转换结束中断服务程序
void ADC0808_ISR() interrupt 0 {
adc_result = ADC0808_Read();
voltage = adc_result * 5000 / 255; // 计算电压值,单位是mV
ADC0808_Start(); // 继续启动下一次转换
}
int main() {
ADC0808_Init();
EA = 1; // 允许中断
EX0 = 1; // 允许外部中断0
IT0 = 1; // 外部中断0触发方式为下降沿触发
ADC0808_Start(); // 启动第一次ADC转换
while (1) {
display(voltage % 10); // 显示个位数
delay(5);
display((voltage / 10) % 10); // 显示十位数
delay(5);
display((voltage / 100) % 10); // 显示百位数
delay(5);
display(voltage / 1000); // 显示千位数
delay(5);
}
return 0;
}
```
需要注意的是,在上述代码中,我们使用了一个外部中断0来实现ADC转换结束后的中断处理。在单片机上,ADC转换需要一定时间,如果我们直接在程序中等待ADC转换结束,那么整个程序的效率会非常低。因此,我们使用了中断的方式,在ADC转换结束后立即进入中断服务程序进行处理,这样可以提高程序的效率。
阅读全文