-
-
Save rmnk/86cbd56270eb316552df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define F_CPU 1000000UL | |
#include <stdint.h> | |
#include <avr/io.h> | |
#include <util/delay.h> | |
#include <avr/cpufunc.h> | |
#define A 0x80 | |
#define B 0x20 | |
#define C 0x08 | |
#define D 0x02 | |
#define E 0x01 | |
#define F 0x40 | |
#define G 0x10 | |
#define I2C_PORT PORTC | |
#define I2C_DDR DDRC | |
#define I2C_PIN PINC | |
#define SDA 4 | |
#define SCL 5 | |
uint8_t digits[16] = { | |
A | B | C | D | E | F, //0 | |
B | C, //1 | |
A | B | D | E | G, //2 | |
A | B | C | D | G, //3 | |
B | C | F | G, //4 | |
A | C | D | F | G, //5 | |
A | C | D | E | F | G, //6 | |
A | B | C, //7 | |
A | B | C | D | E | F | G, //8 | |
A | B | C | D | F | G, //9 | |
A | B | C | E | F | G, //a | |
C | D | E | F | G, //b | |
A | D | E | F, //c | |
B | C | D | E | G, //d | |
A | D | E | F | G, //e | |
A | E | F | G //f | |
}; | |
void | |
set_led_digit(uint8_t id, uint8_t value) | |
{ | |
DDRD = 0xff; | |
DDRB |= 1 << id; | |
PORTB &= 0xf8; | |
PORTB |= 1 << id; | |
PORTD = digits[value]; | |
} | |
uint8_t | |
i2c_get_sda() | |
{ | |
return (I2C_PIN >> SDA) & 0x01; | |
} | |
uint8_t | |
i2c_get_scl() | |
{ | |
return (I2C_PIN >> SCL) & 0x01; | |
} | |
void | |
i2c_set_scl(const uint8_t value) | |
{ | |
do { | |
if (value) { | |
I2C_DDR &= ~(1 << SCL); | |
} else { | |
I2C_DDR |= 1 << SCL; | |
} | |
} while (i2c_get_scl() != value); | |
} | |
void | |
i2c_set_sda(const uint8_t value) | |
{ | |
do { | |
if (value) { | |
I2C_DDR &= ~(1 << SDA); | |
} else { | |
I2C_DDR |= 1 << SDA; | |
} | |
} while (i2c_get_sda() != value); | |
} | |
void | |
i2c_start() | |
{ | |
/* pull down SDA while SCL is up */ | |
i2c_set_sda(1); | |
i2c_set_scl(1); | |
i2c_set_sda(0); | |
} | |
void | |
i2c_stop() | |
{ | |
/* release SDA while SCL is up */ | |
i2c_set_sda(0); | |
i2c_set_scl(1); | |
i2c_set_sda(1); | |
} | |
/* returns ACK bit */ | |
uint8_t | |
i2c_write(uint8_t byte) | |
{ | |
int8_t bit_no; | |
for (bit_no = 7; bit_no >= 0; bit_no--) { | |
i2c_set_scl(0); | |
/* put next bit on SDA */ | |
i2c_set_sda((byte >> bit_no) & 0x01); | |
i2c_set_scl(1); | |
} | |
/* release SDA; let slave to be able to change it */ | |
i2c_set_sda(1); | |
i2c_set_scl(0); | |
i2c_set_scl(1); | |
/* get slave ACK bit */ | |
return i2c_get_sda(); | |
} | |
uint8_t | |
i2c_read(uint8_t ack) | |
{ | |
/* release SDA; let slave to be able to change it */ | |
i2c_set_sda(1); | |
uint8_t byte = 0; | |
int8_t bit_no; | |
for (bit_no = 7; bit_no >= 0; bit_no--) { | |
i2c_set_scl(0); | |
i2c_set_scl(1); | |
/* get next bit */ | |
byte |= i2c_get_sda() << bit_no; | |
} | |
i2c_set_scl(0); | |
/* set ACK bit */ | |
i2c_set_sda(ack); | |
i2c_set_scl(1); | |
return byte; | |
} | |
int | |
main() | |
{ | |
I2C_PORT &= ~((1 << SDA) | (1 << SCL)); | |
//const uint8_t eeprom_i2c_addr = 0b10100000; | |
const uint8_t eeprom_i2c_addr = 0xa0; | |
const uint16_t eeprom_memory_addr = 0x0000; | |
const uint8_t eeprom_memory_value = 0x42; | |
uint8_t ack = 0; | |
i2c_start(); | |
ack |= i2c_write(eeprom_i2c_addr); | |
ack |= i2c_write((uint8_t) (eeprom_memory_addr >> 8)) << 1; | |
ack |= i2c_write((uint8_t) eeprom_memory_addr) << 2; | |
ack |= i2c_write(eeprom_memory_value) << 3; | |
i2c_stop(); | |
while(1) { | |
set_led_digit(0, ack); | |
_delay_ms(1); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment