main.c 13 KB

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