Advertisement
Guest User

Untitled

a guest
Dec 15th, 2018
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.33 KB | None | 0 0
  1.  
  2. #include <avr/interrupt.h>
  3. #include <avr/io.h>
  4. #include <avr/sleep.h>
  5. #include <util/delay.h>
  6.  
  7. #include "USI_TWI_Master.h"
  8.  
  9. /*
  10. Example using an ATtiny85, MCP23017, interrupts and I2C to illuminate
  11. each of 8 LEDs when the appropriate one of 8 buttons are pressed.
  12. A couple of further LEDs on the otherwise-unused ATtiny85 pins give
  13. diagnostic info.
  14.  
  15. Connect Arduino (as ArduinoISP) to ATTiny85 for programming:
  16. 13 7
  17. 12 6
  18. 11 5
  19. 10 1
  20.  
  21. Connect ATtiny85:
  22. * Pin 2, via LED and resistor, to GND
  23. * Pin 3, via LED and resistor, to GND
  24. * Pin 4 to GND
  25. * Pin 5, via 4k7 resistor, to 5V
  26. * Pin 7, via 4k7 resistor, to 5V
  27. * Pin 8 to 5V
  28.  
  29. Connect MCP23017:
  30. * Pins 1-8 via buttons to GND.
  31. * Pin 9 to 5V
  32. * Pin 10 to GND
  33. * Pin 12 to ATtiny85 pin 7 (SCL)
  34. * Pin 13 to ATtiny85 pin 5 (SDA)
  35. * Pins 15-17 to GND
  36. * Pin 18 to ATtiny85 pin 1 (~RESET)
  37. * Pin 19 to ATtiny85 pin 6 (interrupt)
  38. * Pins 21-28, via LED and resistor, to GND
  39.  
  40. You need USI_TWI_Master.c and USI_TWI_Master.h from the zip file on
  41. http://www.atmel.com/images/atmel-2561-using-the-usi-module-as-a-i2c-master_ap-note_avr310.pdf
  42.  
  43. Compile and upload with:
  44. avr-gcc -mmcu=attiny85 -Wall -Werror -Os -DF_CPU=1000000UL -o bin.elf main.c USI_TWI_Master.c
  45. avr-objcopy -j .text -j .data -O ihex bin.elf bin.hex
  46. avrdude -b 19200 -c arduino -P /dev/ttyUSB0 -p attiny85 -e -U flash:w:bin.hex:i
  47. */
  48.  
  49. // MCP23017 slave address:
  50. // 0 1 0 0 a2 a1 a0 R/~W
  51. // 0 1 0 0 0 0 0 0 = 0x40 to write
  52. // 0 1 0 0 0 0 0 1 = 0x41 to read
  53. #define SLAVE_WRITE_ADDR 0x40
  54. #define SLAVE_READ_ADDR 0x41
  55.  
  56. ISR(PCINT0_vect) {
  57. unsigned char messageBuf[3];
  58. unsigned char temp;
  59.  
  60. while(!(PINB & 0x02)) {
  61. PORTB ^= 0b00010000;
  62. messageBuf[0] = SLAVE_WRITE_ADDR;
  63. messageBuf[1] = 0x13; // GPIOB
  64. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 2);
  65. if(!temp) {
  66. PORTB |= 0b00001000;
  67. }
  68. messageBuf[0] = SLAVE_READ_ADDR;
  69. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 2);
  70. if(!temp) {
  71. PORTB |= 0b00001000;
  72. }
  73. unsigned char result = messageBuf[1];
  74. messageBuf[0] = SLAVE_WRITE_ADDR;
  75. messageBuf[1] = 0x12; // GPIOA
  76. messageBuf[2] = result;
  77. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  78. if(!temp) {
  79. PORTB |= 0b00001000;
  80. }
  81. }
  82. }
  83.  
  84. int main(void) {
  85. unsigned char messageBuf[3];
  86. unsigned char temp;
  87.  
  88. DDRB = 0b00011000; // Pins 2 and 3 are outputs
  89. PORTB = 0b00000010; // Turn the LEDs off and enable the
  90. // interrupt pin (6) pull-up resistor
  91.  
  92. USI_TWI_Master_Initialise();
  93.  
  94. messageBuf[0] = SLAVE_WRITE_ADDR;
  95. messageBuf[1] = 0x0A; // IOCON register
  96. messageBuf[2] = 0x04; // Set interrupt pin to open-drain
  97. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  98. if(!temp) {
  99. PORTB |= 0b00001000;
  100. }
  101. messageBuf[0] = SLAVE_WRITE_ADDR;
  102. messageBuf[1] = 0x00; // IODIRA register
  103. messageBuf[2] = 0x00; // set all of port A to outputs
  104. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  105. if(!temp) {
  106. PORTB |= 0b00001000;
  107. }
  108. messageBuf[0] = SLAVE_WRITE_ADDR;
  109. messageBuf[1] = 0x03; // IPOLB register
  110. messageBuf[2] = 0xFF; // invert all of port B's inputs
  111. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  112. if(!temp) {
  113. PORTB |= 0b00001000;
  114. }
  115. messageBuf[0] = SLAVE_WRITE_ADDR;
  116. messageBuf[1] = 0x0D; // GPPUB register
  117. messageBuf[2] = 0xFF; // enable pull-up resistor for all
  118. // of port B's inputs
  119. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  120. if(!temp) {
  121. PORTB |= 0b00001000;
  122. }
  123. messageBuf[0] = SLAVE_WRITE_ADDR;
  124. messageBuf[1] = 0x05; // GPINTENB register
  125. messageBuf[2] = 0xFF; // enable interrupt-on-change for all
  126. // of port B's inputs
  127. temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
  128. if(!temp) {
  129. PORTB |= 0b00001000;
  130. }
  131.  
  132. GIMSK = 0x20; // Enable the PCINT interrupt
  133. PCMSK = 0b00000010; // Enable PCINT interrupts for pin 6
  134.  
  135. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  136.  
  137. sei();
  138.  
  139. while(1) {
  140. sleep_mode();
  141. }
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement