Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Микропроцессорные системы. Применение микроконтроллеров семейства AVR для управления внешними устройствами

.pdf
Скачиваний:
1
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
61
/** * @brief Обращение к таймерам – только через этот метод! * * @return cSoftTimers& */ static cSoftTimers& instance();
private: /** * @brief Вызывается аппаратным прерыванием * * @return void */ friend void irq_1ms_static();
/** * @brief список таймеров */ dscTimer m_Timers[maxTimers];
/** * @brief Показывает, что обработчик выполняется. */ bool m_HandlerRunning;
/** * @brief Вызывается каждую миллисекунду * * @return void */ void irq_1ms();
/** * @brief Инициализация аппаратного таймера * * @return void */ void hwIrqInit();
};
#endif // CSOFTTIMERS_H
// Файл cSoftTimers.cpp #include <avr/interrupt.h>
62
#include <avr/io.h> #include "cSoftTimers.h"
cSoftTimers::cSoftTimers() {
m_HandlerRunning=false;
for( int8_t i=0; i<maxTimers; i++){ delTimer(i); }
}
void cSoftTimers::irq_1ms() {
for(auto &i:m_Timers){ i.counter=(i.counter!=0)?(i.counter-1):0; }
if(!m_HandlerRunning){ for(auto &i:m_Timers){ if((i.counter == 0) && (i.period !=0 ) && (i.proc) ){ m_HandlerRunning=true; i.counter = i.period; i.proc(); m_HandlerRunning=false; } } }
}
cSoftTimers::idT cSoftTimers::addTimer ( uint16_t period, cSoft-
Timers::timerProc handler ) {
idT r(0);
if( period == 0 ){ return(-1); }
for(auto &i:m_Timers){ if(i.period == 0){ i.counter = i.period = period; i.proc = handler; break; } r++;
63
}
if(r>=maxTimers){ return(-1); }
return(r);
}
void cSoftTimers::delTimer ( cSoftTimers::idT id ) {
if((id<0)||(id>=maxTimers)){ return; } m_Timers[id]={};
}
void cSoftTimers::rstTimer ( cSoftTimers::idT id ){
if((id<0)||(id>=maxTimers)){ return; } m_Timers[id].counter = m_Timers[id].period;
}
void irq_1ms_static() { cSoftTimers::instance().irq_1ms(); }
ISR ( TIMER0_COMP_vect, ISR_NOBLOCK ) { irq_1ms_static(); }
// прерывания 1 миллисекунда // #if F_CPU == 1000000UL #define T0PSC ((0<<CS02) | (1<<CS01) | (0<<CS00)) #define T0OCR (F_CPU/(8UL*1000UL)) // #elif F_CPU == 2000000 #define T0PSC ((0<<CS02) | (1<<CS01) | (0<<CS00)) #define T0OCR (F_CPU/(8000UL)) // #elif F_CPU == 8000000 #define T0PSC ((0<<CS02) | (1<<CS01) | (1<<CS00))
64
#define T0OCR (F_CPU/(64000UL)) #endif
void cSoftTimers::hwIrqInit(){
// Режим таймера 1 TCCR0A = T0PSC | /* prescaler = 8 */ (1 << WGM01) | (0 << WGM00) | /* CTC mode */ (0 << COM0A0) | (0 << COM0A0) | /* output not use */ (0 << FOC0A); /* Force not use */ OCR0A= T0OCR; TIFR0= (1<<OCF0A); TCNT0=0; TIMSK0= (1<<OCF0A);
}
void cSoftTimers::start(){ hwIrqInit(); }
void cSoftTimers::stop(){
TIMSK0=0; OCR0A=0;
}
static cSoftTimers softTimers; cSoftTimers& cSoftTimers::instance(){ return(softTimers); }
65
Приложение В. Исходные тексты программной реализации
циклических буферов ( CycloBuf.h и CycloBuf.cpp )
// CycloBuf.h #ifndef CYCLOBUF_H #define CYCLOBUF_H #include <stdint.h>
/** * @brief Циклический буфер (не более 255 байт) */ class CycloBuf{ public:
/** * @brief Конструктор */ CycloBuf();
/** * @brief Инициализировать буфер * * @param buffer – указатель на буфер * @param size – размер буфера * @return void */ void init(uint8_t* buffer, uint8_t size);
/** * @brief – очистить буфер * * @return void */ void clear();
/** * @brief – проверить, пуст ли буфер * * @return bool */ bool isEmpty();
/** * @brief Поместить байт в буфер * * @param c – байт * @return bool – true – символ помещен в буфер */ bool putByte(uint8_t c);
66
/** * @brief Считать символ из буфера * * @param c – считываемый символ * @return bool – true – символ считан из буфера */ bool getByte(uint8_t& c);
private: /** * @brief Указатель на буфер */ uint8_t* m_Buffer;
/** * @brief Размер буфера */ uint8_t m_Size;
/** * @brief Голова */ uint8_t m_Begin;
/** * @brief Хвост */ uint8_t m_End;
}; #endif // CYCLOBUF_H
// CycloBuf.cpp #include "CycloBuf.h"
CycloBuf::CycloBuf () {
m_Buffer=nullptr; m_Size=0; clear();
} void CycloBuf::init ( uint8_t* buffer, uint8_t size ){
m_Buffer=buffer; m_Size=size; clear(); }
67
void CycloBuf::clear(){ m_Begin=m_End=0;
} bool CycloBuf::isEmpty(){
if(m_Begin==m_End){ return(true); } return(false);
} bool CycloBuf::putByte ( uint8_t c ){
uint8_t e=m_End+1; if(e>=m_Size){ e=e-m_Size; }
if(e==m_Begin){ return(false); }
m_Buffer[ m_End ] = c; m_End=e;
return(true);
}
bool CycloBuf::getByte ( uint8_t& c ){
if( m_Begin !=m_End ){ c = m_Buffer[ m_Begin++ ]; } else{ return(false); }
if(m_Begin>=m_Size){ m_Begin=m_Begin-m_Size; }
return(true); }
68
Приложение Г. Исходные тексты программной реализации
драйвера UART ( cUSART.h и cUSART.cpp )
// cUSART.h #ifndef CUSART_H #define CUSART_H
#include <stdint.h> #include "CycloBuf.h"
class cUSART{ public:
/** * @brief Конструктор */ cUSART();
/** * @brief Установить Скорость * @param baud – скорость (19200 и др) * @return void */ void setBaud(uint16_t baud);
/** * @brief Начать использование USART * @return void */ void start();
/** * @brief Запустить передачу символа * @param c – символ * @return uint8_t – 0 – символ не передан, 1 – символ передан */ uint8_t putc(char c);
/** * @brief Запустить передачу строки * @param s – строка * @return uint8_t – сколько байт удалось засунуть в буфер */
69
uint8_t puts(const char* s);
/** * @brief Запустить передачу вектора байт * @param s – вектор * @param size – размер вектора * @return uint8_t – сколько байт удалось засунуть в буфер */ uint8_t put(const char* s, uint8_t size);
/** * @brief Cчитать строку из буфера * @param s – буфер для считывания строки * @param size – размер буфера * @return uint8_t – сколько байт реально считано */ uint8_t get(char* s, uint8_t size);
/** * @brief Запустить передачу строки из PROGMEM * @param s – строка * @return uint8_t – сколько байт удалось засунуть в буфер */ uint8_t putsF(const char* s);
/** * @brief Синглтон * @return cUSART& */ static cUSART& instance(); private: enum Constants{ // Скорость по умолчанию defaultBaudRate = 19200, // Бит приемника bitRx = 0, // Бит передатчика bitTx = 1, // Размеры буферов bufSize=0x80 };
/** * @brief Буфер передатчика
70
*/ uint8_t m_TxB[Constants::bufSize]; CycloBuf m_TxBuffer;
/** * @brief Буфер Приемника */ uint8_t m_RxB[Constants::bufSize]; CycloBuf m_RxBuffer;
/** * @brief Инициализация аппаратной части * @return void */ void hwInit();
void rx_complete();
void tx_complete();
friend void static_rx_complete();
friend void static_tx_complete();
};
#endif // CUSART_H
// cUSART.cpp #include "cUSART.h" #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h>
cUSART::cUSART(){
m_RxBuffer.init(m_RxB, sizeof(m_RxB)); m_TxBuffer.init(m_TxB, sizeof(m_TxB));
setBaud( Constants::defaultBaudRate );
}
void cUSART::setBaud ( uint16_t baud ){
uint32_t ub= ( (F_CPU >> 3)/baud)-1; UBRR = (ub & 0xFFFF);
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]