User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

c:i2c-scanner [2018-02-20 12:22] (current)
Line 1: Line 1:
 +=====I2C scanner on Atmel micro-controller=====
  
 +**//From the project "You bought for your son a microcontroller - program it yourself"//​** =) 
 +
 +The code can indicate which addresses are used by the I2C bus. I wrote it in one evening. For it I use embedded realization I2C driver for AVR.
 +
 +Fully source here [[https://​github.com/​onborodin/​arduino-tiny-shell]]
 +
 +{{:​c:​img_20180220_120100-2.jpg?​720|}}
 +
 +<code C twiscan-cut.c>​
 +...
 +
 +void twi_start(void) {
 +    TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
 +    while (!(TWCR & (1 << TWINT)));
 +}
 +
 +void twi_stop(void) {
 +    TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
 +    while ((TWCR & (1 << TWSTO)));
 +}
 +
 +void twi_write(uint8_t data) {
 +    TWDR = data;
 +    TWCR = (1 << TWINT) | (1 << TWEN);
 +    while (!(TWCR & (1 << TWINT)));
 +}
 +
 +uint16_t twi_scan(void) {
 +    uint8_t addr = 1;
 +    uint8_t str[4];
 +    outnl();
 +    while (addr < 127) {
 +        if((addr == 0x38) || (addr == 0x7c)) ​ {
 +            addr++;
 +            continue;
 +        }
 +        twi_start();​
 +        twi_write(addr << 1);
 +        if(TW_STATUS == TW_MT_SLA_ACK ) {
 +            outs("​0x"​);​
 +            int2str(addr,​ str, 3, 16);
 +            outl(str);
 +        }
 +        twi_stop();
 +        addr++;
 +    }
 +    i2c_init();
 +    return addr;
 +}
 +
 +uint16_t twi_scan_lcd(void) {
 +    uint8_t addr = 1;
 +    uint8_t str[4];
 +    lcd_command(LCD_CLEAR);​
 +    lcd_gotolr(0,​0);​
 +    lcd_print("#​ ");
 +    ​
 +    while (addr < 127) {
 +        if((addr == 0x38) || (addr == 0x7c)) ​ {
 +            addr++;
 +            continue;
 +        }
 +        twi_start();​
 +        twi_write(addr << 1);
 +        if(TW_STATUS == TW_MT_SLA_ACK ) {
 +            int2str(addr,​ str, 3, 16);
 +            lcd_print(str);​
 +            lcd_putchar('​ ');
 +        }
 +        twi_stop();
 +        addr++;
 +    }
 +    i2c_init();
 +    return addr;
 +}
 +
 +cdef_t cdef[] = {
 +    ...
 +    {.name = "​ts",​ .func = &​twi_scan,​ .argc = 0}
 +};
 +
 +uint8_t *prompt = "​READY>";​
 +
 +int main() {
 +
 +    fifo_iohook();​
 +    uart_init();​
 +    timer_init();​
 +
 +    i2c_init();
 +    lcd_init();
 +    wdt_init();
 +
 +    sei();
 +
 +    _delay_ms(1000);​
 +
 +    outl("​\r\nTINY SHELL V01");
 +    outs(prompt);​
 +
 +    lcd_print(prompt);​
 +
 +    uint8_t str[STR_LEN];​
 +    memset(str, 0, STR_LEN);
 +
 +    _delay_ms(1000);​
 +
 +    while (1) {
 +        twi_scan_lcd();​
 +
 +        uint8_t *s;
 +        s = str;
 +        while (fifo_gett(in,​ str, STR_LEN, '​\r'​) > 0) {
 +
 +            shell(str, cdef, sizeof(cdef) / sizeof(cdef[0]));​
 +            outs("​\r\n"​);​
 +            outs(prompt);​
 +        }
 +        _delay_ms(200);​
 +    }
 +}
 +</​code>​