hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 361|回复: 0

低成本m48+熱敏電阻做的多路溫度顯示及音樂警報裝置

[复制链接]

256

主题

429

帖子

951

积分

中郎将

Rank: 4

积分
951
发表于 2024-4-13 20:05:16 | 显示全部楼层 |阅读模式
電路圖:

  1. // icc 6.31a , atmage48, 8m osc #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+17; 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[i]]; 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; } } }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-2 00:06 , Processed in 0.058108 second(s), 22 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

快速回复 返回顶部 返回列表