/* 原程序是本壇下載的。 采用STC15W408AS單片機。12M晶振。三位數碼管顯示電壓值。想改為四位數碼管顯示電壓值。雖受限于單片機的AD轉換精度是10位的,用5V電源,
分辨率只有5MV.要改為四位顯示,線路板已做好四位的。程序沒有改成功,現在顯示四個零,希望得到指導。有2.5V的431取樣電路P14,ADC是P15。
*/
#include "STC15F408.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ADC_POWER 0x80 //AD電源控制位
#define ADC_FLAG 0x10 //轉換結束標志位。1 結束
#define ADC_START 0x08 //開始轉換位
#define ADC_SPEEDLL 0x00 //轉換速度540個時鐘
uchar ADC_POSITION; //0x00 AD通道位置P1.0, 0x01 AD通道位置P1.1
sbit bai=P1^3;//改動過
sbit shi=P1^2;
sbit ge=P1^1;
sbit sf=P1^0;
uchar s1,sec;
uint adval=0; //AD轉換值
uint show; //電壓值
uint show1; //基準電壓
uchar code table[]={0x28,0xeb,0x32,0xa2,0xe1,
0xa4,0x24,0xea,0x20,0xa0}; //P3數碼管數字0-9
uchar code table1[]={0x08,0xcb,0x12,0x82,0xc1,
0x84,0x04,0xca,0x00,0x80}; //P3數碼管數字0-9帶小數點
/*****************************************
系統初始化
*****************************************/
void system_init(void)
{
TMOD=0x01; //定時器0工作在方式1,的定時模式
ET0=1; //定時器0中斷允許
EA=1; //系統中斷允許
TR0=1; //定時器1和定時器0開始定時
TH0=(65536-30000)/256; //定時器0的初值30ms
TL0=(65536-30000)%256;
sec=59;
P3M1=0x00;//改動過
P3M0=0x00;//
P5M1=0x00;//
P5M0=0x00;//
P1M1=0x30;//
P1M0=0x3f;//
}
/********************************************************
* 函數名稱:delay
* 輸 入:z 延時時間
* 輸 出:無
* 功能描述: 毫秒級延時
********************************************************/
void delay(uchar n) //延時n ms
{
uchar a,b,c;
for(c=n;c>0;c--)
for(b=222;b>0;b--)
for(a=12;a>0;a--);
}
/********************顯示電壓值***************************/
void display()
{
uchar c,d,e,q,f;//q是后加的
uint su;
if(show1>850)
c=d=e=q=10;//q=是后加的
else
{
su=show;
c=su/100; //分離各位數值
f=su%100;
d=f/10;
e=f%10;
q=f%100; //后加的
}
P3=table1[c]; //顯示百位
bai=1;
delay(5);
bai=0;
P3=table[d]; //顯示十位
;
shi=1;
delay(5);
shi=0;
P3=table[e]; //顯示個位
ge=1;
delay(5);
ge=0;
P3=table[q]; //顯示十分位//后加的
sf=1;//后加的
delay(5);//后加的
sf=0; //后加的
}
/*****************************************************
** 函數名稱: void adc_isr() interrupt 5
** 功能描述: AD中斷,獲取AD數據
** 輸 入: 無
** 輸 出: show
** 全局變量: show
** 調用模塊: Delay_ms
********************************************************/
get_ad()
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|ADC_POSITION; //啟動ADC轉換
_nop_();
_nop_();
_nop_();
_nop_();
//默認ADRJ=0; 高8位+低2位
while(!(ADC_CONTR & ADC_FLAG)); //等待ADC轉換結束
ADC_CONTR &= ~ADC_FLAG; //必須軟件清0
adval=ADC_RES; //00000000 00000011 高8位
adval=ADC_RES<<2|ADC_RESL; //00000011 11111111 右對齊 高8位+低2位 // a|b;
adval=adval/1.024;
return (adval);
}
/******************取20次AD轉換值 求平均值*****************/
AD_work()
{
uint advalf=0; //定義處理后的數值AD_val為浮點數
uchar i;
for(i=0;i<50;i++)
{
advalf=advalf+get_ad(); //轉換20次求平均值(提高精度)
delay(2);
}
advalf=advalf/50;
return advalf;
}
/*****************************************
定時器中斷子程序
*****************************************/
void Timer0_PL() interrupt 1 //頻率定時器0中斷
{
TH0=(65536-20000)/256; //定時器0的初值20ms
TL0=(65536-20000)%256;
s1++;
display(); //顯示
if(s1==25)
{
s1=0;
sec++;
}
if(sec==60)
{
sec=0;
ADC_POSITION=0x05; //ADC輸入選擇改動過
show1=get_ad();
}
}
/******************************************************
** 函數名稱: void InitADC()
** 功能描述: 初始化AD功能
** 輸 入: 無
** 輸 出: 無
** 全局變量: 無
** 調用模塊: Delay_ms
*********************************************************/
void InitADC()
{
P1ASF = 0x30; //使能P1.5,p1.4為AD輸入改動過
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = ADC_POWER|ADC_SPEEDLL|ADC_START|ADC_POSITION;
// IE = 0xa0;
delay(10);
}
/**************************主函數***********************/
main()
{
system_init();
InitADC();
while(1)
{
show=AD_work(); //讀取AD值
}
}
|