标题:
如何用STC15单片机内部AD读取并在数码管显示电压值?
[打印本页]
作者:
pql2438547
时间:
2019-8-21 16:43
标题:
如何用STC15单片机内部AD读取并在数码管显示电压值?
MCU用的是STC15F2K60S2,外部硬件电路为一个20K的电位器,中间脚滑动端接AD输入引脚P1.0,另外两边引脚分别接GND和VCC,目前代码可以通过旋转电位器实现在四位一体共阴数码管上显示0~1023的数值,但是下一步想尝试显示电压值却总是格式不对显示不正常?参考了几个例程文件,还是不能弄出。代码部分的计算电压值时:adcnum=adcnum*500/1024;结果显示到数码管上就不正常了?以下是代码
#include "reg52.h"
#include "intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr AUXR = 0x8e; //辅助寄存器
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_RESL = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
sfr CLK_DIV = 0x97;
sbit LSA=P3^2;
sbit LSB=P3^3;
sbit LSC=P3^4;
uchar code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
uchar DisplayData[8];
void Delay_ms(unsigned int ms)//ms级延时
{
unsigned int a,b;
for(a=ms;a>0;)
{
for(b=1000;b>0;)
{
b=b-1;
}
a--;
}
}
void ADC_int() //ADC初始化
{
ADC_CONTR=0X80;
P1ASF=0X01;
CLK_DIV=0X20;
ADC_RESL=0;
ADC_RES=0;
Delay_ms(10);
}
unsigned int ADC_Read()
{
unsigned int a=0;
ADC_CONTR = 0X88;
Delay_ms(1);
while(!(ADC_CONTR&0X10));
a=ADC_RES*256+ADC_RESL;
ADC_CONTR&=~0x10;
return a;
}
void DigDisplay()
{
uchar i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P2=DisplayData[i];//发送段码
Delay_ms(1);//间隔一段时间扫描
P2=0x00;//消隐
}
}
void datapros()
{
uint adcnum;
adcnum=ADC_Read();
adcnum=adcnum*500/1024;
DisplayData[0]=smgduan[adcnum%1000%100%10/1]; //显示个位
DisplayData[1]=smgduan[adcnum%1000%100/10]; //显示十位
DisplayData[2]=smgduan[adcnum%1000/100]; //显示百位
DisplayData[3]=smgduan[adcnum/1000]; //显示千位
Delay_ms(10);
}
void main()
{
ADC_int(); //初始化ADC
while(1)
{
datapros(); //数码管数据处理函数
DigDisplay(); //数码管显示函数
}
}
复制代码
作者:
suuy79
时间:
2019-8-21 17:35
uint adcnum;
adcnum=ADC_Read();
adcnum=adcnum*500/1024; 数据超范围啦
作者:
pql2438547
时间:
2019-8-21 18:48
suuy79 发表于 2019-8-21 17:35
uint adcnum;
adcnum=ADC_Read();
adcnum=adcnum*500/1024; 数据超范围啦
但是我看别人程序的,他用串口发送给电脑的却能正常显示?
void adcsend()
{
unsigned char a[4],b;
send=send*500/1024; //电压计算
a[0]=send%10+'0';
a[1]=send/10%10+'0';
a[2]='.';
a[3]=send/100+'0';
for(b=4;b>0;b--)
Uartsend(a[b-1]); //从4-1=[3]个位开始依次[2][1][0]发送给数据
}
复制代码
作者:
angmall
时间:
2019-8-21 19:01
给你改了一下试试。
#include "reg52.h"
#include "intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr AUXR = 0x8e; //辅助寄存器
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_RESL = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
sfr CLK_DIV = 0x97;
sbit LSA=P3^2;
sbit LSB=P3^3;
sbit LSC=P3^4;
uchar code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
uchar DisplayData[8];
void Delay_ms(unsigned int ms)//ms级延时
{
unsigned int a,b;
for(a=ms;a>0;)
{
for(b=1000;b>0;)
{
b=b-1;
}
a--;
}
}
void ADC_int() //ADC初始化
{
ADC_CONTR=0X80;
P1ASF=0X01;
CLK_DIV=0X20;
ADC_RESL=0;
ADC_RES=0;
Delay_ms(10);
}
unsigned int ADC_Read()
{
unsigned int a=0;
ADC_CONTR = 0X88;
Delay_ms(1);
while(!(ADC_CONTR&0X10));
a=ADC_RES*256+ADC_RESL;
ADC_CONTR&=~0x10;
return a;
}
void DigDisplay()
{
uchar i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P2=DisplayData[i];//发送段码
Delay_ms(1);//间隔一段时间扫描
P2=0x00;//消隐
}
}
void datapros()
{
ulong adcnum;
adcnum=ADC_Read();
adcnum=adcnum*500/1024;
DisplayData[0]=smgduan[adcnum%1000%100%10/1]; //显示个位
DisplayData[1]=smgduan[adcnum%1000%100/10]; //显示十位
DisplayData[2]=smgduan[adcnum%1000/100]; //显示百位
DisplayData[3]=smgduan[adcnum/1000]; //显示千位
Delay_ms(10);
}
void main()
{
ADC_int(); //初始化ADC
while(1)
{
datapros(); //数码管数据处理函数
DigDisplay(); //数码管显示函数
}
}
复制代码
作者:
107056
时间:
2019-8-21 22:20
先将数据化为强制类型转换为整形,再将adcnum=adcnum*500/1024;里的500变为500.0,将结果转换为浮点型应该就行了,这问题我也遇到过
作者:
aking991
时间:
2019-8-22 08:52
adcnum=adcnum*500/1024;关键就是这个算出来都是浮点数,所以当然不对,你应是定义为浮点数计算,然后再把结果数据放大为整数,然后再进行BCD解码,这样就OK了
作者:
CHUANGBIANZHE
时间:
2020-2-17 23:23
将“adcnum=adcnum*500/1024"改为“adcnum=adcnum*0.49”就OK了。
作者:
许你一世柔情
时间:
2020-3-26 18:57
根据楼上说的 你先乘0.49 然后乘100 得到49 *上前面的模拟值 然后模拟值会变成千位 你取千位和百位就可以避免浮点数运算
作者:
左岸的花会开
时间:
2020-3-31 10:58
suuy79 发表于 2019-8-21 17:35
uint adcnum;
adcnum=ADC_Read();
adcnum=adcnum*500/1024; 数据超范围啦
没有超吧
作者:
zhang32568
时间:
2024-4-17 08:54
adcnum=adcnum*500/1024; 要进行强制数据转换
改成 adcnum=500*(unsigned long)adcnun/1024
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1