main.c 12 KB

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