usart - передача данных по последовательному порту USART
В примере usart демонстрируется использование нескольких классов:
- Класс, реализующий функции 16-битного таймера-счётчика 1, используется для отсчёта времени задержки мигающего светодиода (как в примере timer).
- Вспомогательный класс потенциометра Pot (файл misc/pot.h) используется для управления временем задержки мигающего светодиода.
- Класс, реализующий функции 8-битного таймера-счётчика 0, используется для отсчёта интервалов между передачами показаний потенциометра по последовательному порту USART.
- Класс, реализующий функции интерфейса последовательного порта USART, используется для передачи показаний потенциометра.
Данные передаются как шестнадцатиричные числа в строковом режиме (одно число на строку).
Исходный код примера:
/**
* usart.cpp
*
* VE_AVR_Library ADC Control LED Blinking Example.
*
* Created on: 11.05.2012
* Author: andrey
*/
#include <ve_avr.h>
#include <misc/ve_led.h>
#include <misc/ve_pot.h>
#define LED DEV_GPIOB, 7 // Светодиод LED подключен к выводу PB7 микроконтроллера
#define LED_POT_CHANNEL AnalogMux::CH_ADC0 // Потенциометр LED_POT_CHANNEL подключен к выводу ADC0
// микроконтроллера
volatile bool bLedOn = false; // Флаг состояния светодиода LED (false - выключен)
volatile uint16_t potValue; // Состояние потенциометра, умноженное на 64
volatile uint8_t bSendPotValue = 16; // Счётчик отправки сообщений от состоянии потенциометра по USART
char hexChar(uint8_t hex); // Функция перевода числа [0..15] в шестнадцатеричный формат
int main()
{
DEV_POWER.adcOn(); // Включить питание АЦП
DEV_POWER.timer1On(); // Включить питание таймера-счётчика 1
DEV_POWER.usart0On(); // Включить питание USART 0
led::setup(LED); // Предварительная настройка вывода светодиода LED
Pot pot;
pot.setup(LED_POT_CHANNEL); // Предварительная настройка канала АЦП LED_POT_CHANNEL
potValue = pot.getValue() << 6; // Первый опрос потенциометра
// Предварительная настройка таймера-счётчика 1
DEV_TIMER1.setClockSelect(TimerW::Prescaler_64); // Частота равна CLKIO/64 (например 16 МГц / 64 = 250 кГц)
DEV_TIMER1.setWaveGenMode(TimerW::FastPWM_OCRA); // Режим быстрого ШИМ со сравнением TCNT1 == OCR1A
DEV_TICTRL1.outCompIntEnableA(); // Разрешить прерывание сравнения (TIMER1_COMPA_vect)
// Предварительная настройка таймера-счётчика 0
DEV_TIMER0.setClockSelect(Prescaler0::Prescaler_1024); // Частота равна CLKIO/1024
// (например 16 МГц / 1024 = 15625 Гц)
DEV_TIMER0.setWaveGenMode(Timer0::Normal); // Режим простого счёта
DEV_TICTRL0.overflowIntEnable(); // Разрешить прерывание по переполнению
// (TIMER0_OVF_vect)
DEV_USART0.setBaudRate(57600); // Скорость передачи данных 57600 бод (формат по умолчанию 8N1)
DEV_USART0.transmitterEnable(); // Разрешить передачу данных
enableInterrupts(); // Разрешить прерывания
while(true) {
potValue = pot.getValue() << 6; // Опрос потенциометра
if (bLedOn) // Если светодиод LED должен светиться
led::on(LED); // включить светодиод LED
else // и наоборот
led::off(LED);
if (bSendPotValue == 0) { // Если пора отправить данные по USART
DEV_USART0 << hexChar(potValue >> 12); // отправить состояние потенциометра, умноженное на 64
DEV_USART0 << hexChar(potValue >> 8); // в шестнадцатеричном формате
DEV_USART0 << hexChar(potValue >> 4);
DEV_USART0 << hexChar(potValue);
DEV_USART0 << "\r\n"; // Одно данное на строку
bSendPotValue = 16; // Обновить счётчик отправки сообщений
}
}
}
ISR(TIMER1_COMPA_vect) // Обработчик прерывания сравнения таймера-счётчика 1
{
DEV_TIMER1.setOutputCompareA(potValue); // Установить интервал времени до следующего прерывания
bLedOn = ! bLedOn; // Переключить состояние светодиода LED через флаг состояния
}
ISR(TIMER0_OVF_vect) // Обработчик прерывания переполнения таймера-счётчика 0
{
if (bSendPotValue > 0) // Уменьшить текущее значение счётчика отправки сообщений на единицу
--bSendPotValue; // т.о. при частоте CLKIO = 16 МГц сообщения будут отправляться
// с частотой (15624 Гц / 256) / 16 = 3 Гц
}
char hexChar(uint8_t hex) // Функция перевода числа [0..15] в шестнадцатеричный формат
{
char ret = (hex & 0x0F);
return (ret <= 9) ? (ret + '0') : (ret + 'A'- 10);
}
Предыдущий пример: timer - прерывания от таймера.
Следующий пример: EEPROM - чтение и запись данных в память EEPROM.
- blink -- мигающий светодиод
- button -- обработка нажатий кнопки
- adc -- считывание значения напряжения потенциометра
- timer -- прерывания от таймера
- usart -- передача данных по последовательному порту USART
- EEPROM -- чтение и запись данных в память EEPROM
- LEDfade - управление яркостью светодиода с помощью ШИМ
Автор: Андрей Шаройко <vanyamboe@gmail.com>