/* 原程序是本坛下载的。 采用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值
}
}
|