Интерфейс I2C -- TWI

I2C (IIC -- Inter-Integrated Circuit; TWI -- Two-Wire Interface) -- интерфейс для межпроцессорной коммуникации с использованием одной двунаправленной линии данных (SDA) и одной синхронизирующей линии (SCL).

В ATmega8A выход SDA располагается на пине PC4, а SCL -- на пине PC5.

TWI -- интрфейс передачи данных, основанный на прерываниях. Это значит, что при получении очередного блока данных, при возникновении ошибок или при других условиях генерируется соответствующее прерывание.

Каждое устройство имеет адрес. Передача данных осуществляется последовательно от ведущего (Master) устройства к ведомому (Slave) между сигналами начала (START) и окончания (STOP) передачи. Сначала передается адрес устройства-приемника, затем (при условии согласия устройства принять данные / ответить на запрос) начинается собственно передача данных пакетами.

Линии SDA и SCL должны быть подняты (pulled up) над уровнем земли (GND) вручную при помощи резистроров (pull-up resistors).

Передаваемые по линии данные обрабатываются программами, записанными на общающиеся устройства.

SPI

SPI (Serial Peripherial Interface) -- четырехпроводной интерфейс последовательной передачи данных (MISO -- Master In Slave Out, MOSI -- Master Out Slave In, SCK -- Serial Clock, SS -- Slave Select). В литературе иногда приводится как трехпроводной (в число линий не включается управляющий SS-порт).

SPI и программирование памяти

Осуществляется двумя путями, один из которых -- SPI.

При программировании линия SS не используется. Для инициализации процедуры программирования необходимо на вход RESET подать логический 0. Программатор (компьютер: IAR EW) сам будет подавать команды по программированию flash и EEPROM.

Интерфейс RS-232 -- USART

ATmega8A не имеет встроенных средств отладки (например, JTAG). Поэтому отладочный вывод реализуется через один из последовательных интерфейсов. Предлагается для этого воспользоваться RS-232 на базе USART.

USART -- последовательный интерфейс асинхронной / синхронной передачи данных в режиме полного дуплекса или в режиме master-slave. RS-232 -- асинхронный USART в режиме полного дуплекса, оптимизированный для передачи данных на относительно большие расстояния.

Реализуется через два последовательных вывода RxD и TxD -- передатчика и приемника. Параметры передачи (baud rate, формат кадра) задаются (одинаковыми) на приемной и передающей стороне.

Пример настройки USART

Для настройки USART требуется произвести инициализацию параметров приема-передачи (одинаковую на обоих концах приема-передачи), а конкретно установить формат фрейма и скорость передачи.

Данные в USART передаются фреймами. Наиболее распространенный формат фрейма следующий:

S 0 1 2 3 4 5 6 7 P St

  1. S -- 1 стартовый бит
  2. (n) -- 8 битов данных
  3. P -- 1 паритетный бит
  4. St -- 1 завершающий бит

Для передачи могут быть установлены различые форматы фреймов, в т.ч. и 5-битные, 9-битные, с двумя завершающими битами и т.д.

Также существует набор стандартных скоростей передачи (baud rate-ов), например 4800bps, 9600bps и т.д. При настройке скоростей следует учитывать значение частоты осциллятора микроконтроллера, поскольку на некоторых частотах некоторые скорости либо не получаются вовсе, либо имеют большую погрешность.

В качестве примера приведена настройка USART для работы на прерываниях. Обычно в таких случах дописывается дополнительный код, отвечающий за буферизацию данных (линейные и кольцевые буферы). Он здесь не приводится.

/* Macro Definitions */
#define FOSC      1000000 /* Oscillator frequency (e.g. 1MHz)    */
#define BAUD_RATE 4800    /* USART Baud Rate      (e.g. 4.8kbps) */

/* RX Complete Interrupt Handler */
#pragma vector=USART_RXC_vect
__interrupt void usart_rxc_interrupt_handler()
{
    /* Must read the data anyway
       in order to suppress unnecessary series of interrupts */
    byte udr = UDR;

    // TODO: body here
}

/* Data Register Empty Interrupt Handler */
#pragma vector=USART_UDRE_vect
__interrupt void usart_udre_interrupt_handler()
{
    // TODO: body here

    if (/* no more data to be sent */)
    {    
        /* Must disable interrupts manually
           in order to suppress unnecessary series of interrupts */
        UCSRB &= ~(1 << UDRIE); /* Disable Data Reg. Empty interrupt */
    }
}

void usart_init()
{
    /* Don't use 2x speed */
    const int ubrr = FOSC/16/BAUD_RATE-1;
    /* Set baud rate */
    UBRRH = (unsigned char) (ubrr>>8);
    UBRRL = (unsigned char) ubrr;
    /* Enable receiver and transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Set frame format: 8data, 1stop bit, parity odd bit */
    UCSRC = (1<<URSEL)|(3<<UCSZ0)|(3<<UPM0);
     /* Enable RX Complete and Data Reg. Empty interrupt */
    UCSRB |= (1<<RXCIE)|(1<<UDRIE);
}

void main()
{
    usart_init();

    __enable_interrupt();

    // TODO: body here
}

С USART можно работать и в режиме ожидания ввода/вывода. Тогда разрешение прерываний и код обработки прерываний не требуется. Все данные считываются из и записываются непосредственно в регистр UDR. Для ожидания окончания чтения / записи используются флаги, устанавливаемые интерфейсом USART.

Пример организации чтения / записи данных в блокирующем режиме (без прерываний), взятый из даташитов:

void USART_Transmit( unsigned char data )
{
    /* Wait for empty transmit buffer */
    while( !( UCSRA & (1 << UDRE)) )
        ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

unsigned char USART_Receive( void )
{
    /* Wait for data to be received */
    while( !(UCSRA & (1 << RXC)) )
        ;
    /* Get and return received data from buffer */
    return UDR;
}

results matching ""

    No results matching ""