main.c 14 KB

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