📄 t2cal33x.c
字号:
//-----------------------------------------------------------------------------
// T2Cal33x.c
//-----------------------------------------------------------------------------
// 版权归新华龙电子有限公司所有
//
// 作者:Robi Ken
// 日期: 2004.12.30
//
// 功能:使用片内温度传感器实验
// 目标板: C8051F33x
// 开发工具: Silicon Laboratories IDE
//-----------------------------------------------------------------------------
// 头文件
//-----------------------------------------------------------------------------
#include <c8051f330.h>
#include <stdio.h>
//-----------------------------------------------------------------------------
// F31x’定时器2的16位SFR
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xca;
sfr16 TMR2 = 0xcc;
sfr16 ADC0 = 0xbd;
//-----------------------------------------------------------------------------
// 常量定义
//-----------------------------------------------------------------------------
#define SYSCLK 24500000
#define BAUDRATE 9600
#define TIMER2_RATE 1000
sbit LED = P1^3;
//-----------------------------------------------------------------------------
// 温度传感器参数
//-----------------------------------------------------------------------------
#define AMB_TEMP 25
#define TEMP_SENSOR_GAIN 2860
#define VREF 2430 // ADC 基准电压 (mV)
#define SOAK_TIME 15
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
unsigned int code TEMP_OFFSET = 0xFFFF;
//-----------------------------------------------------------------------------
// 功能函数
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void ADC0_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void Timer2_Init (int);
int get_temp (void);
void calibrate(void);
unsigned int measure(void);
void wait_one_second (void);
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
void main (void) {
unsigned temperature;
PCA0MD &= ~0x40; // 禁止看门狗
PORT_Init();
SYSCLK_Init ();
ADC0_Init ();
Timer2_Init(SYSCLK/TIMER2_RATE);
UART0_Init();
AD0EN = 1; // 使能 ADC0
if (TEMP_OFFSET == 0xFFFF) {
printf ("Calibrating...\n");
calibrate ();
} else {
printf ("Not calibrating.\n");
}
while (1) {
LED = 1;
temperature = get_temp ();
LED = 0;
printf ("Temperature = %+02d hundredths degrees C\n", temperature);
}
}
//-----------------------------------------------------------------------------
// 初始化子程序
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 端口初始化
//-----------------------------------------------------------------------------
//
// P0.4 - UART TX
// P0.5 - UART RX
// P3.3 - LED
void PORT_Init (void)
{
P0SKIP |= 0x01;
P0MDIN |= 0x01;
P0MDOUT |= 0x10;
P1MDOUT |= 0x08;
XBR0 = 0x01;
XBR1 = 0x40;
}
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN |= 0x03;
RSTSRC = 0x04;
}
//-----------------------------------------------------------------------------
// ADC0初始化、使能、中断
//-----------------------------------------------------------------------------
//
void ADC0_Init (void)
{
ADC0CN = 0x40;
AMX0P = 0x10;
AMX0N = 0x11;
ADC0CF = (SYSCLK/3000000) << 3;
ADC0CF &= ~0x04;
REF0CN = 0x0e;
EIE1 &= ~0x08;
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
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;
TMOD &= ~0xf0;
TMOD |= 0x20;
TR1 = 1;
TI0 = 1;
}
//-----------------------------------------------------------------------------
// 定时器2系统时钟中断
//-----------------------------------------------------------------------------
//
void Timer2_Init (int counts)
{
TMR2CN = 0x00;
CKCON |= 0x10;
TMR2RL = -counts;
TMR2 = TMR2RL;
ET2 = 0;
TR2 = 1;
}
//-----------------------------------------------------------------------------
// 等待处理结束
//-----------------------------------------------------------------------------
//
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);
}
}
//-----------------------------------------------------------------------------
// 延时1秒
//-----------------------------------------------------------------------------
void wait_one_second (void)
{
unsigned int count;
TF2H = 0; // 清除定时器2溢出标志
TR2 = 1; // 开始定时器2
for (count = TIMER2_RATE; count != 0; count--) {
while (!TF2H); // 等待溢出
TF2H = 0;
}
TR2 = 0; // 停止定时器2
}
//-----------------------------------------------------------------------------
// 校准
//-----------------------------------------------------------------------------
//
void calibrate (void)
{
bit EA_state=EA; // 保持EA状态
unsigned char xdata * codePtr;
unsigned int code* data pread;
long temp_offset;
pread = (unsigned int code *) TEMP_OFFSET;
wait_soak_time(SOAK_TIME);
temp_offset= (long) measure ();
temp_offset = temp_offset - ((long) AMB_TEMP *
TEMP_SENSOR_GAIN / VREF * 65536 / 1000);
codePtr=(unsigned char xdata*) &TEMP_OFFSET;
EA = 0; // 禁止中断
FLKEY=0xA5;
PSCTL |= 0x01; // 允许写FLASH
*codePtr = (temp_offset>>8);
PSCTL &= ~0x01; // 禁止写FLASH
codePtr++;
FLKEY=0xA5;
FLKEY=0xF1;
PSCTL |= 0x01; // 允许写FLASH
*codePtr =temp_offset;
PSCTL = 0x00; //禁止写FLASH
EA = EA_state; // 恢复中断状态
}
//-----------------------------------------------------------------------------
// measure
//-----------------------------------------------------------------------------
//
unsigned int measure (void)
{
unsigned i;
unsigned long accumulator=0L;
unsigned int currval;
AD0INT = 0;
AD0BUSY = 1;
i = 0;
do
{
while (!AD0INT);
AD0INT = 0;
currval=ADC0;
AD0BUSY = 1;
accumulator += currval;
i++;
} while (i != 16383);
return (unsigned int) (accumulator >> 8);
// shift to obtain a 16-bit result (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 * (VREF / 65536) * (1000 / TEMP_SENSOR_GAIN) * ( 100 )
// the equation above is re-arranged for fixed-point math.
result = result * (long) VREF / 256 * 1000 / TEMP_SENSOR_GAIN * 100 / 256;
return (int) result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -