這是一個網上公開的程序,因只有STC15W408AS,就照樣做了一個,但顯示不正確,請人改成STC15W408AS能用的程序,愿用80黑幣給解決問題的人。
#include<stc15f204ea.h>
//#include<STC15W408AS,H>
#include<intrins.h>
#define ADC_POWER 0x80 //ADC 電源控制位
#define ADC_FLAG 0x10 //ADC 完成標志
#define ADC_START 0x08 //ADC 啟動控制位
#define ADC_speed_LL 0x00 //540 時鐘
#define ADC_speed_L 0x20 //360 時鐘
#define ADC_speed_H 0x40 //180 時鐘
#define ADC_speed_HH 0x60 // 90 時鐘
typedef unsigned long uint;
void delay(unsigned int x); //函數聲明
void LCD(unsigned int LedNumVal); //函數聲明
void Delay1ms(); //函數聲明
void Delay150us(); //函數聲明
void AD_Init(); //函數聲明
uint ADC(uint m); //函數聲明
void Delay350us(); //函數聲明
void Delay20ms(); //函數聲明
unsigned char code Disp_Tab[] = {0xd7,0x14,0xcd,0x5d,0x1e,0x5b,0xdb,0x15,0xdf,0x5f,0xd7}; // 數組 0-9
unsigned char code dispbit[4]={0x07,0x0b,0x0d,0x0e}; //位選控制
/************主函數**********************/
void main()
{
uint Vcc,Int,V,Int_S, Vcc_S;
unsigned char m,M;
P3M1=0x00;
P3M0=0xff; //設置P3口強推挽輸出
AD_Init(); //AD初始化
Delay1ms(); //開始采樣電壓前延時,電路有幾個電容充電未完成前會拉低部分元器件電壓(導致采樣電壓不準),目測須延時1S,懶得改程序了
while(1)
{
Delay20ms();
Int_S=0;
Vcc_S=0;
m=0;
for(m;m<24;m++)
{
Delay350us(); //采樣電壓時差
Int_S += ADC(4);
Vcc_S += ADC(5);
Int = Int_S/24;
Vcc = Vcc_S/24; //采樣24次電壓求平均值
}
M=20*Int/Vcc;
if(M>16) V=19150*Int/Vcc;
else if(M>11) V=19100*Int/Vcc; //大于11V電壓轉換公式
else if(M>10) V=19150*Int/Vcc; //10V-11V
else if(M>5) V=19200*Int/Vcc; //5V-10V
else if(M>3) V=19350*Int/Vcc; //3V-5V
else if(M>1) V=19550*Int/Vcc; //1V-3V
else if(M>=0) V=20000*Int/Vcc; //0-1V 各量程精度調整
LCD(V); //電壓顯示
}
}
/*******數碼管顯示函數*************/
void LCD(unsigned int LedNumVal)
{
unsigned int LedOut[4]; //變量定義
if(LedNumVal>9999)
{
LedOut[0]=Disp_Tab[LedNumVal%100000/10000]; // 千位
LedOut[1]=Disp_Tab[LedNumVal%10000/1000]|0x20; // 百位
LedOut[2]=Disp_Tab[LedNumVal%1000/100]; // 十位
LedOut[3]=Disp_Tab[LedNumVal%100/10]; // 個位
}
if(LedNumVal<10000)
{
LedOut[0]=Disp_Tab[LedNumVal%10000/1000]|0x20; // 千位
LedOut[1]=Disp_Tab[LedNumVal%1000/100]; // 百位
LedOut[2]=Disp_Tab[LedNumVal%100/10]; // 十位
LedOut[3]=Disp_Tab[LedNumVal%10]; // 個位 if語句 實現 小數點自動切換
}
P3=LedOut[3];
P11=0;
delay(700);
P11=1;
P3=LedOut[2];
P12=0;
delay(700);
P12=1;
P3=LedOut[1];
P10=0;
delay(700);
P10=1;
P3=LedOut[0];
P13=0;
delay(700);
P13=1;
delay(700); // 數碼管消隱
}
/***********AD初始化***************/
void AD_Init()
{
P1M1=0x30;
P1M0=0x00; //設置P1.4\P1.5高阻
ADC_RES=0x00;
P1ASF=0x30;
ADC_CONTR=ADC_POWER|ADC_speed_LL;
Delay1ms();
}
/*********電壓采樣*********/
uint ADC(uint m)
{
if(m==4)
{
ADC_CONTR &=0xf8; //清空通道
ADC_CONTR |=0x04; //更換通道
Delay150us(); //更換通道延時
}
if(m==5)
{
ADC_CONTR &=0xf8;
ADC_CONTR |=0x05;
Delay150us();
}
ADC_CONTR |=ADC_START; //開啟AD轉換
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & 0x10));
ADC_CONTR &= ~ADC_FLAG;
return ADC_RES; //返回轉換結果
}
/*******************延時函數**********/
void delay(unsigned int x)
{
char j;
for(x; x> 0; x--)
for(j = 400; j > 0; j--);
}
void Delay1ms() [url=]//@12.000MHz[/url]
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
void Delay150us() [url=]//@12.000MHz[/url]
{
unsigned char i, j;
i = 2;
j = 189;
do
{
while (--j);
} while (--i);
}
void Delay350us() [url=]//@12.000MHz[/url]
{
unsigned char i;
_nop_();
i = 172;
while (--i);
}
void Delay20ms() [url=]//@12.000MHz[/url]
{
unsigned char i, j;
i = 39;
j = 230;
do
{
while (--j);
} while (--i);
}
|