fork download
  1. #include <avr/io.h>
  2.  
  3. #ifndef F_CPU
  4. #define F_CPU 16000000UL
  5. #endif
  6.  
  7. #include <util/delay.h>
  8.  
  9. #define I2C_SDA_DDR DDRB
  10. #define I2C_SCL_DDR DDRB
  11. #define I2C_TEST_DDR DDRB
  12.  
  13. #define I2C_SDA_PORT PORTB
  14. #define I2C_SCL_PORT PORTB
  15. #define I2C_TEST_PORT PORTB
  16.  
  17. #define I2C_SDA_PIN PB1
  18. #define I2C_SCL_PIN PB2
  19. #define I2C_TEST_PIN PB5
  20.  
  21. #define STARTB 0x00 //star bit
  22. #define STOPB 0x01 //stop bit
  23.  
  24. #define setPin(pport, ppin, pbit) \
  25.   (pport = pbit \
  26.   ? pport | (0x01 << ppin) \
  27.   : pport & (~(0x01 << ppin)))
  28.  
  29. uint8_t ack;
  30.  
  31. void setStaSto(const uint8_t pStaSto){
  32. //reset SCL and SDA
  33. pStaSto \
  34. ? setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x01) \
  35. : setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x00);
  36. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x00);
  37.  
  38. //SDA HIGH for StartBit, SDA LOW, for StopBit
  39. pStaSto
  40. ? setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x00) //begin stop bit
  41. : setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x01); //begin start bit
  42. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x01);
  43. _delay_us(0x01); //7 - tSU:sTA > 600nS
  44.  
  45. //SDA LOW for StartBit, SDA HIGH for StopBit
  46. pStaSto
  47. ? setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x01) //end stop bit
  48. : setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x00); //end start bit
  49. _delay_us(0x01); //6 - tHD:sTA > 600nS
  50.  
  51. //set SCL LOW, end of Start or Stop Conditions
  52. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x00);
  53. _delay_us(0x02); //3 - tLOW > 1.3uS - maybe it's not needed
  54. }
  55.  
  56. void sendByte(uint8_t pByte){
  57. uint8_t tmppByte = pByte;
  58.  
  59. for(uint8_t i = 0x00; i < 0x08; i++){
  60. //set SCL to LOW to allow Data change
  61. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x00);
  62. _delay_us(0x01); // 3 - tLOW > 1.3uS - not sure if needed - I set it to the 1sthalf of waht is needed
  63. setPin(I2C_SDA_PORT, I2C_SDA_PIN, tmppByte >> 0x07); //Get MSB of pByte
  64. tmppByte <<= 0x01; //Get next bit
  65. _delay_us(0x01); //3 - tLOW > 1.3 uS - not sure if needed - I set it to the 2nd half of what is needed
  66. //set SCL to HIGH
  67. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x01);
  68. _delay_us(0x01); //2 - tHIGH > 600nS
  69. setPin(I2C_SCL_PORT, I2C_SCL_PIN, 0x00);
  70. //8 - tHD:DAT > 0 - therefore, not needed
  71. }
  72. ack = checkACK();
  73. }
  74.  
  75. uint8_t checkACK(void){
  76. //set SDA as input to allow SDA reading
  77. setPin(I2C_SDA_DDR, I2C_SDA_PIN, 0x00);
  78. //set SDA pin to tri-state mode, disable internal pull-up
  79. setPin(I2C_SDA_PORT, I2C_SDA_PIN, 0x00);
  80. //read ACK value
  81. ack = ( I2C_SDA_PORT & (0x01 << I2C_SDA_PIN) ) \
  82. ? 0x01 \
  83. : 0x00;
  84. //set SDA as output back again
  85. setPin(I2C_SDA_DDR, I2C_SDA_PIN, 0x01);
  86. return ack;
  87. }
  88.  
  89. void writeByte(uint8_t pByte){
  90. setStaSto(STARTB);
  91. sendByte(0xA0);
  92. checkACK();
  93. sendByte(pByte);
  94. checkACK();
  95. setStaSto(STOPB);
  96. checkACK();
  97. }
  98.  
  99. int main(void){
  100. //one time run code goes here
  101. //set DDR SDA and SCL pins as output
  102. setPin(I2C_SDA_DDR, I2C_SDA_PIN, 0x01);
  103. setPin(I2C_SCL_DDR, I2C_SCL_PIN, 0x01);
  104. setPin(I2C_TEST_DDR, I2C_TEST_PIN, 0x01);
  105.  
  106. //loop code goes here
  107. while(0x01){
  108. setPin(I2C_TEST_PORT, I2C_TEST_PIN, 0x01);
  109. _delay_ms(50);
  110. setPin(I2C_TEST_PORT, I2C_TEST_PIN, 0x00);
  111. _delay_ms(100);
  112. }
  113. return 0;
  114. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:1:20: fatal error: avr/io.h: No such file or directory
compilation terminated.
stdout
Standard output is empty