找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

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

[复制链接]
慧龙 发表于 2010-5-15 00:10:11 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
電路圖:
cd1753d2eabd8df51bdf91303c02c61a.jpg


  1. // icc 6.31a , atmage48, 8m osc
  2. #include <iom48v.h>
  3. #include <macros.h>
  4. #include <stdio.h>
  5. #include <eeprom.h>

  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. #define LED_NUM    PORTD
  9. #define LED_VALUE  PORTB
  10. #define ADC_KEY    5
  11. #define SOUND_OUT  0x04
  12. #define DELAY_MIN  1100

  13. uint v = 0;
  14. uchar adc_channel = 0;
  15. uchar hot_warning[4]={30,35,40,45};
  16. uchar setting_mode = 0;
  17. uchar auto_mode = 0x00;

  18. const uchar disp_table[22] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  19. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x01,0x02,0x04,0x08,0x10};

  20. // 溫度表 -10 度到 105 度
  21. const uint v_table[116]={
  22. 895,932,969,1006,1045,1085,1125,1166,1208,1250, //-10 ----  -1
  23. 1294,1338,1382,1427,1473,1519,1566,1614,1661,1709,//0 ----  9
  24. 1758,1807,1856,1905,1955,2004,2054,2104,2154,2204,//10 ----  19
  25. 2253,2303,2353,2402,2451,2500,2549,2597,2645,2692,//20 ----  29
  26. 2740,2786,2832,2878,2923,2968,3012,3056,3099,3141,//30 ----  39
  27. 3183,3224,3265,3304,3344,3382,3420,3457,3493,3529,//40 ----  49
  28. 3564,3599,3632,3665,3698,3729,3760,3791,3820,3849,//50 ----  59
  29. 3878,3905,3932,3959,3985,4010,4034,4058,4082,4105,//60 ----  69
  30. 4127,4149,4170,4191,4211,4231,4250,4269,4287,4304,//70 ----  79
  31. 4322,4339,4355,4371,4387,4402,4417,4431,4445,4459,//80 ----  89
  32. 4472,4485,4497,4510,4522,4533,4545,4556,4566,4577,//90 ----  99
  33. 4587,4597,4607,4616,4625,4634};//100 ----  105


  34. const uchar sound[]={ //樂曲數据表
  35. 0x45,0x48,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x49,0x4a,
  36. 0x49,0x48,0x48,0x48,0x48,0x48,0x45,0x48,0x4a,0x4a,
  37. 0x48,0x4a,0x4c,0x4c,0x4b,0x4a,0x49,0x49,0x49,0x49,
  38. 0x49,0x4c,0x4b,0x4a,0x4a,0x4a,0x49,0x48,0x48,0x49,
  39. 0x4a,0x4c,0x4b,0x4b,0x4b,0x4b,0x4b,0x46,0x46,0x45,
  40. 0x45,0x45,0x47,0x48,0x49,0x49,0x4a,0x49,0x48,0x48,
  41. 0x48,0x48,0x48,0x48,

  42. 0x00,0x00
  43. };

  44. const uint TONETABLE[15]={ //音調頻率數据表
  45. 64580,64684,64777,64820,64898,64968,65030,65058,
  46. 65110,65157,65178,65217,65252,65283,65297
  47. };

  48. uint toneconst;

  49. void delay_1ms(void)
  50. {
  51. uint i;
  52. for (i=0;i<DELAY_MIN;i++);
  53. WDR();
  54. }

  55. void delay_nms(uint n)
  56. {
  57. uint i;
  58. for (i=0;i<n;i++)
  59. delay_1ms();
  60. }

  61. void disp_led(uint value)
  62. {
  63. uchar i,j;
  64.   uchar led_data[5];

  65. led_data[0] = adc_channel+17;

  66. if ((value & 0x8000)==0x8000)
  67. {
  68. value &= 0x7fff;
  69. led_data[4] = 16; // 顯示負號
  70. }
  71. else
  72. {
  73. value &= 0x7fff;
  74. led_data[4] = value/1000;
  75. };

  76. led_data[3] = value/100%10;
  77. led_data[2] = value/10%10;
  78. led_data[1] = value%10;

  79. for (j=0;j<20;j++)
  80. {
  81. for (i=0;i<5;i++)
  82. {
  83. LED_VALUE = disp_table[led_data[i]];
  84. if(i==2)
  85. {
  86. LED_VALUE |= 0x80; // 加上小數點
  87. }
  88. LED_NUM = ~BIT(i+3);
  89. delay_nms(5);
  90. LED_NUM = 0xff;
  91. };
  92. };
  93. }

  94. #pragma interrupt_handler adc_isr:iv_ADC
  95. void adc_isr(void)
  96. {   
  97.     uint temp;
  98. temp = ADCL;
  99. temp |= (int)ADCH<<8;
  100. temp = (49*temp)/10;
  101. v += temp;
  102. }

  103. void get_adc_value(uchar adc_pin)
  104. {   
  105.     uchar i;
  106. v = 0x0000;
  107. ADMUX = (1<<REFS0)|adc_pin;
  108. // for(i=0;i<2;i++)
  109. {
  110. // ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
  111. ADCSRA |= (1<<ADSC);
  112. delay_nms(1);
  113. //  while((ADCSRA & (1<<ADIF))==0);  
  114. ADCSRA &= ~(1<<ADSC);
  115. // ADCSRA &= ~(1<<ADIF);   
  116.     }
  117. // v = v/2;
  118. }

  119. uchar get_key_value(void)
  120. {
  121. get_adc_value(ADC_KEY);
  122. if (v < 1000)
  123. {
  124. return 0;
  125. }
  126. else
  127. {
  128. if ((v > 3000)&&(v < 3500))
  129. {
  130. return 1;
  131. }
  132. else
  133. {
  134. if ((v > 2000)&&(v < 2800))
  135. {
  136. return 2;
  137. }
  138. else
  139. {
  140. if ((v > 1000)&&(v < 1900))
  141. {
  142. return 3;
  143. }
  144. else
  145. {
  146. return 0;
  147. }
  148. }
  149. }
  150. }
  151. }

  152. void temp_setting(void)
  153. {
  154. uchar key;
  155. key = get_key_value();

  156. if(key==2)
  157. {
  158. adc_channel++;
  159. if (adc_channel>3)
  160. {
  161. adc_channel = 0;
  162. }
  163. }

  164. if(key==3)
  165. {
  166. if (adc_channel==0)
  167. {
  168. adc_channel = 1;
  169. auto_mode = ~auto_mode;
  170. }
  171. adc_channel--;
  172. }

  173. while(1) // 查鰎盤是否放開
  174. {
  175. get_adc_value(ADC_KEY);
  176. if(v < 500)
  177. {
  178. break;
  179. };
  180. };

  181. if (key==1) setting_mode = 1;

  182. while(setting_mode==1)
  183. {
  184. key = get_key_value();
  185. if(key==1)
  186. {
  187. adc_channel++;
  188. if (adc_channel>3)
  189. {
  190. adc_channel = 0;
  191. setting_mode = 0;
  192. EEPROMwrite(0x01, hot_warning[0]);
  193. delay_nms(5);
  194. EEPROMwrite(0x02, hot_warning[1]);
  195. delay_nms(5);
  196. EEPROMwrite(0x03, hot_warning[2]);
  197. delay_nms(5);
  198. EEPROMwrite(0x04, hot_warning[3]);
  199. delay_nms(5);
  200. }
  201. }
  202. else
  203. {
  204. if(key==2)
  205. {
  206. ++hot_warning[adc_channel];
  207. }
  208. else
  209. {
  210. if(key==3) --hot_warning[adc_channel];
  211. };
  212. };

  213. while(1)
  214. {
  215. get_adc_value(ADC_KEY);
  216. if(v < 500)
  217. {
  218. break;
  219. };
  220. };

  221. disp_led(hot_warning[adc_channel]);
  222. }

  223. }

  224. uint get_degree(void)
  225. {
  226. uchar x,y;
  227. uint v_big,v_small,v_step;

  228. if (v<100) return 0x83E7; // 當沒有信號時顯示-99.9錯誤

  229. for (x=0;x<115;x++) // 查表
  230. {
  231. if (v_table[x] >= v) // 找出電壓區域
  232. {
  233. v_big = v_table[x]; // 區域 高段
  234. v_small = v_table[x-1]; //區域 低段
  235. v_step = (v_big - v_small)/10; // 把區域細分成10份
  236. for (y=0;y<10;y++) // 細分比較
  237. {
  238. v_small += v_step;
  239. if (v < v_small) // 得出結果
  240. {
  241. v = x*10+y;// 其中x*10 為整數部分, y 為小數部分
  242. if (x<10) // 少於10時為負溫度
  243. {
  244. v |= 0x8000; // 加入負號標記
  245. }
  246. else
  247. {
  248. v -= 100; // 0 度修正
  249. }
  250.         return v;   
  251. };
  252. };
  253. };
  254. WDR();
  255. }   
  256.   return v;  
  257. }

  258. void init_port(void)
  259. {
  260.   CLKPR = 0x80;
  261.   CLKPR = 0x00;
  262. DDRB = 0xff;
  263. PORTB = 0xff;
  264. DDRC = 0x00;
  265. PORTC = 0x00;
  266. DDRD = 0xff;
  267. PORTD = 0xff;
  268. CLI();
  269. ADMUX = (1<<REFS0);
  270. ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
  271. SEI();
  272. WDR(); // 使用看門狗
  273. //WDTCR = 0x0F;
  274.     WDTCSR = 0x0F;
  275. }

  276. //**********************************************8
  277. #pragma interrupt_handler timer1_ovf_isr:14 //iv_TIMER1_OVF
  278. void timer1_ovf_isr(void)
  279. {
  280. TCNT1=toneconst;
  281. PORTD^=SOUND_OUT;
  282. }

  283. void music(void)
  284. {
  285. uchar temp,temp1;
  286. uint sound_add=0;

  287. TCCR1A = 0x00;
  288. TCCR1B =(1<<CS11);//8分頻
  289. temp1 = sound[sound_add];
  290. while(temp1!=0)
  291. {
  292. temp=temp1;
  293. temp&=0x0f;
  294. if(temp!=0)
  295. {
  296. TIMSK1|=(1<<TOIE1);//根据SOUNDTABLE中數据的低四位產生音樂頻率
  297. temp--;
  298. toneconst=TONETABLE[temp];
  299. TCNT1=toneconst;
  300. }
  301. temp=temp1;
  302. temp>>=4;
  303. temp&=0x0f;
  304. delay_nms(temp*129);//根据SOUNDTABLE中數据的高四位,控制音樂頻率持續時間
  305. TIMSK1&=~(1<<TOIE1);
  306. sound_add++;
  307. temp1 = sound[sound_add];
  308. }
  309. delay_nms(1000);
  310. }
  311. //****************************************************

  312. void main(void)
  313. {
  314. uchar j;
  315. init_port();
  316. hot_warning[0] = EEPROMread(0x01);
  317. hot_warning[1] = EEPROMread(0x02);
  318. hot_warning[2] = EEPROMread(0x03);
  319. hot_warning[3] = EEPROMread(0x04);
  320. while(1)
  321. {
  322. for(j=0;j<4;j++)
  323. {
  324. temp_setting(); // 設定
  325. get_adc_value(adc_channel); // 進行adc取樣
  326. get_degree(); // get_degree()的功能是把adc的值進行查表取數
  327. if(v/10 > hot_warning[adc_channel]) // 檢查溫度是否超過上限
  328. {
  329. //disp_led(0x83E7);
  330. music();
  331. }
  332. else
  333. {
  334. disp_led(v); // 顯示數據,v由get_degree()中產生
  335. }
  336. WDR();
  337. }

  338. if (auto_mode==0xff) // 自動模式
  339. {
  340. adc_channel++;
  341. if (adc_channel>3) adc_channel=0;
  342. }
  343. }

  344. }


复制代码
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-12-23 13:09 , Processed in 0.065958 second(s), 11 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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