//*******************************************************************
********************//
//************************2013-09-
25*****************************************************//
//**********************************湖南工业大学
*****************************************//
//*******************************************QQ:401167823************
********************//
//**********************功能:差分 AD 电压测量
*********************************************//
#include "C8051F120.h"
#include
#define uint unsigned int
#define uchar unsigned char
#define SYSCLK 24500000 // Output of PLL derived from (INTCLK*2)
#define SAR_CLK 2500000 // Desired SAR
#define HIGH ((65536-2450)/256) //24.5 定时 100US
#define LOW ((65536-2450)%256)
#define t 1
uchar temp_l,temp_h,count;
uint mm;
double AD;
int temp;
// Peripheral specific initialization functions,
// Called from the Init_Device() function
unsigned char code table1[]={0x03,0x9f,0x25,0x0d,
0x99,0x49,0x41,0x1f,
0x01,0x09,0x11,0xc1,
0x63,0x85,0x61,0x71,0xfd
};//段选 P0
unsigned char code sel[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选 P2
/********************************************************************
*******
软件延时 i*1ms 在内部时钟 24.5MHZ
*********************************************************************
******/
void delay(unsigned int n) //i*1MS 延时,在内部时钟 24.5MHZ 时
{
unsigned int i,j;
for(i = 0; i < n; i++)
for (j = 0; j < 3450; j++); // Wait 1ms for initialization
}
void Reset_Sources_Init()
{
WDTCN = 0xDE;
//禁止看门狗
WDTCN = 0xAD;
}
/*******************定时器 2 自动重载
***********************************************/
void Timer_Init()
{
SFRPAGE = TMR2_PAGE;
ET2=1;
TMR2CN = 0x04;
TMR2CF = 0x08;
RCAP2L = LOW;
RCAP2H = HIGH;
TMR2L = RCAP2L;
TMR2H = RCAP2H;
}
/**************************************ADC0 初始化
**************************************/
void ADC_Init()
{
/*SFRPAGE = ADC0_PAGE;
ADC0CF = 0x20;
ADC0CN = 0x8C;*/
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = ADC0_PAGE;
ADC0CN = 0x0C; // ADC0 disabled; normal tracking
// mode; ADC0 conversions are initiated
// on overflow of Timer3; ADC0 data is
// right-justified
REF0CN = 0x03; // Enable temp sensor, on-chip VREF,
// and VREF output buffer
AMX0CF = 0x0f; // 差分输入
AMX0SL = 0x00; // Select AIN0.0 0.1 pin as ADC mux input
ADC0CF = 0x48; // ADC conversion clock = 2.5MHz
(SYSCLK/2/SAR_CLK) << 3
ADC0CF |= 0x00; // PGA gain = 1 (default)
EIE2 |= 0x02; // enable ADC interrupts
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
void Port_IO_Init()
{
SFRPAGE = CONFIG_PAGE;
P0MDOUT = 0xFF;
P1MDOUT = 0xFF;
P2MDOUT = 0xFF;
P3MDOUT = 0xFF;
P4MDOUT = 0xFF;
P5MDOUT = 0xFF;
P6MDOUT = 0xFF;
P7MDOUT = 0xFF;
XBR2 = 0x40;
}
/********************************************************************
********************
内部时钟 24.5M 配置
*********************************************************************
********************/
void Oscillator_Init()
{
SFRPAGE = CONFIG_PAGE;
OSCICN = 0x83;
}
/********************************************************************
********************
根据数值大小选择相应的处理函数,显得有些繁琐,但还没有其他算法之前也显得还
可以
*********************************************************************
*******************/
void display(uint temp1)
{
unsigned char j,k,m,temp2;
if(temp1>2430)
P1=table1[14];
P2=0xf0;
{
}
else
{
//i=temp1/1000;
//j=temp1%1000/100;
//k=temp1%1000%100/10;
//m=temp1%10;
temp2=ADC0H&0xf0;
if(temp2==0x00)
{
}
P1=0xff;
//正电压第四位不显示
P2=sel[3];
delay(t);
P2=0xff;
P1=0xff;
示符号
if(temp2==0xf0)
temp1=243*2-temp1;
//负电压处理 。第四位显
P1=table1[16];
P2=sel[3];
delay(t);
P2=0xff;
P1=0xff;
{
}
j=temp1/100;
k=temp1%100/10;
m=temp1%10;
//P1=table1[i]&0xfe;
//P2=sel[3];
//delay(t);
//P2=0xff;
//P1=0xff;
P1=table1[j]&0xfe;
P2=sel[2];
delay(t);
P2=0xff;
P1=0xff;
P1=table1[k];
P2=sel[1];
delay(t);
P2=0xff;
P1=0xff;
P1=table1[m];
P2=sel[0];
delay(t);
P2=0xff;
P1=0xff;
}
}
// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
Reset_Sources_Init();
Port_IO_Init();
Oscillator_Init();
ADC_Init();
//Voltage_Reference_Init();
Timer_Init();
//Interrupts_Init();
}
void main()
{
Init_Device();
SFRPAGE = ADC0_PAGE;
//AD0EN = 0; // Enable ADC
//delay(t);
AD0EN = 1; // Enable ADC
EA = 1; // Enable global interrupts
while(1)
{
}
display(temp);
}
//这个入口地址千万别搞错
//溢出位一定要清零!
void timer2() interrupt 5
TF2=0;
{
}
void ADC0_ISR (void) interrupt 15
{
AD0INT=0;
//清 A/D 中断标志
EA=0;
temp_l=ADC0L;
temp_h=ADC0H&0x0f;
mm=temp_h*256+temp_l;
AD+=mm;
count++;
if(count==20)
{
count=0;
mm=0;