Лекция 3. PWM. UART
.pdfФреймы
●Фрейм – это фрагмент данных, предназначенных для передачи по какому-либо интерфейсу и имеющий определённый формат
●Протокол UART устанавливает следующий стандарт на формат пакета:
–Первым следует стартовый бит
–Далее 5, 6, 7, 8 или 9 бит данных
–Может присутствовать бит контроля чётности (если включен – возможны 2 режима: even или odd)
–В конце обязательно следуют 1 или 2 стоповых бита
Формат посылки
Регистры I/O для USARTа
●UDRn – регистр данных
●UCSRnA – регистр состояний A, биты:
–RXC – устанавливается когда есть непрочтённые данные
–TXC – устанавливается когда данные ушли из UDRn
–UDRE – устанавливается когда UDR готов принимать данные для дальнейшей передачи
●UCSRnB – регистр состояний B, биты:
–RXCIEn – вкл. прерывание "приём завершён"
–TXCIEn – вкл. прерывание "передача завершена"
–UDRIE – вкл. прерывание по готовности дальше отправлять
–TXEN – вкл. UART на передачу
–RXEN – вкл. UART на приём
Регистры I/O для USARTа
●UCSRnC – регистр управляет форматом пакета и режимом работы (синхронный/асинхронный)
●UBRRnL и UBRRnH – регистры для установки скорости передачи (Baud rate)
Пример работы с UART
void UARTSend(uint8_t data) {
/* ждём пока не освободится регистр данных */ while(!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
uint8_t UARTGet() {
/* Ждём пока в буфере не появятся непрочтённые данные */ while(!(UCSR0A & (1<<RXC0)));
return UDR0;
}
/* Устанавливем Baud rate : UBRR_VALUE = F_CPU/(16*Baud) - 1 */ UBRR0=UBRR_VALUE;
/* Разрешаем приём + передачу */ UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Формат пакета: 8 бит данных, без контроля чётности */ UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
Прерывания от UART
●Приведённые функции обладают следующим недостатком: они ждут в пустом цикле while пока закончится приём или передача
●Можно сделать приём или передачу без ожидания, для чего используются прерывания (RXComplete, TXComplete и Usart Data Register Empty)
Пример с прерываниями
#define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #define BAUD 9600
#define UBRR_VAL F_CPU/16/BAUD-1 void UARTInit() {
UBRR0=UBRR_VAL;
UCSR0B = (1<<RXEN0)|(1<<TXEN0); UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}
volatile uint8_t buf; ISR(USART_RX_vect) {
buf = UDR0; PORTB ^= (1<<PB5); UCSR0B |= (1<<UDRIE0);
}
ISR(USART_UDRE_vect) {
UDR0 = buf; UCSR0B &= ~(1<<UDRIE0);
}
int main(void) { DDRB = (1<<DDB5); UARTInit();
UCSR0B |= (1<<RXCIE0); sei();
while(1) {;}
}