main.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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. /* ADC init */
  28. resultADC = 0;
  29. ADMUX = (1<<REFS0) | (1<<ADLAR); // Vref = AVcc, channel ADC0, Left adjusted result
  30. ADCSR = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1; // enable ADC, prescaler = 64
  31. /* I2C init */
  32. TWI_MasterInit(100);
  33. __enable_interrupt();
  34. /* Init Scheduler and TDelay */
  35. RTOS_Init();
  36. // Tasks for sheduler
  37. RTOS_SetTask(startADC,0,50);
  38. RTOS_SetTask(getTime,4,500);
  39. RTOS_SetTask(ds18b20_StartMeasure,8,10000);
  40. /* Get time */
  41. while(1) {
  42. /*
  43. if (1 == Flag.newTime) {
  44. Flag.newTime = 0;
  45. Display[0] = IndctrNums[(0x0F & (Clock.hours>>4))];
  46. Display[1] = IndctrNums[(0x0F & Clock.hours)];
  47. Display[2] = IndctrNums[(0x0F & (Clock.minutes>>4))];
  48. Display[3] = IndctrNums[(0x0F & Clock.minutes)];
  49. }
  50. */
  51. if (1 == Flag.newTemp) {
  52. Flag.newTemp = 0;
  53. if (Temperature < 0) {
  54. Display[0] = Sym_minus;
  55. } else {
  56. Display[0] = Sym_blank;
  57. }
  58. Display[1] = IndctrNums[(0x0F & (Temperature>>4))];
  59. Display[2] = IndctrNums[(0x0F & Temperature)];
  60. Display[3] = Sym_gradus;
  61. }
  62. if (1 == Flag.newBTN) {
  63. Flag.newBTN = 0;
  64. btn_t btn = getBTN();
  65. if (btn == btn_1) {
  66. LED_ON(LED_1);
  67. } else if (btn == btn_2) {
  68. LED_ON(LED_2);
  69. } else if (btn == btn_3) {
  70. LED_OFF(LED_1);
  71. } else if (btn == btn_4) {
  72. LED_OFF(LED_2);
  73. } else if (btn == btn_5) {
  74. LED_ON(LED_1);
  75. LED_ON(LED_2);
  76. } else if (btn == btn_6) {
  77. LED_OFF(LED_1);
  78. LED_OFF(LED_2);
  79. }
  80. }
  81. tdelay_ms(10); // sleep and rotate dispatcher
  82. } // end of while(1)
  83. } // end of main()
  84. /**
  85. * S u b r o u t i n e s
  86. */
  87. static void startADC(void) {
  88. // enable interrupt and start conversion
  89. ADCSR |= ((1<<ADSC) | (1<<ADIE));
  90. }
  91. static btn_t getBTN(void) {
  92. uint8_t btn_code = resultADC;
  93. if (btn_code > 0xED) {
  94. return btn_no;
  95. } else if (btn_code > 0xD8) {
  96. return btn_1;
  97. } else if (btn_code > 0xD0) {
  98. return btn_2;
  99. } else if (btn_code > 0xC5) {
  100. return btn_3;
  101. } else if (btn_code > 0xB4) {
  102. return btn_4;
  103. } else if (btn_code > 0x94) {
  104. return btn_5;
  105. } else if (btn_code > 0x3F) {
  106. return btn_6;
  107. } else {
  108. return btn_7;
  109. }
  110. }
  111. static void getTime(void) {
  112. static uint8_t old_sec;
  113. /*устанавливаем указатель DS1307 на нулевой адрес*/
  114. twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
  115. twi_buf[1] = 0; //адрес регистра
  116. TWI_SendData(twi_buf, 2);
  117. /*считываем время с DS1307*/
  118. twi_buf[0] = (DS1307_ADR<<1)|1;
  119. TWI_SendData(twi_buf, 5);
  120. /*переписываем данные буфера драйвера в свой буфер*/
  121. TWI_GetData(twi_buf, 5);
  122. Clock.seconds = twi_buf[1];
  123. Clock.minutes = twi_buf[2];
  124. Clock.hours = twi_buf[3];
  125. if (old_sec != Clock.seconds) {
  126. Flag.needDot = 1;
  127. old_sec = Clock.seconds;
  128. } else {
  129. Flag.needDot = 0;
  130. }
  131. Flag.newTime = 1;
  132. }
  133. static void setTime(void) {
  134. /*подготавливаем сообщение*/
  135. twi_buf[0] = (DS1307_ADR<<1)|0; //адресный пакет
  136. twi_buf[1] = 0; //адрес регистра
  137. twi_buf[2] = Clock.seconds; //значение секунд
  138. twi_buf[3] = Clock.minutes; //значение минут
  139. twi_buf[4] = Clock.hours; //значение часов
  140. /*отправляем его*/
  141. TWI_SendData(twi_buf, 5);
  142. }
  143. static uint8_t ds18b20_Reset(void) {
  144. uint8_t i;
  145. /* Pull line low and wait for 480uS */
  146. DS18B20_LOW;
  147. DS18B20_OUTPUT_MODE;
  148. //ds18b20_delay(us(480));
  149. Flag.T1OC = 0;
  150. TCNT1 = 0;
  151. OCR1A = 480;
  152. TIMSK |= (1<<OCF1A);
  153. while (0 == Flag.T1OC) {
  154. MCUCR = 1<<SE;
  155. __sleep();
  156. }
  157. Flag.T1OC = 0;
  158. /* Release line and wait for 60uS */
  159. DS18B20_INPUT_MODE;
  160. //ds18b20_delay(us(60));
  161. TCNT1 = 0;
  162. OCR1A = 60;
  163. OCR1B = 420;
  164. TIMSK |= (1<<OCF1B);
  165. while (0 == Flag.T1OC) {
  166. MCUCR = 1<<SE;
  167. __sleep();
  168. }
  169. Flag.T1OC = 0;
  170. /* Store line value and wait until the completion of 480uS period */
  171. i = DS18B20_VALUE;
  172. //ds18b20_delay(us(420));
  173. while (0 == Flag.T1OC) {
  174. MCUCR = 1<<SE;
  175. __sleep();
  176. }
  177. TIMSK &= ~((1<<OCF1A) | (1<<OCF1B));
  178. /* Return the value read from the presence pulse (0=OK, else=WRONG) */
  179. return i;
  180. }
  181. static void ds18b20_WriteBit(uint8_t bit) {
  182. /* Pull line low for 1uS */
  183. DS18B20_LOW;
  184. DS18B20_OUTPUT_MODE;
  185. //ds18b20_delay(us(1));
  186. __delay_cycles(8);
  187. /* If we want to write 1, release the line (if not will keep low) */
  188. if(1 == bit) {
  189. DS18B20_INPUT_MODE;
  190. }
  191. /* Wait for 60uS and release the line */
  192. //ds18b20_delay(us(60));
  193. Flag.T1OC = 0;
  194. TCNT1 = 0;
  195. OCR1A = 60;
  196. TIMSK |= (1<<OCF1A);
  197. while (0 == Flag.T1OC) {
  198. MCUCR = 1<<SE;
  199. __sleep();
  200. }
  201. TIMSK &= ~(1<<OCF1A);
  202. DS18B20_INPUT_MODE;
  203. }
  204. static uint8_t ds18b20_ReadBit(void) {
  205. uint8_t bit=0;
  206. /* Pull line low for 1uS */
  207. DS18B20_LOW;
  208. DS18B20_OUTPUT_MODE;
  209. //ds18b20_delay(us(1));
  210. __delay_cycles(8);
  211. /* Release line and wait for 14uS */
  212. DS18B20_INPUT_MODE;
  213. //ds18b20_delay(us(14));
  214. Flag.T1OC = 0;
  215. TCNT1 = 0;
  216. OCR1A = 14;
  217. OCR1B = 45;
  218. TIMSK |= (1<<OCF1A) | (1<<OCF1B);
  219. while (0 == Flag.T1OC) {
  220. MCUCR = 1<<SE;
  221. __sleep();
  222. }
  223. Flag.T1OC = 0;
  224. /* Read line value */
  225. if (DS18B20_VALUE != 0) {
  226. bit = 0x80;
  227. }
  228. /* Wait for 45uS to end and return read value */
  229. //ds18b20_delay(us(45));
  230. while (0 == Flag.T1OC) {
  231. MCUCR = 1<<SE;
  232. __sleep();
  233. }
  234. TIMSK &= ~((1<<OCF1A) | (1<<OCF1B));
  235. return bit;
  236. }
  237. static uint8_t ds18b20_ReadByte(void) {
  238. uint8_t i=8, n=0;
  239. while (i--) {
  240. /* Shift one position right and store read value */
  241. n >>= 1;
  242. n |= ds18b20_ReadBit();
  243. }
  244. return n;
  245. }
  246. static void ds18b20_WriteByte(uint8_t byte) {
  247. uint8_t i=8;
  248. while (i--) {
  249. /* Write actual bit and shift one position right to make the next bit ready */
  250. ds18b20_WriteBit(byte & 0x01);
  251. byte >>= 1;
  252. }
  253. }
  254. static void ds18b20_StartMeasure(void) {
  255. /* Reset, skip ROM and start temperature conversion */
  256. if (ds18b20_Reset() != 0) {
  257. Temperature = -99;
  258. Flag.newTemp = 1;
  259. } else {
  260. ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
  261. ds18b20_WriteByte(DS18B20_CMD_CONVERTTEMP);
  262. RTOS_SetTask(ds18b20_ReadTemperature, 750, 0);
  263. }
  264. }
  265. static void ds18b20_ReadTemperature(void) {
  266. uint8_t temperature[2];
  267. int8_t digit;
  268. /* Reset, skip ROM and send command to read Scratchpad */
  269. if (ds18b20_Reset() != 0) {
  270. Temperature = -98;
  271. } else {
  272. ds18b20_WriteByte(DS18B20_CMD_SKIPROM);
  273. ds18b20_WriteByte(DS18B20_CMD_RSCRATCHPAD);
  274. /* Read Scratchpad (only 2 first bytes) */
  275. temperature[0]=ds18b20_ReadByte();
  276. temperature[1]=ds18b20_ReadByte();
  277. //ds18b20_reset();
  278. /* Store temperature integer digits */
  279. digit=temperature[0]>>4;
  280. digit|=(temperature[1]&0x7)<<4;
  281. /* Get only integer part of temperature */
  282. Temperature = digit / 16;
  283. }
  284. Flag.newTemp = 1;
  285. }
  286. /**
  287. * I n t e r r u p t h a n d l e r s
  288. */
  289. #pragma vector=TIMER0_OVF_vect
  290. __interrupt void TIMER0_OVF_ISR(void) {
  291. static uint8_t indicator = 0;
  292. TCNT0 = TIM0_CNT; // reload timer
  293. INDCTR_COMMON_PORT &= ~INDCTR_COMMON_ALL; // off all indikators
  294. switch (indicator) {
  295. case 0:
  296. INDCTR_SEGMENT_PORT = Display[0];
  297. INDCTR_COMMON_PORT |= 0x01;
  298. indicator = 1;
  299. break;
  300. case 1:
  301. if (1 == Flag.needDot) {
  302. INDCTR_SEGMENT_PORT = Display[1] | Sym_dot;
  303. } else {
  304. INDCTR_SEGMENT_PORT = Display[1];
  305. }
  306. INDCTR_COMMON_PORT |= 0x02;
  307. indicator = 2;
  308. break;
  309. case 2:
  310. INDCTR_SEGMENT_PORT = Display[2];
  311. INDCTR_COMMON_PORT |= 0x04;
  312. indicator = 3;
  313. break;
  314. case 3:
  315. INDCTR_SEGMENT_PORT = Display[3];
  316. INDCTR_COMMON_PORT |= 0x08;
  317. default:
  318. indicator = 0;
  319. break;
  320. }
  321. }
  322. #pragma vector=TIMER1_COMPA_vect
  323. __interrupt void TIMER1_COMPA_ISR(void) {
  324. Flag.T1OC = 1;
  325. }
  326. #pragma vector=TIMER1_COMPB_vect
  327. __interrupt void TIMER1_COMPB_ISR(void) {
  328. Flag.T1OC = 1;
  329. }
  330. #pragma vector=ADC_vect
  331. __interrupt void ADC_ISR(void) {
  332. resultADC = ADCH;
  333. ADCSR &= ~(1<<ADIE); // disable interrupt
  334. Flag.newBTN = 1;
  335. }