使用單片機自帶的AD轉換功能將模擬量轉換為數字量,并以float輸發送給串口調試助手,但是發現通過調試助手得到的電壓值與實際測得的電壓值不同,小弟C語言能力一般,請大神們幫助看看程序應該怎門改。附上程序和部分原理圖。。。。。
#include "reg51.h"
#include "intrins.h"
#define FOSC 22118400L
#define BAUD 9600
#define V_SCALE (4.89f/1024)
typedef unsigned char BYTE;
typedef unsigned int WORD;
union float2int{
BYTE num[4];
float f;
}data_send;
/*聲明與ADC有關的SFR*/
sfr AUXR = 0x8e;
sfr ADC_CONTR = 0xC5;//ADC控制寄存器
sfr ADC_DATA = 0xC6;//DC高8為結果寄存器
sfr ADC_LOW2 = 0xBE;//ADC結果寄存器低2位有效
sfr P1M0 = 0x91;//P1口模式控制寄存器0
sfr P1M1 = 0x92;//P1口模式控制寄存器1
/*定義ADC_CONTR中ADC操作常量*/
#define ADC_POWER 0x80 //ADC電源控制位
#define ADC_FLAG 0x10 //ADC完成標志
#define ADC_START 0x08 //ADC開始控制位
#define ADC_SPEEDLL 0x00 //1080
#define ADC_SPEEDL 0x20 //810
#define ADC_SPEEDH 0x40 //540
#define ADC_SPEEDHH 0x60 //270 clocks
void InitUart();
void SendData(BYTE dat);
void Delay(WORD n);
void InitADC();
void SendHello(BYTE dat);
void ADC_DataProcess(void);
//ADC channel NO.
BYTE ch = 2;
void main()
{
InitUart();
InitADC();
AUXR |= 0x10;//set EADCI
IE = 0xa0;//開中斷
//EA = 1;
//SendHello('H');
while(1);
}
/**
* ADC interrupt service routine
*
*/
void adc_isr() interrupt 5 using 1
{
ADC_CONTR &= !ADC_FLAG;//清ADC中斷標志位
// SendData(ADC_DATA);
// SendData(ADC_LOW2);
// SendData('\n');
ADC_DataProcess();
// if((++ch) > 7)
// {
// ch = 0;
// SendData('\n');
// }
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
}
void ADC_DataProcess(void)
{
unsigned int temp;
unsigned int t2;
unsigned int t;
//float f;
temp = ADC_DATA;
t2 = ADC_LOW2;
temp = temp<<2;
temp = temp + t2;
t = temp * 478;//V_SCALE;
// SendData(data_send.num[3]);
// SendData(data_send.num[2]);
// SendData(data_send.num[1]);
// SendData(data_send.num[0]);
//f = f*1000.0;
SendData((t/100000) + '0');
SendData('.');
SendData((t/10000)%10 + '0');
SendData((t/1000)%10 + '0');
SendData(t%10 + '0');
SendData('\n');
}
/**
* Initial ADC sfr
*/
void InitADC()
{
P1 = P1M0 = P1M1 |= 0xff;//把P1設為開漏
ADC_DATA = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
Delay(2);
}
/**
* Initial UART
*/
void InitUart()
{
//PCON &= 0x7F; //波特率不倍速
SCON = 0x52; //8位數據,可變波特率
//TMOD &= 0x0F; //清除定時器1模式位
TMOD |= 0x20; //設定定時器1為8位自動重裝方式
TL1 = 0xFA; //設定定時初值
TH1 = 0xFA; //設定定時器重裝值
ET1 = 0; //禁止定時器1中斷
TR1 = 1; //啟動定時器1
}
/**
* 發送一個字節數據
*/
void SendData(BYTE dat)
{
while(!TI); //等待
TI = 0;
SBUF = dat;
}
void SendHello(BYTE dat)
{
while(!TI); //等待
TI = 0;
SBUF = dat;
}
/**
* 軟件延時
*/
void Delay(WORD n)
{
WORD x;
while(n--)
{
x = 5000;
while(x--);
}
}
|