main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. #include "main.h"
  2. #ifdef __ICCAVR__
  3. __C_task
  4. #endif
  5. void main(void)
  6. {
  7. /* Disable comaparator */
  8. ACSR = 1<<ACD;
  9. /* Init LED */
  10. LED_DDR = LED_1 | LED_2;
  11. LED_OFF(LED_1);
  12. LED_OFF(LED_2);
  13. /* Init 7 segment LED indicators */
  14. INDCTR_SEGMENT_DDR = 0xFF; // segment pins to output
  15. INDCTR_SEGMENT_PORT = 0x00; // off all segment
  16. INDCTR_COMMON_DDR = INDCTR_COMMON_ALL; // common pins to output
  17. INDCTR_COMMON_PORT = ~INDCTR_COMMON_ALL; // off all indikators
  18. Flag2.needDot = 0;
  19. /* Timer0 every 4 ms switch showing LED */
  20. TCCR0 = TIM0_PRESCALER;
  21. TCNT0 = TIM0_CNT; // load timer
  22. TIMSK |= 1<<TOIE0; // enable TIM0_OVF interrupt
  23. /* Timer1 ticks with 1 MHz frequency for DS18B20 delays */
  24. TCCR1B = TIM1_PRESCALER;
  25. // TCNT1 = 64536;
  26. // TIMSK |= 1<<TOIE1; // enable TIM1_OVF interrupt
  27. /* Timer2 count 1 ms */
  28. TCCR2 = TIM2_PRESCALER;
  29. TCNT2 = TIM2_CNT; // load timer
  30. TIMSK |= 1<<TOV2; // enable TIM2_OVF interrupt
  31. /* ADC init */
  32. resultADC = 0;
  33. ADMUX = (1<<REFS0) | (1<<ADLAR); // Vref = AVcc, channel ADC0, Left adjusted result
  34. ADCSR = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1; // enable ADC, prescaler = 64
  35. /* I2C init */
  36. TWI_MasterInit(100);
  37. sei();
  38. // Start tasks
  39. counterADC = PERIOD_ADC; // every 50 ms start ADC measure
  40. counterTWI = 4; // small delay
  41. counterDS18B20s = 12; // small delay
  42. State = show_HHMM;
  43. while(1) {
  44. /* check time */
  45. if (1 == Flag.getTime) {
  46. Flag.getTime = 0;
  47. getTime();
  48. } // end of Flag.getTime
  49. if (1 == Flag.newTime) {
  50. Flag.newTime = 0;
  51. switch (State) {
  52. case show_HHMM:
  53. // every 25 and 55 seconds shoe temperature for 5 seconds
  54. if ((25 == Clock.seconds) || (55 == Clock.seconds)) {
  55. State = show_TEMPt;
  56. counterShowTemp = PERIOD_SHT;
  57. showTEMP();
  58. } else {
  59. showHHMM();
  60. }
  61. break;
  62. case show_MMSS:
  63. showMMSS();
  64. break;
  65. default:
  66. break;
  67. }
  68. } // end of Flag.newTime
  69. /* Temperature */
  70. if (1 == Flag.startDS18B20) {
  71. Flag.startDS18B20 = 0;
  72. ds18b20_StartMeasure();
  73. }
  74. if (1 == Flag.readDS18B20) {
  75. Flag.readDS18B20 = 0;
  76. ds18b20_ReadTemperature();
  77. }
  78. if (1 == Flag.newTemp) {
  79. Flag.newTemp = 0;
  80. if ((show_TEMPt == State) || (show_TEMPp == State)) {
  81. showTEMP();
  82. }
  83. } // end of Flag.newTemp
  84. /* check buttons */
  85. if (1 == Flag.newBTN) {
  86. Flag.newBTN = 0;
  87. uint8_t mm, hh;
  88. btn_t btn = getBTN();
  89. switch (btn) {
  90. case btn_1:
  91. // show HH:MM
  92. State = show_HHMM;
  93. counterShowTemp = 0;
  94. showHHMM();
  95. break;
  96. case btn_2:
  97. // show MM SS
  98. State = show_MMSS;
  99. Flag2.needDot = 1;
  100. counterShowTemp = 0;
  101. showMMSS();
  102. break;
  103. case btn_3:
  104. // show temperature
  105. State = show_TEMPp;
  106. Flag2.needDot = 0;
  107. counterShowTemp = 0;
  108. showTEMP();
  109. break;
  110. case btn_4:
  111. // time --
  112. if (Flag.setTime == 1) {
  113. mm = bcd2bin(Clock.minutes);
  114. hh = bcd2bin(Clock.hours);
  115. if (mm > 0) {
  116. mm --;
  117. } else {
  118. mm = 59;
  119. if (hh > 0) {
  120. hh --;
  121. } else {
  122. hh = 23;
  123. }
  124. }
  125. Clock.minutes = bin2bcd(mm);
  126. Clock.hours = bin2bcd(hh);
  127. }
  128. break;
  129. case btn_5:
  130. // time ++
  131. if (Flag.setTime == 1) {
  132. mm = bcd2bin(Clock.minutes);
  133. hh = bcd2bin(Clock.hours);
  134. mm ++;
  135. if (mm > 59) {
  136. mm = 0;
  137. hh ++;
  138. if (hh > 23) {
  139. hh = 0;
  140. }
  141. }
  142. Clock.minutes = bin2bcd(mm);
  143. Clock.hours = bin2bcd(hh);
  144. }
  145. break;
  146. case btn_6:
  147. // save new time
  148. if (Flag.setTime == 1) {
  149. Flag.setTime = 0;
  150. Flag2.blankIndktr = 0;
  151. setTime();
  152. counterTWI = PERIOD_TWI;
  153. }
  154. break;
  155. case btn_7:
  156. // time set
  157. Flag.setTime = 1;
  158. Flag2.blankIndktr = 1;
  159. counterTWI = 0;
  160. break;
  161. default:
  162. break;
  163. }
  164. } // end of new BTN
  165. // делать нехрен -- спим, ждём прерывание
  166. MCUCR = 1<<SE;
  167. sleep_mode();
  168. } // end of while(1)
  169. } // end of main()
  170. /**
  171. * S u b r o u t i n e s
  172. */
  173. static uint8_t bcd2bin(uint8_t bcd) {
  174. return (10*(bcd>>4)|(bcd&0x0f));
  175. }
  176. static uint8_t bin2bcd(uint8_t bin) {
  177. return (((bin/10)<<4)|(bin%10));
  178. }
  179. static void showHHMM(void) {
  180. State = show_HHMM;
  181. Indicator1 = IndctrNums[(0x0F & (Clock.hours>>4))];
  182. Indicator2 = IndctrNums[(0x0F & Clock.hours)];
  183. Indicator3 = IndctrNums[(0x0F & (Clock.minutes>>4))];
  184. Indicator4 = IndctrNums[(0x0F & Clock.minutes)];
  185. }
  186. static void showMMSS(void) {
  187. Indicator1 = IndctrNums[(0x0F & (Clock.minutes>>4))];
  188. Indicator2 = IndctrNums[(0x0F & Clock.minutes)];
  189. Indicator3 = IndctrNums[(0x0F & (Clock.seconds>>4))];
  190. Indicator4 = IndctrNums[(0x0F & Clock.seconds)];
  191. }
  192. static void showTEMP(void) {
  193. int8_t t = Temperature;
  194. if (t < 0) {
  195. Indicator1 = Sym_minus;
  196. t = -t;
  197. } else {
  198. Indicator1 = Sym_blank;
  199. }
  200. // convert to BCD
  201. t = bin2bcd(t);
  202. Indicator2 = IndctrNums[(0x0F & (t>>4))];
  203. Indicator3 = IndctrNums[(0x0F & t)];
  204. Indicator4 = Sym_gradus;
  205. Flag2.needDot = 0;
  206. }
  207. static btn_t getBTN(void) {
  208. uint8_t btn_code = resultADC;
  209. if (btn_code > 0xED) {
  210. return btn_no;
  211. } else if (btn_code > 0xD8) {
  212. return btn_1;
  213. } else if (btn_code > 0xD0) {
  214. return btn_2;
  215. } else if (btn_code > 0xC5) {
  216. return btn_3;
  217. } else if (btn_code > 0xB4) {
  218. return btn_4;
  219. } else if (btn_code > 0x94) {
  220. return btn_5;
  221. } else if (btn_code > 0x3F) {
  222. return btn_6;
  223. } else {
  224. return btn_7;
  225. }
  226. }
  227. static void getTime(void) {
  228. static uint8_t old_sec;
  229. /* Sync with indicators */
  230. Flag2.waitIndktr = 1;
  231. while (Flag2.waitIndktr == 1);
  232. /*устанавливаем указатель DS1307 на нулевой адрес*/
  233. twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
  234. twi_buf[1] = 0; //адрес регистра
  235. TWI_SendData(twi_buf, 2);
  236. /*считываем время с DS1307*/
  237. twi_buf[0] = (DS1307_ADR<<1)|1;
  238. TWI_SendData(twi_buf, 5);
  239. /*переписываем данные буфера драйвера в свой буфер*/
  240. TWI_GetData(twi_buf, 5);
  241. Clock.seconds = twi_buf[1];
  242. Clock.minutes = twi_buf[2];
  243. Clock.hours = twi_buf[3];
  244. if (show_HHMM == State) {
  245. if (old_sec != Clock.seconds) {
  246. Flag2.needDot = 1;
  247. } else {
  248. Flag2.needDot = 0;
  249. }
  250. }
  251. old_sec = Clock.seconds;
  252. Flag.newTime = 1;
  253. }
  254. static void setTime(void) {
  255. /* Sync with indicators */
  256. Flag2.waitIndktr = 1;
  257. while (Flag2.waitIndktr == 1);
  258. /* prepare new time */
  259. twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
  260. twi_buf[1] = 0; //адрес регистра
  261. twi_buf[2] = 0; //значение секунд
  262. twi_buf[3] = Clock.minutes; //значение минут
  263. twi_buf[4] = Clock.hours; //значение часов
  264. /* senr to rtc */
  265. TWI_SendData(twi_buf, 5);
  266. }
  267. /* DS18B20 functions */
  268. static uint8_t ds18b20_Reset(void) {
  269. uint8_t i;
  270. /* Pull line low and wait for 480uS */
  271. DS18B20_LOW;
  272. DS18B20_OUTPUT_MODE;
  273. //ds18b20_delay(us(480));
  274. TCNT1 = 0;
  275. while (TCNT1 <= 480) {
  276. }
  277. /* Release line and wait for 60uS */
  278. DS18B20_INPUT_MODE;
  279. //ds18b20_delay(us(60));
  280. TCNT1 = 0;
  281. while (TCNT1 <= 60) {
  282. }
  283. /* Store line value and wait until the completion of 480uS period */
  284. i = DS18B20_VALUE;
  285. //ds18b20_delay(us(420));
  286. //OCR1B = 420;
  287. TCNT1 = 0;
  288. while (TCNT1 <= 420) {
  289. }
  290. /* Return the value read from the presence pulse (0=OK, else=WRONG) */
  291. return i;
  292. }
  293. static void ds18b20_WriteBit(uint8_t bit) {
  294. /* Pull line low for 1uS */
  295. DS18B20_LOW;
  296. DS18B20_OUTPUT_MODE;
  297. //ds18b20_delay(us(1));
  298. TCNT1 = 0;
  299. while (TCNT1 <= 1);
  300. /* If we want to write 1, release the line (if not will keep low) */
  301. if(1 == bit) {
  302. DS18B20_INPUT_MODE;
  303. }
  304. /* Wait for 60uS and release the line */
  305. //ds18b20_delay(us(60));
  306. TCNT1 = 0;
  307. while (TCNT1 <= 60) {
  308. }
  309. DS18B20_INPUT_MODE;
  310. }
  311. static uint8_t ds18b20_ReadBit(void) {
  312. uint8_t bit=0;
  313. /* Pull line low for 1uS */
  314. DS18B20_LOW;
  315. DS18B20_OUTPUT_MODE;
  316. //ds18b20_delay(us(1));
  317. TCNT1 = 0;
  318. while (TCNT1 <= 1);
  319. /* Release line and wait for 14uS */
  320. DS18B20_INPUT_MODE;
  321. //ds18b20_delay(us(14));
  322. TCNT1 = 0;
  323. while (TCNT1 <= 14) {
  324. }
  325. /* Read line value */
  326. if (DS18B20_VALUE != 0) {
  327. bit = 0x80;
  328. }
  329. /* Wait for 45uS to end and return read value */
  330. //ds18b20_delay(us(45));
  331. TCNT1 = 0;
  332. while (TCNT1 <= 45) {
  333. }
  334. return bit;
  335. }
  336. static uint8_t ds18b20_ReadByte(void) {
  337. uint8_t i=8, n=0;
  338. while (i--) {
  339. /* Shift one position right and store read value */
  340. n >>= 1;
  341. n |= ds18b20_ReadBit();
  342. }
  343. return n;
  344. }
  345. static void ds18b20_WriteByte(uint8_t byte) {
  346. uint8_t i=8;
  347. while (i--) {
  348. /* Write actual bit and shift one position right to make the next bit ready */
  349. ds18b20_WriteBit(byte & 0x01);
  350. byte >>= 1;
  351. }
  352. }
  353. static void ds18b20_StartMeasure(void) {
  354. /* Sync with indicators */
  355. Flag2.waitIndktr = 1;
  356. while (Flag2.waitIndktr == 1);
  357. /* Reset, skip ROM and start temperature conversion */
  358. if (ds18b20_Reset() != 0) {
  359. Temperature = -99;
  360. Flag.newTemp = 1;
  361. } else {
  362. ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
  363. ds18b20_WriteByte(DS18B20_CMD_CONVERTTEMP);
  364. counterDS18B20r = PERIOD_DS18B20r;
  365. }
  366. }
  367. static void ds18b20_ReadTemperature(void) {
  368. uint8_t temperature[2];
  369. uint8_t decimal;
  370. /* Sync with indicators */
  371. Flag2.waitIndktr = 1;
  372. while (Flag2.waitIndktr == 1);
  373. /* Reset, skip ROM and send command to read Scratchpad */
  374. if (ds18b20_Reset() != 0) {
  375. Temperature = -98;
  376. } else {
  377. ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
  378. ds18b20_WriteByte(DS18B20_CMD_RSCRATCHPAD);
  379. /* Read Scratchpad (only 2 first bytes) */
  380. temperature[0]=ds18b20_ReadByte();
  381. temperature[1]=ds18b20_ReadByte();
  382. //ds18b20_reset();
  383. /* Store temperature integer digits */
  384. Temperature = ((temperature[1]&0x7)<<4) | (temperature[0]>>4);
  385. // get decimal part
  386. decimal = (temperature[0] & 15);
  387. // convert to binary
  388. //decimal *= 10; //(tempDecimals << 1) + (tempDecimals << 3);// Умножаем на 10
  389. //decimal >>= 4; //(tempDecimals >> 4);//делим на 16 или умножаем на 0.0625
  390. // round integer part
  391. if (decimal > 7) {
  392. Temperature ++;
  393. }
  394. }
  395. Flag.newTemp = 1;
  396. }
  397. /**
  398. * I n t e r r u p t h a n d l e r s
  399. */
  400. #ifdef __ICCAVR__
  401. #pragma vector=TIMER0_OVF_vect
  402. __interrupt void TIMER0_OVF_ISR(void)
  403. #else // __GNUC__
  404. ISR (TIMER0_OVF_vect)
  405. #endif
  406. {
  407. static uint8_t indicator = 0;
  408. static uint8_t blank_time = 0; // blanking timer
  409. uint8_t flag = 1;
  410. TCNT0 = TIM0_CNT; // reload timer
  411. INDCTR_COMMON_PORT &= ~INDCTR_COMMON_ALL; // off all indikators
  412. Flag2.waitIndktr = 0;
  413. if (1 == Flag2.blankIndktr) {
  414. if (blank_time <= 150) {
  415. flag = 1;
  416. blank_time ++;
  417. } else if (blank_time <= 250) {
  418. blank_time ++;
  419. flag = 0;
  420. } else {
  421. blank_time = 0;
  422. flag = 1;
  423. }
  424. }
  425. if (1 == flag) {
  426. switch (indicator) {
  427. case 0:
  428. INDCTR_SEGMENT_PORT = Indicator1;
  429. INDCTR_COMMON_PORT |= 0x01;
  430. indicator = 1;
  431. break;
  432. case 1:
  433. if (1 == Flag2.needDot) {
  434. INDCTR_SEGMENT_PORT = Indicator2 | Sym_dot;
  435. } else {
  436. INDCTR_SEGMENT_PORT = Indicator2;
  437. }
  438. INDCTR_COMMON_PORT |= 0x02;
  439. indicator = 2;
  440. break;
  441. case 2:
  442. INDCTR_SEGMENT_PORT = Indicator3;
  443. INDCTR_COMMON_PORT |= 0x04;
  444. indicator = 3;
  445. break;
  446. case 3:
  447. INDCTR_SEGMENT_PORT = Indicator4;
  448. INDCTR_COMMON_PORT |= 0x08;
  449. default:
  450. indicator = 0;
  451. break;
  452. } // end of switch
  453. }
  454. }
  455. #ifdef __ICCAVR__
  456. #pragma vector=TIMER1_COMPA_vect
  457. __interrupt void TIMER1_COMPA_ISR(void) {
  458. }
  459. #pragma vector=TIMER1_COMPB_vect
  460. __interrupt void TIMER1_COMPB_ISR(void) {
  461. }
  462. #pragma vector=TIMER1_OVF_vect
  463. __interrupt void TIMER1_OVF_ISR(void) {
  464. // Flag.T1OC = 1;
  465. }
  466. #endif
  467. #ifdef __ICCAVR__
  468. #pragma vector=TIMER2_OVF_vect
  469. __interrupt void TIMER2_OVF_ISR(void)
  470. #else // __GNUC__
  471. ISR (TIMER2_OVF_vect)
  472. #endif
  473. {
  474. TCNT2 = TIM2_CNT; // reload timer
  475. if (counterADC > 0) {
  476. counterADC --;
  477. if (counterADC == 0) {
  478. counterADC = PERIOD_ADC;
  479. // enable interrupt and start conversion
  480. ADCSR |= ((1<<ADSC) | (1<<ADIE));
  481. }
  482. }
  483. if (counterTWI > 0) {
  484. counterTWI --;
  485. if (counterTWI == 0) {
  486. counterTWI = PERIOD_TWI;
  487. Flag.getTime = 1;
  488. }
  489. }
  490. if (counterShowTemp > 0) {
  491. counterShowTemp --;
  492. if (counterShowTemp == 0) {
  493. State = show_HHMM;
  494. }
  495. }
  496. if (counterDS18B20s > 0) {
  497. counterDS18B20s --;
  498. if (counterDS18B20s == 0) {
  499. counterDS18B20s = PERIOD_DS18B20s;
  500. Flag.startDS18B20 = 1;
  501. }
  502. }
  503. if (counterDS18B20r > 0) {
  504. counterDS18B20r --;
  505. if (counterDS18B20r == 0) {
  506. Flag.readDS18B20 = 1;
  507. }
  508. }
  509. }
  510. #ifdef __ICCAVR__
  511. #pragma vector=ADC_vect
  512. __interrupt void ADC_ISR(void)
  513. #else // __GNUC__
  514. ISR (ADC_vect)
  515. #endif
  516. {
  517. resultADC = ADCH;
  518. ADCSR &= ~(1<<ADIE); // disable interrupt
  519. Flag.newBTN = 1;
  520. }