如题,STC8G1K08最小系统开发板,学习NTC采样,参照@布丁橘长 的NTC经验公式法来采样温度,数码管一直显示38.5。完全搞不清楚问题出在哪。还请大佬花费点时间指点迷津,万分感谢。
#include "stc8xxxx.h"
#include "math.h"
#include "intrins.h"
#include "ADfliter.h"
#include "NTC.h"
#define MAIN_Fosc 24000000UL //定义主频24MHz,请根据实际使用频率修改(用于delay函数自适应主频)
#define Timer0_Reload (MAIN_Fosc / 1000) //Timer 0 中断频率, 1000次/秒
#define Timer1_Reload (MAIN_Fosc / 1000) //Timer 1 中断频率, 1000次/秒
#define Vref 5
sbit DS = P1^7; //串行输入接P2.0
sbit ST = P1^6; //锁存时钟接P2.1
sbit SH = P1^5; //串行输入时钟接P2.2
sbit COM1 = P1^2; //数码管公共端COM1接P1.2
sbit COM2 = P1^3; //数码管公共端COM2接P1.3
sbit COM3 = P1^4; //数码管公共端COM3接P1.4
sbit LED = P5^4;
bit B_1ms; // 1ms计时标志
u16 adc_result; // ADC转换结果
u16 adc_volt; // ADC换算后的电压
u16 value; // ADC采样值变量
u8 segdelay; // 数码管延时计数
u32 temperature;
// 0 1 2 3 4 5 6 7 8 9 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. A B C D E F
u8 SEG_Code[29] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x88,0x83,0xc6,0xa1,0x86,0x8e, //共阳数码管段码:0~F,
0xFF,0xBF,0x00}; //数码管全灭(17),横杆-(18),数码管全亮(19)
void delayms(u16 ms) //简单延时函数,自适应主频,1毫秒*ms
{
u16 i;
do{
i = MAIN_Fosc / 15000;
while(--i);
}while(--ms);
}
void ADC_Config()
{
ADC_CONTR = 0xC1;
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置 ADC 内部时序,ADC采样时间建议设最大值
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16/16
ADC_CONTR |= 0x80; //使能 ADC 模块
}
void Timer0_Isr(void) interrupt 1
{
B_1ms = 1; // 1毫秒到
segdelay++;
}
u16 Fliter_range()
{
static u16 new_value;
value = new_value;
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | 0x01; //启动 AD 转换
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & 0x20)) ; //等待转换完成
ADC_CONTR &= ~0x20; //清除ADC结束标志
new_value = ADC_RES*256 + ADC_RESL;
if((new_value - value > 500)||(value - new_value > 500)) return value;//跳变大于0.3V放弃本次采样值
else return new_value;
}
float CalculationTemperature(u16 adc)
{
float Temper=0.0; // 温度
float Rt=0.0; // NTC热敏电阻阻值
float R25=10000.0; // NTC热敏电阻25℃时的阻值:10K
float T2=298.15; // 273.15+25;
float B=3950.0; // 热敏指数3950
float K=273.15; // 绝对温度
float RtV=0.0; // NTC热敏电阻电压
RtV = (adc*(Vref/4096)); // NTC电压
Rt = (RtV*R25)/(Vref-RtV); // NTC阻值
Temper = 1.0/(log(Rt/R25)/B + 1.0/T2)-K; // 经验公式计算温度
return Temper; // 返回温度值
}
void Timer0_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x20; //设置定时初始值
TH0 = 0xD1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计数
ET0 = 1; //使能定时器0中断
}
void Write595(u8 dat) //向595写数据函数
{
u16 i;
u8 datcode;
datcode = SEG_Code[dat]; //十进制数转段码
for(i = 0;i < 8;i++) //写数据
{
SH = 0; //拉低串行输入时钟SCLK
DS = datcode & 0x80; //取最高位
SH = 1; //SCKL时钟上升沿,数据存移位寄存器
datcode <<= 1; //每次一位
}
ST = 0; //拉低ST时钟
ST = 1; //ST时钟上升沿,更新输出存储器数据
}
//显示扫描函数
void DisplayScan(void)
{
while(1)
{
Write595((u8)(temperature/100)-10); //显示00-999计数百位
COM1 = 0;
COM2 = 0;
COM3 = 1; //共阳极数码管,公共端给高电平点亮,点亮数码管左起第1位
delayms(3); //延时3毫秒
Write595((u8)(temperature/10)+10); //显示00-999计数十位
COM1 = 0;
COM2 = 1;
COM3 = 0; //共阳极数码管,公共端给高电平点亮,点亮数码管左起第2位
delayms(3); //延时3毫秒
Write595((u8)(temperature%10)); //显示00-999计数个位
COM1 = 1;
COM2 = 0;
COM3 = 0; //共阳极数码管,公共端给高电平点亮,点亮数码管左起第3位
delayms(3); //延时3毫秒
}
}
void main(void)
{
P1M1 = 0x03;P1M0 = 0x1C; //设置P1口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
P3M1 = 0x14;P3M0 = 0x28; //设置P3口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出 0001 0100
P5M1 = 0x00;P5M0 = 0x10; //设置P5口模式 00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出 0010 1000
ADC_Config();
Timer0_Init(); // 定时器0初始化
EA = 1; // 使能EA总中断
ADC_CONTR |= 0x40; // 先启动一次ADC
LED = 0;
while (1)
{
adc_result = Fliter_range();
temperature = CalculationTemperature(adc_result)*10;
/*volt_int1 = temperature /100;
volt_int2 = temperature / 10;
volt_int3 = temperature % 10;
//volt_float1 = (temperature)% 10; */ // 电池电压,小数点后第2位
DisplayScan(); // 刷新数码管
}
}