📄 main.c
字号:
//***************************************************
//*功能:NTC测温 *
//*硬件:AtemlMega16L LCM1286*64 ST7920 *
//* NTC MF58502F327 R=5K B=3270K *
//*编译:WinAVR-20050214 *
//*作者:陈崇 QQ:86395850 EMAIL:worm.chen@163.com *
//*日期:2007.5.29 *
//***************************************************
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>
#include <lcm12864.h>
#define VREF 4740 // 实测的Vref引脚电压@4.74V供电
#define R 5020 // 分压电阻
#define VCC 4740 // 电源电压mV
const unsigned char icon_rt[] PROGMEM= // 热敏电阻
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x02,0x00,0x1F,0xF8,0xF1,0x0F,
0x10,0x88,0x1F,0xF8,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
const unsigned char icon_volt[] PROGMEM= // 电压表
{
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFC,0x10,0x04,0x12,0x24,0x12,0x24,0x11,0x44,
0x10,0x84,0x1F,0xFC,0x10,0x04,0x12,0x24,0x10,0x04,0x1F,0xFC,0x00,0x00,0x00,0x00,
};
const unsigned char icon_temp[] PROGMEM= // 温度计
{
0x00,0x00,0x03,0xD0,0x02,0x46,0x03,0x48,0x02,0x48,0x03,0x46,0x02,0x40,0x03,0x40,
0x02,0x40,0x03,0x40,0x02,0x40,0x02,0x40,0x04,0x20,0x04,0x20,0x02,0x40,0x01,0x80,
};
const unsigned int vt_table[] PROGMEM= // 电压温度对照表
{
4132,4098,4063,4026,3988,3949,3908,3866,3823,3779,
3733,3686,3639,3590,3540,3489,3437,3385,3331,3277,
3222,3166,3110,3054,2997,2940,2882,2824,2767,2709,
2651,2593,2536,2478,2421,2365,2309,2253,2198,2143,
2089,2036,1984,1932,1881,1831,1782,1734,1686,1640,
1594,1550,1506,1464,1422,1381,1341,1303,1265,1228,
1192
};
unsigned int temp; // 温度
unsigned int adc_volt; // 测试点电压
unsigned int rt; // 热敏电阻
//***********************************************************************
//*名称: unsigned int GetADC(unsigned char adc_channel) *
//*功能: 获取ADC转换值程序 *
//*参数: adc_channel 转换通道 *
//*返回: ADC值 *
//***********************************************************************
unsigned int GetADC(unsigned char adc_channel)
{
unsigned char i;
unsigned int adc_value[8]; // AD转换缓冲区
unsigned int adc_value_ave=0;
unsigned int max_value=0,min_value=0,max_index=1,min_index=1;
ADMUX=((1<<REFS0)|adc_channel); // 选择ACC参考电压和测试转换通道
for(i=0;i<8;i++) // 连续AD转换8次
{
ADCSRA|=(1<<ADSC); // 启动AD转换
loop_until_bit_is_set(ADCSRA,ADIF); // 等待AD转换结束
ADCSRA|=(1<<ADIF); // 写1清除标志位
adc_value[i]=ADC; // 将单次ADC转换结果=ADCH:ADCL放入缓冲区
}
for(i=1;i<8;i++) // 去掉第一次测量值
{
adc_value_ave+=adc_value[i];
}
adc_value_ave/=7; // 去掉一个值外的平均值
for(i=1;i<8;i++) // 计算最大值和最小值索引号
{
if(adc_value[i]>adc_value_ave)
{
if((adc_value[i]-adc_value_ave)>max_value)
{
max_value=adc_value[i];
max_index=1;
}
}
else
{
if((adc_value_ave-adc_value[i])>min_value)
{
min_value=adc_value_ave-adc_value[i];
min_index=i;
}
}
}
adc_value_ave=0;
for(i=1;i<8;i++) // 计算去掉最大值和最小值后的总和
{
if((i!=max_index)&&(i!=min_index))
{
adc_value_ave+=adc_value[i];
}
}
if(max_index!=min_index) // 如果测量值不同
{
adc_value_ave/=5; // 计算平均值
}
else // 如果测量值相同
{
adc_value_ave/=6; // 计算平均值
}
ADCSRA&=~(1<<ADSC); // 停止AD转换
return adc_value_ave;
}
//***********************************************************************
//*名称: unsigned char GetTemp(unsigned int adc_volt) *
//*功能: 获取温度值 程序 *
//*参数: adc_channel ADC电压 *
//*返回: 温度值 *
//***********************************************************************
unsigned char GetTemp(unsigned int adc_volt)
{
unsigned char i;
unsigned char temp=0;
for(i=0;i<61;i++)
{
if(adc_volt>=pgm_read_word(vt_table+i)) // 查表计算温度
{
temp=i;
if(temp<10) // -10~-1
{
temp|=0x80; // 加负温度标志
}
else // 0~50
{
temp-=10;
}
return temp;
}
}
temp=255; // 如果超出范围返回255
return temp;
}
int main(void)
{
PORTA=(1<<PA7)|(1<<PA6)|(1<<PA5); // PA7-PA5输出高电平
DDRA|=(1<<PA7)|(1<<PA6)|(1<<PA5); // PA7-PA5设置为输出
PORTD|=(1<<PD7)|(1<<PD0); // PD7 PD1 PD0输出高电平
DDRD=(1<<PD7)|(1<<PD6)|(1<<PD1)|(1<<PD0); // PD7 PD6 PD1 PD0设置为输出
ADCSRA|=(1<<ADEN); // 使能ADC
lcm12864_init();
lcm12864_clear();
lcm12864_cls_gdram(); lcm12864_dis_string(2,0,"NTC 测温",0);
lcm12864_dis_string(6,1,"Ω",0);
lcm12864_dis_string(6,2,"mV",0);
lcm12864_dis_string(6,3,"℃",0);
lcm12864_dis_dot(2,1,icon_rt);
lcm12864_dis_dot(2,2,icon_volt);
lcm12864_dis_dot(2,3,icon_temp);
while(1)
{
adc_volt=(int)((long)GetADC(0)*VREF/1024);
rt=(int)(((long)adc_volt*R)/(VCC-adc_volt));
temp=GetTemp(adc_volt);
lcm12864_char_locate(4,1);
lcm12864_dis_ascii(0x30+rt/1000);
lcm12864_dis_ascii(0x30+rt%1000/100);
lcm12864_dis_ascii(0x30+rt%100/10);
lcm12864_dis_ascii(0x30+rt%10);
lcm12864_char_locate(4,2);
lcm12864_dis_ascii(0x30+adc_volt/1000);
lcm12864_dis_ascii(0x30+adc_volt%1000/100);
lcm12864_dis_ascii(0x30+adc_volt%100/10);
lcm12864_dis_ascii(0x30+adc_volt%10);
lcm12864_char_locate(4,3);
if(temp&0x80)
{
lcm12864_dis_ascii('-');
}
else
{
lcm12864_dis_ascii('+');
}
lcm12864_dis_ascii(0x30+temp%100/10);
lcm12864_dis_ascii(0x30+temp%10);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -