?? temperature.c
字號(hào):
/*----------------------------------------------------------------------------
拔下短路環(huán)J8,連上短路環(huán) J10,J12和J21。
功能:在LCD上顯示從內(nèi)部溫度傳感器傳來(lái)的溫度值.
------------------------------------------------------------------------------*/
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f330.h>
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F33x
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xca; // 定時(shí)器2重裝載寄存器
sfr16 TMR2 = 0xcc; // 定時(shí)器2計(jì)數(shù)寄存器
sfr16 ADC0 = 0xbd; // ADC 數(shù)據(jù)寄存器
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // 系統(tǒng)時(shí)鐘頻率
#define BAUDRATE 9600 // UART的波特率
#define TIMER2_RATE 1000 // 定時(shí)器2溢出率
//sbit LED = P1^0; // LED='1' 為開(kāi)
//-----------------------------------------------------------------------------
// Temperature Sensor Calibration PARAMETERS
//-----------------------------------------------------------------------------
#define AMB_TEMP 22 // Ambient Calibration Temperature
// (degC)此校準(zhǔn)值取決于運(yùn)行程序時(shí)的環(huán)境溫度
#define TEMP_SENSOR_GAIN 2860 // Temp Sensor Gain in (uV / degC)
#define VREF 3300 // ADC 參考電壓 (mV)
#define SOAK_TIME 15 // Soak Time in Seconds
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
// 在FLASH存儲(chǔ)空間分配2字節(jié)
// 用來(lái)存儲(chǔ)溫度校準(zhǔn)值
unsigned int code TEMP_OFFSET = 0xFFFF;
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void ADC0_Init (void);
void UART0_Init (void);
void PORTa_Init (void);
void Timer2_Init (int);
void Write_COM(unsigned yjcom );
void Write_CHAR(unsigned char yjchar);
void YJ_Init(void);
int get_temp (void);
void calibrate(void);
unsigned int measure(void);
void wait_one_second (void);
unsigned int m1,m2,m3,m4;
unsigned char aa,bb,cc,dd;
unsigned char xdata tab2[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
int k;
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) {
unsigned temperature;
unsigned int i;
PCA0MD &= ~0x40; // 禁止看門(mén)狗
PORTa_Init(); // 端口初始化
SYSCLK_Init (); // 系統(tǒng)時(shí)鐘
ADC0_Init (); // 初始化
Timer2_Init(SYSCLK/TIMER2_RATE); // 定時(shí)器2初始化
UART0_Init();
AD0EN = 1; // 使能ADC0
if (TEMP_OFFSET == 0xFFFF) { // TRUE if first-time to execute
printf ("Calibrating...\n");
calibrate (); // execute calibration sequence
} else {
printf ("Not calibrating.\n");
}
while (1) {
temperature = get_temp ();
printf ("Temperature = %+02d hundredths degrees C\n", temperature);
m1=temperature/1000;
m2=(temperature-1000*m1)/100;
m3=(temperature-1000*m1-100*m2)/10;
m4=temperature-1000*m1-100*m2-10*m3;
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
i=0;
do
{;
if(i==m1)aa=tab2[i];
if(i==m2) bb=tab2[i];
if(i==m3) cc=tab2[i];
if(i==m4) dd=tab2[i];
i++;
}while(i<10);
YJ_Init();
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
Write_CHAR(aa);
Write_CHAR(bb);
Write_CHAR(0x2e);
Write_CHAR(cc);
Write_CHAR(dd);
Write_CHAR(0xdf);
Write_CHAR(0x43);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
for(k=0;k<4000;k++);
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// 配置交叉開(kāi)關(guān)和所用端口.
//
// P0.4 - UART TX
// P0.5 - UART RX
// P1.0 - LED
void PORTa_Init (void)
{
P0MDOUT |= 0x10; //使能TX為推挽輸出
XBR0 = 0x01; // 使能UART P0.4(TX) and P0.5(RX)
XBR1 = 0x40; // 使能交叉開(kāi)關(guān)和弱上拉
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
//
void SYSCLK_Init (void)
{
OSCICN |= 0x03; // 配置為內(nèi)部晶振
//
RSTSRC = 0x04; // 使能時(shí)鐘丟失檢測(cè)
}
//-----------------------------------------------------------------------------
// ADC0_Init ADBUSY, LP tracking, no Interrupt, ADC disabled
//-----------------------------------------------------------------------------
//
// 配置 ADC0 的 ADBUSY為作為開(kāi)始轉(zhuǎn)換標(biāo)志,
// 禁止ADC轉(zhuǎn)換完進(jìn)入中斷.
//
void ADC0_Init (void)
{
ADC0CN = 0x40; // ADC0 禁止; LP tracking
// mode; ADC0 conversions are initiated
// on a write to ADBusy
AMX0P = 0x10; // 溫度傳感器的輸出作為正端輸入
AMX0N = 0x11; // 單端模式
ADC0CF = (SYSCLK/3000000) << 3; // ADC 轉(zhuǎn)換時(shí)鐘為 3MHz
ADC0CF &= ~0x04; // 使 ADC0 右對(duì)齊
REF0CN = 0x0e; // 使能溫度傳感器, VREF = VDD, 偏置電壓產(chǎn)生
EIE1 &= ~0x08; // 禁止ADC 中斷
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// 用定時(shí)器配置UART0.
//
void UART0_Init (void)
{
SCON0 = 0x10;
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x09;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
TL1 = TH1; // init Timer1
TMOD &= ~0xf0; // TMOD: 定時(shí)器1,8位自動(dòng)重裝載
TMOD |= 0x20;
TR1 = 1; // 啟動(dòng)定時(shí)器1
TI0 = 1; // 指示 TX0準(zhǔn)備好
}
//-----------------------------------------------------------------------------
// Timer2_Init SYSCLK no Interrupt
//-----------------------------------------------------------------------------
//
// 配置 Timer2自動(dòng)重裝載,從裝載值為 <counts> (不產(chǎn)生中斷).
//使用系統(tǒng)時(shí)鐘作為時(shí)間基準(zhǔn).
void Timer2_Init (int counts)
{
TMR2CN = 0x00; // 禁止Timer2; 清 TF2H and TF2L;
// 禁止低字節(jié)中斷產(chǎn)生
// 分離模式; 選擇內(nèi)部時(shí)間基準(zhǔn)
CKCON |= 0x10; // Timer2 用系統(tǒng)時(shí)鐘作為基準(zhǔn)
TMR2RL = -counts; // 初始化定時(shí)器2重裝載值
TMR2 = TMR2RL;
ET2 = 0; // 禁止定時(shí)器2中斷
TR2 = 1; // 啟動(dòng)定時(shí)器2
}
//-----------------------------------------------------------------------------
// wait_soak_time
//-----------------------------------------------------------------------------
//
// 這段程序用來(lái)延時(shí)一定時(shí)間等待輸出穩(wěn)定結(jié)果.
//
void wait_soak_time (unsigned char soak_time)
{
unsigned char i;
for( i = soak_time; i != 0; i--) {
wait_one_second();
printf ("Soaking...%d\n", (int) i);
}
}
//-----------------------------------------------------------------------------
// 延時(shí)1秒
//-----------------------------------------------------------------------------
void wait_one_second (void)
{
unsigned int count;
TF2H = 0; // 清定時(shí)器2溢出標(biāo)志
TR2 = 1; // 啟動(dòng)定時(shí)器2
for (count = TIMER2_RATE; count != 0; count--) {
while (!TF2H); // 等待溢出
TF2H = 0; // 清溢出標(biāo)志
}
TR2 = 0; // 定時(shí)器2禁止
}
//-----------------------------------------------------------------------------
// calibrate
//-----------------------------------------------------------------------------
//
void calibrate (void)
{
bit EA_state=EA; // 保存EA狀態(tài)
unsigned char xdata * codePtr; // 用于在FLASH存儲(chǔ)空間寫(xiě)校準(zhǔn)值
unsigned int code* data pread; // 讀FLASH指針
long temp_offset; // 存儲(chǔ)ADC的返回值
pread = (unsigned int code *) TEMP_OFFSET;
wait_soak_time(SOAK_TIME); // 等待使溫度穩(wěn)定
temp_offset= (long) measure (); // 讀取ADC過(guò)采樣代碼
// now calculate the 0 DEG C offset value using <temp_offset>, the
// temp sensor gain (TEMP_SENSOR_GAIN), and the ambient temperature.
temp_offset = temp_offset - ((long) AMB_TEMP *
TEMP_SENSOR_GAIN / VREF * 65536 / 1000);
codePtr=(unsigned char xdata*) &TEMP_OFFSET;
// 指向 TEMP_OFFSET
EA = 0; //總的中斷禁止
FLKEY=0xA5; // 輸入第一個(gè)關(guān)鍵代碼
FLKEY=0xF1; //輸入第二個(gè)關(guān)鍵代碼
// FLASH 現(xiàn)在沒(méi)有被鎖定
PSCTL |= 0x01; // FLASH 寫(xiě)使能
*codePtr = (temp_offset>>8); // 寫(xiě)temp_offset的高8位值
PSCTL &= ~0x01; // FLASH 寫(xiě)禁止
codePtr++; // Move to low byte of
// 移動(dòng)地址指針用來(lái)
//存儲(chǔ)采樣值的低字節(jié)
FLKEY=0xA5; // 輸入第一個(gè)關(guān)鍵代碼
FLKEY=0xF1; // 輸入第二個(gè)關(guān)鍵代碼
// FLASH 現(xiàn)在沒(méi)有被鎖定
PSCTL |= 0x01; // FLASH 寫(xiě)使能
*codePtr =temp_offset; //寫(xiě)temp_offset的低8位值
PSCTL = 0x00; // FLASH 寫(xiě)禁止
EA = EA_state; // 恢復(fù)EA狀態(tài)
}
//-----------------------------------------------------------------------------
// measure
//-----------------------------------------------------------------------------
//
// 本程序通常進(jìn)行 16383 ADC采樣并且返回16位無(wú)符號(hào)結(jié)果
unsigned int measure (void)
{
unsigned i; // 采樣計(jì)數(shù)器
unsigned long accumulator=0L; // ADC采樣值的總和
unsigned int currval;
AD0INT = 0;
AD0BUSY = 1;
// 讀ADC值進(jìn)行累加
i = 0;
do
{
while (!AD0INT); // 等待轉(zhuǎn)換完成
AD0INT = 0; // 清轉(zhuǎn)換中斷標(biāo)志
currval=ADC0; // 存儲(chǔ)最終ADC轉(zhuǎn)換值
AD0BUSY = 1; // 啟動(dòng)ADC轉(zhuǎn)換
accumulator += currval; // 累加
i++; // 更新記數(shù)值
} while (i != 16383);
return (unsigned int) (accumulator >> 8);
// 轉(zhuǎn)換到獲取16位的結(jié)果 (14 + 10 = 24 - 8 = 16) bits
}
int get_temp (void)
{
unsigned int ADC_code;
long result;
ADC_code = measure();
result = ADC_code - TEMP_OFFSET;
result = result * (long) VREF / 256 * 1000 / TEMP_SENSOR_GAIN * 100 / 256;
return (int) result;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -