求程序代码:51单片机8位动态数码管数字电压显示,经过mcp3001串行A/D转换后,利用8位动态数码管显示外部电压的数值。要求精确到小数点后2位。外部电压改变的时候,显示的电压数值也要随之改变,注意,最后一个字符为大写的字符“U”
时间: 2024-03-01 14:56:22 浏览: 79
以下是基于51单片机的8位动态数码管数字电压显示程序代码,使用了MCP3001串行A/D转换芯片:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS = P1^4; //定义片选引脚
uchar code LedChar[] = { //数码管字符表
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
void delay(uint t) { //延时函数
uint i, j;
for(i=0; i<t; i++) {
for(j=0; j<120; j++);
}
}
uchar SpiWrite(uchar dat) { //SPI写函数
uchar i, rdat;
for(i=0; i<8; i++) {
P1 &= ~0x08; //SCK=0
if(dat & 0x80) P1 |= 0x02; //MOSI=1
else P1 &= ~0x02; //MOSI=0
P1 |= 0x08; //SCK=1
dat <<= 1;
}
P1 &= ~0x08; //SCK=0
rdat = P1 & 0x01; //MISO
return rdat;
}
uint AdcRead(uchar chn) { //ADC读函数
uchar i;
uint rdat = 0;
CS = 0; //片选
SpiWrite(0x01); //起始字节
SpiWrite((chn<<4) | 0x80); //通道号
for(i=0; i<3; i++) {
rdat <<= 8;
rdat |= SpiWrite(0x00); //读取数据
}
CS = 1; //取消片选
return rdat & 0x3ff; //取低10位
}
void DispNum(uint num, uchar dp) { //数码管显示函数
uchar i, j, k, buf[8];
for(i=0; i<8; i++) { //转换成字符
buf[i] = LedChar[num % 10];
if(i == dp) buf[i] |= 0x80; //小数点
num /= 10;
}
buf[7] = LedChar[16]; //添加“U”字符
for(i=0; i<8; i++) { //循环扫描
P0 = 0xff; //消影
for(j=0; j<8; j++) {
k = (i+j) & 0x07; //计算位序
P0 = buf[k]; //显示字符
P2 = ~(1<<k); //位选
delay(1); //短延时
}
}
}
void main() {
uint adval;
while(1) {
adval = AdcRead(0); //读取ADC值
DispNum(adval, 2); //显示ADC值
delay(10); //短延时
}
}
```
注意,上述程序中的`AdcRead`函数使用了MCP3001芯片进行串行A/D转换,通过调用该函数读取外部电压的模拟值,再将其转换成数码管字符进行显示。其中,`DispNum`函数用于将数字转换成数码管字符并进行循环扫描显示,其中第二个参数`dp`用于指定小数点的位置。在显示的最后一位添加大写字母“U”的方法是将数码管字符表中的第16个字符作为“U”的显示。
阅读全文