Advertisement
Guest User

Untitled

a guest
May 26th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.57 KB | None | 0 0
  1. /*
  2. * LM75_Tempsensor.c
  3. * Temperaturmessung (5x pro Sekunde) und Ausgabe der Temperatur als Binärwert am PORTD
  4. * Eine negative Temperatur wird zusätzlich durch eine LED an PB0 angezeigt
  5. * CPU: ATmega88
  6. * FCPU: 8MHz
  7. * I²C CLK Frequency = 100kHz, CLK = 8000000/(16 + 2*(0x50)*1)
  8. */
  9. #include <avr/io.h>
  10. #include <util/delay.h>
  11.  
  12. /*** Statusregister codes and other defines ***/
  13. #define START 0x08 // A START condition has been transmitted
  14. #define R_START 0x10 // A REPEATED START condition has been transmitted
  15. #define SLA_W 0x90 // Slave Address & Write 1001 0000
  16. #define SLA_R 0x91 // Slave Address & Read 1001 0001
  17. #define MT_SLA_ACK 0x18 // Master Transmit SLA+W has been transmitted & ACK has been received
  18. #define MR_SLA_ACK 0x40 // Master Receive SLA + R has been transmitted & ACK has been received
  19. #define MT_DATA_ACK 0x28 // Master Transmit Data byte has been transmitted & ACK has been received
  20. #define MR_DATA_NACK 0x58 // Master Receive Data byte has been transmitted & NACK has been returned
  21. #define BIT_RATE 0x50 // Set value for the bit rate register TWBR
  22. #define POINTER_ADDRESS 0x00 // LM75 pointer address for temperature register
  23. void ERROR(void); // Prototyping of function "ERROR"
  24.  
  25. /*** Function to send a START Condition ***/
  26. void TWI_START(void)
  27. {
  28. TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  29. // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
  30. while (!(TWCR & (1<<TWINT)));
  31. // Check value of TWI statusregister. Mask prescaler bits. If status different from START go to ERROR if ((TWSR & 0xF8) != START)
  32. ERROR();
  33. }
  34.  
  35. /*** Function to send the Slave Address with ACK in Master Transmit Mode ***/
  36. void TWI_MT_SLA_ACK(void)
  37. {
  38. // Load SLA_W into TWDR Register
  39. TWDR = SLA_W;
  40. // Clear TWINT bit in TWCR to start transmission of address
  41. TWCR = (1<<TWINT) | (1<<TWEN);
  42. // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
  43. while (!(TWCR & (1<<TWINT)));
  44. // Check value of TWI status register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
  45. if ((TWSR & 0xF8) != MT_SLA_ACK)
  46. ERROR();
  47. }
  48.  
  49. /*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
  50. void TWI_MT_DATA_ACK(void)
  51. {
  52. // Load DATA into TWDR register
  53. TWDR = POINTER_ADDRESS;
  54. // Clear TWINT bit in TWCR to start transmission of data
  55. TWCR = (1<<TWINT) | (1<<TWEN);
  56. // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
  57. while (!(TWCR & (1<<TWINT)));
  58. // Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
  59. if ((TWSR & 0xF8) != MT_DATA_ACK)
  60. ERROR();
  61. }
  62.  
  63. /*** Function to send a REPEATED START condition **/
  64. void TWI_R_START(void)
  65. {
  66. // Send a START condition
  67. TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  68. // Wait for TWINT Flag set. This indicates that the START condition has been transmitted
  69. while (!(TWCR & (1<<TWINT)));
  70. // Check value of TWI statusregister. Mask prescaler bits. If status different from R_START go to ER-ROR
  71. if ((TWSR & 0xF8) != R_START)
  72. ERROR();
  73. }
  74.  
  75. /*** Function to send the Slave Address in Master Receive Mode with Acknowledge **/
  76. void TWI_MR_SLA_ACK(void)
  77. {
  78. // Load SLA_R into TWDR Register
  79. TWDR = SLA_R;
  80. // Clear TWINT bit in TWCR to start transmission of address
  81. TWCR = (1<<TWINT) | (1<<TWEN);
  82. // Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
  83. while (!(TWCR & (1<<TWINT)));
  84. // Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
  85. if ((TWSR & 0xF8) != MR_SLA_ACK)
  86. ERROR();
  87. }
  88.  
  89. /*** Function to read one Databyte in Master Receive Mode with NACK ***/
  90. uint8_t TWI_READ_DATABYTE_NACK(void)
  91. {
  92. // Read one data byte
  93. TWCR = (1<<TWINT)| (1<<TWEN);
  94. // Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
  95. while (!(TWCR & (1<<TWINT)));
  96. // Check value of TWI status register. Mask prescaler bits. If status different from MR_DATA_NACK go to ERROR
  97. if ((TWSR & 0xF8) != MR_DATA_NACK)
  98. ERROR();
  99. return TWDR; // Return the value of data register
  100. }
  101.  
  102. /*** function to send a STOP condition ***/
  103. void TWI_STOP(void)
  104. {
  105. TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Transmit STOP condition
  106. }
  107.  
  108. /*** function to show a bus error ***/
  109. void ERROR(void)
  110. {
  111. PORTB |= (1<<PB1); // ERROR LED ON
  112. }
  113.  
  114. uint8_t LSByte, MSByte;
  115. uint16_t data_16bit, temperature, high_byte, low_byte;
  116.  
  117. int main(void)
  118. {
  119. DDRD = 0xFF; // PORTD = output
  120. DDRC = 0x3F; // PC0 ... PC5 = output
  121. DDRB = 0x03; // PB0 and PB1 = output
  122. TWBR = BIT_RATE; // Set the TWI clock-frequency in bit rate register
  123. while(1)
  124. {
  125. TWI_START(); // Send START condition
  126. TWI_MT_SLA_ACK(); // Master Transmit Slave Address with ACK
  127. TWI_MT_DATA_ACK(); // Master Transmit Data with ACK
  128. TWI_R_START(); // Send REPEATED START condition
  129. TWI_MR_SLA_ACK(); // Send the Slave Address in Master Receive Mode with ACK
  130. MSByte = TWI_READ_DATABYTE_NACK(); // Read one Databyte without ACK
  131. LSByte = TWI_READ_DATABYTE_NACK(); // Read one Databyte without ACK
  132. TWI_STOP(); // Send STOP condition
  133. low_byte = LSByte >> 5; // Shift LSByte 5 digits right
  134. high_byte = MSByte << 8; // Shift MSByte 8 digits left
  135. data_16bit = high_byte + low_byte; // Store 16bit-result of temp-register in data
  136. temperature = data_16bit >> 8; // Shift data 8 digits right to get a 8bit value
  137.  
  138. if (MSByte & 0x80) // if bit7 = 1 --> negative Temperature
  139. {
  140. MSByte = ~MSByte + 1; // build 2´s complement
  141. temperature = MSByte >> 3; // divide by 8
  142. PORTD = temperature; // Show negative temperature on PORTD
  143. PORTB |= (1<<PB0); // LED for negative Temperature ON
  144. }
  145.  
  146. else // if bit7 = 0 --> positive Temperature
  147. {
  148. PORTB &= ~(1<<PB0); // LED for negative Temperature OFF
  149. PORTD = temperature; // Show positive temperature on PORTD
  150. }
  151. _delay_ms(200); // wait 200ms for new readout
  152. }
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement