Браслет с кольцом на цепочке

Поделитесь в социальных сетях:vKontakteFacebookTwitter

Пример реализации I2C Slave на AVR микроконтроллере Atmega8

#include 
#include 
#include 

#define I2CSLAVE_ADDR		0x4E

#define PORT_DDR			0xB0 // PORTB Settings
#define PORT_IN				0xB1 // Get PINB
#define PORT_OUT			0xB2 // Set PORTB

unsigned char regaddr; // Store the Requested Register Address
unsigned char regdata; // Store the Register Address Data

void i2c_slave_action(unsigned char rw_status)
{
	switch(regaddr) {
		// PORT
		case PORT_DDR:
			if (rw_status == 0)
				// read
				regdata = DDRB;
			else
				// write
				DDRB = regdata;
			break;

		case PORT_IN:
			if (rw_status == 0)
				// read
				regdata = PINB;
			break;

		case PORT_OUT:
			if (rw_status == 1)
				// write
				PORTB = regdata;
			break;
	}
}

ISR(TWI_vect)
{
	static unsigned char i2c_state;
	unsigned char twi_status;

	// Disable Global Interrupt
	cli();

	// Get TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
	twi_status=TWSR & 0xF8;     

	switch(twi_status) {
		case TW_SR_SLA_ACK:	// 0x60: SLA+W received, ACK returned
			i2c_state=0;	// Start I2C State for Register Address required
			break;

		case TW_SR_DATA_ACK:	// 0x80: data received, ACK returned
			if (i2c_state == 0) {
				regaddr = TWDR;	// Save data to the register address
				i2c_state = 1;
			} else {
				regdata = TWDR;	// Save to the register data
				i2c_state = 2;
			}
			break;

		case TW_SR_STOP:	// 0xA0: stop or repeated start condition received while selected
			if (i2c_state == 2) {
				i2c_slave_action(1);	// Call Write I2C Action (rw_status = 1)
				i2c_state = 0;		// Reset I2C State
			}
			break;

		case TW_ST_SLA_ACK:	// 0xA8: SLA+R received, ACK returned
		case TW_ST_DATA_ACK:	// 0xB8: data transmitted, ACK received
			if (i2c_state == 1) {
				i2c_slave_action(0);	// Call Read I2C Action (rw_status = 0)
				TWDR = regdata;		// Store data in TWDR register
				i2c_state = 0;		// Reset I2C State
			}
			break;

		case TW_ST_DATA_NACK:	// 0xC0: data transmitted, NACK received
		case TW_ST_LAST_DATA:	// 0xC8: last data byte transmitted, ACK received
		case TW_BUS_ERROR:	// 0x00: illegal start or stop condition
		default:
			i2c_state = 0;	// Back to the Begining State
	}
	// Clear TWINT Flag
	TWCR |= (1

Тактовая частота микроконтроллера должен быть не менее 8 MHz.

В этом примере, обращаясь по шине I2C к устройству по адресу указанному в строке:

#define I2CSLAVE_ADDR        0x4E

можно управлять портом B микроконтроллера, используя адреса:

#define PORT_DDR 0xB0 // PORTB Settings #define PORT_IN 0xB1 // Get PINB #define PORT_OUT 0xB2 // Set PORTB

Для программирования порта на вход, следует записать 0x00 по адресу 0xB0. Для получения состояния входов порта B нужно прочитать один байт по адресу 0xB1. Для программирования порта на выход записать 0xFF по адресу 0xB0. Чтобы установить все выходы порта в 1 надо записать 0xFF по адресу 0xB2.

Используя этот пример можно создавать свои специфические I2C Slave устройства на базе AVR микроконтроллеров. Например, модули сенсоров, дисплеев и т.д., интерфейс которых нужно унифицировать.

Успехов!

Поделитесь в социальных сетях:vKontakteFacebookTwitter
Напишите комментарий