完成是功能是读取电压值,显示在号码管上。
先了解A/D需要的代码设置
我用到了P1ASF、ADC_CONTR、ADC_RES、ADC_RESL。其他是默认的。
P1ASF设置P1口模拟功能控制寄存器。默认P1口上电是弱上拉型I/O口。需要软件相应的位置1。本人用到P1.5。下面介绍P1ASF的功能。
ADC_CONTR,软件上的操作,打开A/D模式、选择去读那个引脚读取数据。如下图,红框的数据需要仔细选择。我选择的是P1.5口。
P1ASF 寄存器与ADC_CONTER 的区别:
P1ASF 寄存器,是为了设置 那几个 I/O 用来作 AD 转换用的,一次设置完成就可以了。
ADC_CONTER 的CHS2 CHS1 CHS0,是为了选择读取那一路 AD 用的,
即选择那一路进行AD转换 ,并且读取转换后的数据,
因为 单片机内部 只有 一个 AD 转换电路, 8路AD是进行选通选择的。
没有冲突的问题,当然你要理解了,使用起来就得心应手了。
可以看看AD转换的实例
ADRJ读取串口数据存放的位置,我选择默认。具体如下图。
ADC_RES、ADC_RESL数据存放的位置,我选择是默认。
遗留问题:结果10位和8位是不同的,这默认是10位。具体怎么设置。我之前找到过。不过没有用到,现在整理资料时忘记了在哪里?后期找到加上,或者各位看到了评论上了。
IE和IP是中断和设置中断的优先级。本次没有用到,就没有探索了。
附上我的代码:
#include "stc15.h"
sbit ep = P2^7;
sbit led = P2^6;
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA=P4^1;
sbit LSB=P4^2;
sbit LSC=P4^3;
sbit LSD=P4^4;
u8 disp[4];
u8 code sm[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(u16 i)
{
while(i--);
}
void LedInit()
{
P4M1=0x00;
P4M0=0x00;
P0M1=0x00;
P0M0=0x00;
P2M1=0x0f;
P2M0=0x0f;
P4=0;
P0=0;
}
void ADCinit()
{
P1ASF=0x20;
ADC_RES=0;
ADC_CONTR=0x80|0x00|0x05;
delay(2);
}
/*
void ADCinit()
{
P1ASF=0xff;
ADC_RES=0;
ADC_CONTR=0x80|0x00|0x05;
delay(2);
} */
void LedWei(u8 weiNumber)
{
P4=weiNumber;
}
void LedDuan(u8 duanNumber)
{
ep=1;
P0=duanNumber;
ep=0;
}
int readValue()
{
u16 i=0;
float j;
ADC_CONTR = ADC_CONTR|0x08;
//delay(100);
while (!(ADC_CONTR & 0x10));
ADC_CONTR &= ~0x10;
i=ADC_RES;
i=i<<2;
i=i|(ADC_RESL&0x03);
//delay(20);
ADC_CONTR=0x80|0x00|0x05;
ADC_RESL=0x00;
ADC_RES = 0x00;
j = i*0.0206*100;
//j = (5*i)/1024*262/62*100;
i=j;
return i;
} /*
int readValue()
{
u16 i=0;
ADC_CONTR = ADC_CONTR|0x08;
delay(20);
//while (!(ADC_CONTR & 0x10));
while (!(ADC_CONTR & 0x10))
{
led=0;
delay(50000);
}
ADC_CONTR &= ~0x10;
i=ADC_RES;
i = i<<2;
ADC_CONTR=0x80|0x00|0x05;
return i;
} */
void LedPara()
{
u16 temp,numberDate,n;
u8 j;
disp[0] = 0;
disp[1] = 0;
disp[2] = 0;
disp[3] = 0;
if(n==10)
{ n=0;
numberDate=0;
numberDate = readValue();
for(j=0;j<10;j++)
{
numberDate += readValue();
numberDate =numberDate/2;
}
}
n++;
/* if(j==200)
{
j=0;
numberDate = readValue();
}
j++;
*/
disp[0]= sm[numberDate/1000];
disp[1]= sm[numberDate%1000/100];
disp[2]= sm[numberDate%1000%100/10];
disp[3]= sm[numberDate%1000%100%10];
//numberDate=0;
}
void DiDisplay()
{
u8 i;
for(i=0;i<4;i++)
{
switch(i)
{
case(0):
LSA=1;LSB=0;LSC=0;LSD=0;break;
case(1):
LSA=0;LSB=1;LSC=0;LSD=0;break;
case(2):
LSA=0;LSB=0;LSC=1;LSD=0;break;
case(3):
LSA=0;LSB=0;LSC=0;LSD=1;break;
}
LedDuan(disp[i]);
delay(5000);
P4=0x00;
}
}
void main()
{
LedInit();
ADCinit();
delay(100);
while(1)
{
LedPara();
DiDisplay();
}
}
代码有注释,自己走的弯路。放上去。