main.c 8.8 KB

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