Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <avr/interrupt.h>
- #include <avr/io.h>
- #include <avr/sleep.h>
- #include <util/delay.h>
- #include "USI_TWI_Master.h"
- /*
- Example using an ATtiny85, MCP23017, interrupts and I2C to illuminate
- each of 8 LEDs when the appropriate one of 8 buttons are pressed.
- A couple of further LEDs on the otherwise-unused ATtiny85 pins give
- diagnostic info.
- Connect Arduino (as ArduinoISP) to ATTiny85 for programming:
- 13 7
- 12 6
- 11 5
- 10 1
- Connect ATtiny85:
- * Pin 2, via LED and resistor, to GND
- * Pin 3, via LED and resistor, to GND
- * Pin 4 to GND
- * Pin 5, via 4k7 resistor, to 5V
- * Pin 7, via 4k7 resistor, to 5V
- * Pin 8 to 5V
- Connect MCP23017:
- * Pins 1-8 via buttons to GND.
- * Pin 9 to 5V
- * Pin 10 to GND
- * Pin 12 to ATtiny85 pin 7 (SCL)
- * Pin 13 to ATtiny85 pin 5 (SDA)
- * Pins 15-17 to GND
- * Pin 18 to ATtiny85 pin 1 (~RESET)
- * Pin 19 to ATtiny85 pin 6 (interrupt)
- * Pins 21-28, via LED and resistor, to GND
- You need USI_TWI_Master.c and USI_TWI_Master.h from the zip file on
- http://www.atmel.com/images/atmel-2561-using-the-usi-module-as-a-i2c-master_ap-note_avr310.pdf
- Compile and upload with:
- avr-gcc -mmcu=attiny85 -Wall -Werror -Os -DF_CPU=1000000UL -o bin.elf main.c USI_TWI_Master.c
- avr-objcopy -j .text -j .data -O ihex bin.elf bin.hex
- avrdude -b 19200 -c arduino -P /dev/ttyUSB0 -p attiny85 -e -U flash:w:bin.hex:i
- */
- // MCP23017 slave address:
- // 0 1 0 0 a2 a1 a0 R/~W
- // 0 1 0 0 0 0 0 0 = 0x40 to write
- // 0 1 0 0 0 0 0 1 = 0x41 to read
- #define SLAVE_WRITE_ADDR 0x40
- #define SLAVE_READ_ADDR 0x41
- ISR(PCINT0_vect) {
- unsigned char messageBuf[3];
- unsigned char temp;
- while(!(PINB & 0x02)) {
- PORTB ^= 0b00010000;
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x13; // GPIOB
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 2);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- messageBuf[0] = SLAVE_READ_ADDR;
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 2);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- unsigned char result = messageBuf[1];
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x12; // GPIOA
- messageBuf[2] = result;
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- }
- }
- int main(void) {
- unsigned char messageBuf[3];
- unsigned char temp;
- DDRB = 0b00011000; // Pins 2 and 3 are outputs
- PORTB = 0b00000010; // Turn the LEDs off and enable the
- // interrupt pin (6) pull-up resistor
- USI_TWI_Master_Initialise();
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x0A; // IOCON register
- messageBuf[2] = 0x04; // Set interrupt pin to open-drain
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x00; // IODIRA register
- messageBuf[2] = 0x00; // set all of port A to outputs
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x03; // IPOLB register
- messageBuf[2] = 0xFF; // invert all of port B's inputs
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x0D; // GPPUB register
- messageBuf[2] = 0xFF; // enable pull-up resistor for all
- // of port B's inputs
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- messageBuf[0] = SLAVE_WRITE_ADDR;
- messageBuf[1] = 0x05; // GPINTENB register
- messageBuf[2] = 0xFF; // enable interrupt-on-change for all
- // of port B's inputs
- temp = USI_TWI_Start_Transceiver_With_Data(messageBuf, 3);
- if(!temp) {
- PORTB |= 0b00001000;
- }
- GIMSK = 0x20; // Enable the PCINT interrupt
- PCMSK = 0b00000010; // Enable PCINT interrupts for pin 6
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- sei();
- while(1) {
- sleep_mode();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement