代码:
hardware.c
/*
《AVR专题精选》随书例程
2.编程技巧
项目:查表法使用NTC测量温度
文件:hardware.c
说明:硬件驱动文件
作者:邵子扬
时间:2012年12月12日
*/
#include "hardware.h"
// IO初始化
void IO_init()
{
}
// 串口初始化
void UART_init()
{
unsigned int UBRRREG;
UBRRREG = F_CPU / ( 8 * BAUDRATE ) - 1;
UBRRH = UBRRREG / 256;
UBRRL = UBRRREG % 256;
UCSRA = ( 1 << U2X );
UCSRB = ( 1 << TXEN );
UCSRC = (1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );
}
// 输出字符串
void UART_puts( char *s )
{
while( *s )
{
UART_write( *s );
s++;
while( !( UCSRA & (1 << TXC )) );
UCSRA |= ( 1 << TXC );
}
}
void MCU_init()
{
}
// ADC模块初始化
void ADC_init()
{
// AVCC做基准源,时钟8分频
ADMUX = 0;
ADCSRA = (1 << ADEN)|(1 << ADPS1)|(1 << ADPS0);
}
// ADC转换
// chn: ADC通道号
// 返回:ADC的10位转换结果
unsigned int getADC(unsigned char chn)
{
ADMUX = (chn % 16);
ADCSRA = (1 << ADEN)|(1 << ADPS1)|(1 << ADPS0)|(1 << ADSC);
while(ADCSRA & (1 << ADSC));
return ADC;
}
ntc_table.c
/*
《AVR专题精选》随书例程
2.编程技巧
项目:查表法使用NTC测量温度
文件:ntc_tab.c
说明:NTC查表法函数
系统参数:
RT0 = 10000
B = 3380
温度范围: -50 - 70
步长: 5
ADC 位数: 10
作者:邵子扬
EMAIL:shaoziyang@@126.com
时间:2012年12月12日
*/
#include <avr/pgmspace.h>
#include "ntc_tab.h"
#define NTC_Step 50
#define NTC_Start -500
#define NTC_TabCnt 25
// Table for NTC: [ -50 - 70 ]
PROGMEM unsigned int NTCTABLE[NTC_TabCnt] = {
1002, 993, 982, 968, 951, // -50 - -30
929, 904, 873, 838, 799, // -25 - -5
756, 710, 661, 611, 561, // 0 - 20
512, 464, 419, 376, 337, // 25 - 45
301, 268, 239, 212, 189 // 50 - 70
};
/*
val: ADC value
return: Temperature * 10
eg, -224 = -22.4 C
300 = 30.0 C
*/
signed int getTemperature(unsigned int val)
{
unsigned char i;
for( i = 0; i < NTC_TabCnt; i++ )
{
if(pgm_read_word(NTCTABLE + i) <= val)
break;
}
if(i == 0)
return NTC_Start;
if(i == NTC_TabCnt)
return (NTC_Start + (NTC_TabCnt - 1) * NTC_Step);
return ( NTC_Start + (i - 1) * NTC_Step + \
NTC_Step * (pgm_read_word(&NTCTABLE[i - 1]) - val) / \
(pgm_read_word(&NTCTABLE [i - 1]) - pgm_read_word(&NTCTABLE[i])));
}
main.c
/*
《AVR专题精选》随书例程
2.编程技巧
项目:查表法使用NTC测量温度
文件:main.c
说明:主程序
作者:邵子扬
时间:2012年12月12日
*/
#include "hardware.h"
#include "ntc_tab.h"
#include <util/delay.h>
// 系统初始化
void SYS_init()
{
MCU_init();
IO_init();
UART_init();
}
signed int TMP;
char s[10];
int main()
{
SYS_init(); // 初始化
while(1)
{
// 读取ADC,并通过查表函数转换为实际温度值
TMP = getTemperature(getADC(chnTMP));
if (TMP >= 0) // 判断符号位
s[0] = ' ';
else
{
s[0] = '-';
TMP = -TMP;
}
s[1] = TMP / 100 + '0'; // 将结果转换为字符串
TMP = TMP % 100; // 为了节省资源,没有使用标准库函数
s[2] = TMP / 10 + '0';
s[3] = '.';
s[4] = TMP % 10 + '0';
s[5] = 0;
UART_puts(s); // 输出结果
UART_puts("\r\n"); // 输出回车
_delay_ms(500); // 延时500ms
}
return 0;
}
仿真效果图;