|
发表于 2010-1-9 18:16:38
|
显示全部楼层
// icc 6.31a , atmage48, 8m osc
//热敏电阻:10KΩ B值:3380
#include <iom48v.h>
#include <macros.h>
#include <stdio.h>
#include <eeprom.h>
#define uchar unsigned char
#define uint unsigned int
#define LED_NUM PORTD
#define LED_VALUE PORTB
#define ADC_KEY 5
#define SOUND_OUT 0x04
#define DELAY_MIN 1100
uint v = 0;
uchar adc_channel = 0;
uchar hot_warning[4]={30,35,40,45};
uchar setting_mode = 0;
uchar auto_mode = 0x00;
const uchar disp_table[22] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x01,0x02,0x04,0x08,0x10};
// 溫度表 -10 度到 105 度
const uint v_table[116]={
895,932,969,1006,1045,1085,1125,1166,1208,1250, //-10 ---- -1
1294,1338,1382,1427,1473,1519,1566,1614,1661,1709,//0 ---- 9
1758,1807,1856,1905,1955,2004,2054,2104,2154,2204,//10 ---- 19
2253,2303,2353,2402,2451,2500,2549,2597,2645,2692,//20 ---- 29
2740,2786,2832,2878,2923,2968,3012,3056,3099,3141,//30 ---- 39
3183,3224,3265,3304,3344,3382,3420,3457,3493,3529,//40 ---- 49
3564,3599,3632,3665,3698,3729,3760,3791,3820,3849,//50 ---- 59
3878,3905,3932,3959,3985,4010,4034,4058,4082,4105,//60 ---- 69
4127,4149,4170,4191,4211,4231,4250,4269,4287,4304,//70 ---- 79
4322,4339,4355,4371,4387,4402,4417,4431,4445,4459,//80 ---- 89
4472,4485,4497,4510,4522,4533,4545,4556,4566,4577,//90 ---- 99
4587,4597,4607,4616,4625,4634};//100 ---- 105
const uchar sound[]={ //樂曲數据表
0x45,0x48,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x49,0x4a,
0x49,0x48,0x48,0x48,0x48,0x48,0x45,0x48,0x4a,0x4a,
0x48,0x4a,0x4c,0x4c,0x4b,0x4a,0x49,0x49,0x49,0x49,
0x49,0x4c,0x4b,0x4a,0x4a,0x4a,0x49,0x48,0x48,0x49,
0x4a,0x4c,0x4b,0x4b,0x4b,0x4b,0x4b,0x46,0x46,0x45,
0x45,0x45,0x47,0x48,0x49,0x49,0x4a,0x49,0x48,0x48,
0x48,0x48,0x48,0x48,
0x00,0x00
};
const uint TONETABLE[15]={ //音調頻率數据表
64580,64684,64777,64820,64898,64968,65030,65058,
65110,65157,65178,65217,65252,65283,65297
};
uint toneconst;
void delay_1ms(void)
{
uint i;
for (i=0;i<DELAY_MIN;i++);
WDR();
}
void delay_nms(uint n)
{
uint i;
for (i=0;i<n;i++)
delay_1ms();
}
void disp_led(uint value)
{
uchar i,j;
uchar led_data[5];
led_data[0] = adc_channel;
if ((value & 0x8000)==0x8000)
{
value &= 0x7fff;
led_data[4] = 16; // 顯示負號
}
else
{
value &= 0x7fff;
led_data[4] = value/1000;
};
led_data[3] = value/100%10;
led_data[2] = value/10%10;
led_data[1] = value%10;
for (j=0;j<20;j++)
{
for (i=0;i<5;i++)
{
LED_VALUE = disp_table[led_data];
if(i==2)
{
LED_VALUE |= 0x80; // 加上小數點
}
LED_NUM = ~BIT(i+3);
delay_nms(5);
LED_NUM = 0xff;
};
};
}
#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
uint temp;
temp = ADCL;
temp |= (int)ADCH<<8;
temp = (49*temp)/10;
v += temp;
}
void get_adc_value(uchar adc_pin)
{
uchar i;
v = 0x0000;
ADMUX = (1<<REFS0)|adc_pin;
// for(i=0;i<2;i++)
{
// ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
ADCSRA |= (1<<ADSC);
delay_nms(1);
// while((ADCSRA & (1<<ADIF))==0);
ADCSRA &= ~(1<<ADSC);
// ADCSRA &= ~(1<<ADIF);
}
// v = v/2;
}
uchar get_key_value(void)
{
get_adc_value(ADC_KEY);
if (v < 1000)
{
return 0;
}
else
{
if ((v > 3000)&&(v < 3500))
{
return 1;
}
else
{
if ((v > 2000)&&(v < 2800))
{
return 2;
}
else
{
if ((v > 1000)&&(v < 1900))
{
return 3;
}
else
{
return 0;
}
}
}
}
}
void temp_setting(void)
{
uchar key;
key = get_key_value();
if(key==2)
{
adc_channel++;
if (adc_channel>3)
{
adc_channel = 0;
}
}
if(key==3)
{
if (adc_channel==0)
{
adc_channel = 1;
auto_mode = ~auto_mode;
}
adc_channel--;
}
while(1) // 查鰎盤是否放開
{
get_adc_value(ADC_KEY);
if(v < 500)
{
break;
};
};
if (key==1) setting_mode = 1;
while(setting_mode==1)
{
key = get_key_value();
if(key==1)
{
adc_channel++;
if (adc_channel>3)
{
adc_channel = 0;
setting_mode = 0;
EEPROMwrite(0x01, hot_warning[0]);
delay_nms(5);
EEPROMwrite(0x02, hot_warning[1]);
delay_nms(5);
EEPROMwrite(0x03, hot_warning[2]);
delay_nms(5);
EEPROMwrite(0x04, hot_warning[3]);
delay_nms(5);
}
}
else
{
if(key==2)
{
++hot_warning[adc_channel];
}
else
{
if(key==3) --hot_warning[adc_channel];
};
};
while(1)
{
get_adc_value(ADC_KEY);
if(v < 500)
{
break;
};
};
disp_led(hot_warning[adc_channel]);
}
}
uint get_degree(void)
{
uchar x,y;
uint v_big,v_small,v_step;
if (v<100) return 0x83E7; // 當沒有信號時顯示-99.9錯誤
for (x=0;x<115;x++) // 查表
{
if (v_table[x] >= v) // 找出電壓區域
{
v_big = v_table[x]; // 區域 高段
v_small = v_table[x-1]; //區域 低段
v_step = (v_big - v_small)/10; // 把區域細分成10份
for (y=0;y<10;y++) // 細分比較
{
v_small += v_step;
if (v < v_small) // 得出結果
{
v = x*10+y;// 其中x*10 為整數部分, y 為小數部分
if (x<10) // 少於10時為負溫度
{
v |= 0x8000; // 加入負號標記
}
else
{
v -= 100; // 0 度修正
}
return v;
};
};
};
WDR();
}
return v;
}
void init_port(void)
{
CLKPR = 0x80;
CLKPR = 0x00;
DDRB = 0xff;
PORTB = 0xff;
DDRC = 0x00;
PORTC = 0x00;
DDRD = 0xff;
PORTD = 0xff;
CLI();
ADMUX = (1<<REFS0);
ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
SEI();
WDR(); // 使用看門狗
//WDTCR = 0x0F;
WDTCSR = 0x0F;
}
//**********************************************8
#pragma interrupt_handler timer1_ovf_isr:14 //iv_TIMER1_OVF
void timer1_ovf_isr(void)
{
TCNT1=toneconst;
PORTD^=SOUND_OUT;
}
void music(void)
{
uchar temp,temp1;
uint sound_add=0;
TCCR1A = 0x00;
TCCR1B =(1<<CS11);//8分頻
temp1 = sound[sound_add];
while(temp1!=0)
{
temp=temp1;
temp&=0x0f;
if(temp!=0)
{
TIMSK1|=(1<<TOIE1);//根据SOUNDTABLE中數据的低四位產生音樂頻率
temp--;
toneconst=TONETABLE[temp];
TCNT1=toneconst;
}
temp=temp1;
temp>>=4;
temp&=0x0f;
delay_nms(temp*129);//根据SOUNDTABLE中數据的高四位,控制音樂頻率持續時間
TIMSK1&=~(1<<TOIE1);
sound_add++;
temp1 = sound[sound_add];
}
delay_nms(1000);
}
//****************************************************
void main(void)
{
uchar j;
init_port();
hot_warning[0] = EEPROMread(0x01);
hot_warning[1] = EEPROMread(0x02);
hot_warning[2] = EEPROMread(0x03);
hot_warning[3] = EEPROMread(0x04);
while(1)
{
for(j=0;j<4;j++)
{
temp_setting(); // 設定
get_adc_value(adc_channel); // 進行adc取樣
get_degree(); // get_degree()的功能是把adc的值進行查表取數
if(v/10 > hot_warning[adc_channel]) // 檢查溫度是否超過上限
{
//disp_led(0x83E7);
music();
}
else
{
disp_led(v); // 顯示數據,v由get_degree()中產生
}
WDR();
}
if (auto_mode==0xff) // 自動模式
{
adc_channel++;
if (adc_channel>3) adc_channel=0;
}
}
} |
|