You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

303 regels
8.4 KiB

  1. #include <stdbool.h>
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #define F_CPU 20000000UL //20 MHz
  5. #include <util/delay.h>
  6. NO LONGER USED
  7. /* 7-Segment display: */
  8. #define NUM_DIGITS 3U //3 Digits
  9. #define DIGIT_TENS 2U //left
  10. #define DIGIT_ONES 1U //middle
  11. #define DIGIT_UNIT 0U //right
  12. #define SELECT_DIGIT(digit) (1U << digit)
  13. /* DS18B20 peripherals: */
  14. #define DS18B20_PORT PORTC
  15. #define DS18B20_DDR DDRC
  16. #define DS18B20_PIN PINC
  17. #define DS18B20_DQ PINC3
  18. /* DS18B20 commands: */
  19. #define DS18B20_CMD_CONVERTTEMP 0x44U
  20. #define DS18B20_CMD_RSCRATCHPAD 0xBEU
  21. #define DS18B20_CMD_WSCRATCHPAD 0x4EU
  22. #define DS18B20_CMD_CPYSCRATCHPAD 0x48U
  23. #define DS18B20_CMD_RECEEPROM 0xB8U
  24. #define DS18B20_CMD_RPWRSUPPLY 0xB4U
  25. #define DS18B20_CMD_SEARCHROM 0xF0U
  26. #define DS18B20_CMD_READROM 0x33U
  27. #define DS18B20_CMD_MATCHROM 0x55U
  28. #define DS18B20_CMD_SKIPROM 0xCCU
  29. #define DS18B20_CMD_ALARMSEARCH 0xECU
  30. /* Symbol indexes: */
  31. #define SYM_n 10U
  32. #define SYM_o 11U
  33. #define SYM_E 12U
  34. #define SYM_R 13U
  35. #define SYM_DEG_CELCIUS 14U
  36. #define SYM_P_P 15U
  37. #define SYM_OFF 16U
  38. #define SYM_DASH 17U
  39. /*
  40. 7-Segment Layout:
  41. A
  42. F B
  43. G
  44. E C
  45. D P
  46. Pin 7 6 5 4 3 2 1 0
  47. Segment A F B E D C G P
  48. */
  49. static uint8_t g_au8Symbols[18U] =
  50. {
  51. /* 00 */ 0b11111100U, //0 (ABCDEF)
  52. /* 01 */ 0b00100100U, //1 (BC)
  53. /* 02 */ 0b10111010U, //2 (ABDEG)
  54. /* 03 */ 0b10101110U, //3 (ABCDG)
  55. /* 04 */ 0b01100110U, //4 (BCFG)
  56. /* 05 */ 0b11001110U, //5 (ACDFG)
  57. /* 06 */ 0b11011110U, //6 (ACDEFG)
  58. /* 07 */ 0b10100100U, //7 (ABC)
  59. /* 08 */ 0b11111110U, //8 (ABCDEFG)
  60. /* 09 */ 0b11101110U, //9 (ABCDFG)
  61. /* 10 */ 0b00010110U, //n (CEG) SYM_n
  62. /* 11 */ 0b00011110U, //o (CDEG) SYM_o
  63. /* 12 */ 0b11011010U, //E (ADEFG) SYM_E
  64. /* 13 */ 0b00010010U, //r (EG) SYM_r
  65. /* 14 */ 0b10101101U, //degC (ABCDP) SYM_DEG_CELCIUS
  66. /* 15 */ 0b11110011U, //P. (ABEFGP) SYM_P_P
  67. /* 16 */ 0b00000000U, //OFF SYM_OFF
  68. /* 17 */ 0b00000010U //- (G) SYM_DASH
  69. };
  70. uint8_t g_u8ISRDigitSelect = 0U;
  71. uint8_t g_au8Digits[3U] =
  72. {
  73. SYM_OFF, //unit
  74. SYM_OFF, //ones
  75. SYM_OFF //tens
  76. };
  77. void vInit( void );
  78. void vSetValue( uint8_t u8Value, uint8_t u8Unit );
  79. void vSetDisplayDigits( uint8_t u8Tens, uint8_t u8Ones, uint8_t u8Unit );
  80. uint8_t u8DS18B20_Reset( void );
  81. void vDS18B20_WriteByte( uint8_t u8Byte );
  82. void vDS18B20_WriteBit( uint8_t u8Bit );
  83. uint8_t u8DS18B20_ReadByte( void );
  84. uint8_t u8DS18B20_ReadBit( void );
  85. /************************************************************************/
  86. /* Timer1 ISR - show values on display */
  87. /************************************************************************/
  88. ISR ( TIMER1_COMPA_vect )
  89. {
  90. PORTB = 0;
  91. PORTD = 0;
  92. _delay_us(2);
  93. PORTB = SELECT_DIGIT(g_u8ISRDigitSelect);
  94. PORTD = g_au8Symbols[g_au8Digits[g_u8ISRDigitSelect]];
  95. g_u8ISRDigitSelect++;
  96. if (g_u8ISRDigitSelect > 2U)
  97. {
  98. g_u8ISRDigitSelect = 0U;
  99. }
  100. }
  101. /************************************************************************/
  102. /* main() */
  103. /************************************************************************/
  104. int main(void)
  105. {
  106. uint8_t u8TempLo, u8TempHi;
  107. float f32Temperature;
  108. /* Init I/O: */
  109. vInit();
  110. /* Set default value: */
  111. vSetDisplayDigits( SYM_DASH, SYM_DASH, SYM_DASH );
  112. /* wait 3 seconds for DS18B20 sensor */
  113. _delay_ms(2400);
  114. while (1)
  115. {
  116. (void) u8DS18B20_Reset();
  117. vDS18B20_WriteByte( DS18B20_CMD_SKIPROM );
  118. vDS18B20_WriteByte( DS18B20_CMD_CONVERTTEMP );
  119. while ( !u8DS18B20_ReadBit() );
  120. (void) u8DS18B20_Reset();
  121. vDS18B20_WriteByte( DS18B20_CMD_SKIPROM );
  122. vDS18B20_WriteByte( DS18B20_CMD_RSCRATCHPAD );
  123. u8TempLo = u8DS18B20_ReadByte();
  124. u8TempHi = u8DS18B20_ReadByte();
  125. f32Temperature = ((u8TempHi << 8) + u8TempLo) * 0.0625;
  126. vSetValue( (uint8_t) f32Temperature, SYM_DEG_CELCIUS );
  127. _delay_ms(500);
  128. } //end while(1)
  129. }
  130. /************************************************************************/
  131. /* Initialize inputs and outputs */
  132. /************************************************************************/
  133. void vInit( void )
  134. {
  135. /* Port D - Pins 0-7: Outputs */
  136. DDRD = 0b11111111U;
  137. /* Port B - Pins 0-2: Outputs */
  138. DDRB = 0b00000111U;
  139. /* 16-bit TIMER1 in CTC mode
  140. * prescaler = 8
  141. * 20 MHz / 8 = 2.5 MHz
  142. * Compare value = 2500 => 1 ms IRQ
  143. */
  144. TCCR1A = 0U;
  145. TCCR1B = (1<<WGM12) | (1<<CS11);
  146. OCR1A = 2500U;
  147. TIMSK1 |= (1<<OCIE1A);
  148. sei();
  149. return; //void
  150. }
  151. /************************************************************************/
  152. /* Set new values to be shown on display */
  153. /************************************************************************/
  154. void vSetValue( uint8_t u8Value, uint8_t u8Unit )
  155. {
  156. uint8_t u8Tmp = u8Value / 10U;
  157. vSetDisplayDigits(u8Tmp, u8Value - (u8Tmp * 10U), u8Unit);
  158. return; //void
  159. }
  160. /************************************************************************/
  161. /* Set display digits individually */
  162. /************************************************************************/
  163. void vSetDisplayDigits( uint8_t u8Tens, uint8_t u8Ones, uint8_t u8Unit )
  164. {
  165. g_au8Digits[DIGIT_TENS] = u8Tens;
  166. g_au8Digits[DIGIT_ONES] = u8Ones;
  167. g_au8Digits[DIGIT_UNIT] = u8Unit;
  168. return; //void
  169. }
  170. /************************************************************************/
  171. /* Reset DS18B20 (960 us) */
  172. /************************************************************************/
  173. uint8_t u8DS18B20_Reset( void )
  174. {
  175. uint8_t u8Status;
  176. //low for 480 us
  177. DS18B20_PORT &= ~ (1<<DS18B20_DQ); //low
  178. DS18B20_DDR |= (1<<DS18B20_DQ); //output
  179. _delay_us(480);
  180. //release line and wait for 60 us
  181. DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
  182. _delay_us(60);
  183. //get value and wait 420 us
  184. u8Status = (DS18B20_PIN & (1<<DS18B20_DQ));
  185. _delay_us(420);
  186. //return the read value: 0=okay, 1=error
  187. return u8Status;
  188. }
  189. /************************************************************************/
  190. /* Write byte to DS18B20 (8 * 61 us = 488 us) */
  191. /************************************************************************/
  192. void vDS18B20_WriteByte( uint8_t u8Byte )
  193. {
  194. uint8_t u8Bits = 8U;
  195. while ( u8Bits-- )
  196. {
  197. vDS18B20_WriteBit( u8Byte & 1U );
  198. u8Byte >>= 1U;
  199. }
  200. return; //void
  201. }
  202. /************************************************************************/
  203. /* Write single bit to DS18B20 (61 us) */
  204. /************************************************************************/
  205. void vDS18B20_WriteBit( uint8_t u8Bit )
  206. {
  207. //low for 1 us
  208. DS18B20_PORT &= ~ (1U<<DS18B20_DQ); //low
  209. DS18B20_DDR |= (1U<<DS18B20_DQ); //output
  210. _delay_us(1);
  211. //if we want to write 1, release the line (if not will keep low)
  212. if (1U == u8Bit )
  213. {
  214. DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
  215. }
  216. //wait 60 us and release the line
  217. _delay_us(60);
  218. DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
  219. return; //void
  220. }
  221. /************************************************************************/
  222. /* Read byte from DS18B20 (8 * 60 us = 480 us) */
  223. /************************************************************************/
  224. uint8_t u8DS18B20_ReadByte( void )
  225. {
  226. uint8_t u8Bits = 8U;
  227. uint8_t n = 0U;
  228. while ( u8Bits-- )
  229. {
  230. n >>= 1U;
  231. n |= (u8DS18B20_ReadBit()<<7U);
  232. }
  233. return n;
  234. }
  235. /************************************************************************/
  236. /* Read single bit from DS18B20 (60 us) */
  237. /************************************************************************/
  238. uint8_t u8DS18B20_ReadBit( void )
  239. {
  240. uint8_t u8Bit = 0U;
  241. //low for 1 us
  242. DS18B20_PORT &= ~ (1U<<DS18B20_DQ); //low
  243. DS18B20_DDR |= (1U<<DS18B20_DQ); //output
  244. _delay_us(1);
  245. //release line and wait for 14 us
  246. DS18B20_DDR &= ~(1U<<DS18B20_DQ); //input
  247. _delay_us(14);
  248. //read the value
  249. if ( DS18B20_PIN & (1U<<DS18B20_DQ) )
  250. {
  251. u8Bit = 1U;
  252. }
  253. //wait 45 us and return read value
  254. _delay_us(45);
  255. return u8Bit;
  256. }