I2C 100kHz

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Awatar użytkownika
Kulpina
Użytkownik
Posty: 2037
Rejestracja: 28 lip 2005, 16:57
Lokalizacja: Sanok
Kontakt:

I2C 100kHz

Post autor: Kulpina » 28 lut 2013, 1:02

Witajcie!

Piszę procedurę obsługi I2C na Atmedze taktowanej zegarem 1MHz.

Niby wszystko spoko - sama procedura to nietrudna sprawa, kłopot pojawia się inny - chcę uzyskać 100kHz prędkości transmisji (fCPU = 1MHz i nie chcę go zmieniać). Typowe procedury przy tym clocku oferują ~50kHz, a może i mniej (sprawdzam analizatorem stanów logicznych).

Napisałem taki cudaczny program w C:

Kod: Zaznacz cały

void i2c_write(uint8_t send) //write 170 - BIN10101010
{

uint8_t tablica[8];
tablica[0] = send & 0x80;
tablica[1] = send & 0x40;
tablica[2] = send & 0x20;
tablica[3] = send & 0x10;
tablica[4] = send & 0x08;
tablica[5] = send & 0x04;
tablica[6] = send & 0x02;
tablica[7] = send & 0x01;

if (tablica[0]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[1]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[2]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[3]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[4]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[5]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[6]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
if (tablica[7]) PORTC |= (1 << 4); else PORTC &= ~(1 << 4);
		PORTC |= (1 << 5); asm("nop"); asm("nop"); PORTC &= ~(1 << 5);
Jak można by zrobić to ładniej, inaczej?

Podpowiem, że jakiekolwiek funkcje void odpadają - skok do nich wnosi kolejne opóźnienie (mamy 10us na okres i2c, czyli 10 instrukcji procesora).

Chodzi mi o wszelkie, nawet najdziwniejsze porady.

Wiem też, że powyższy kod jest kuriozalny, to eksperyment, tego nie musicie komentować :mrgreen:

Pozdrawiam
kulpina

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 28 lut 2013, 16:49

Po to właściwie jest sprzętowy kontroler I²C. Programowo cięzko bedzie ci uzyskać 100KHz, bo szybkość ta będzie ci pływać, wystarczy jakiekolwiek przerwanie.

ODPOWIEDZ