Воскресенье, 2024-05-19
Сборник компьютерных технологий
Меню сайта
Категории раздела
My articles [30]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » Статьи » My articles

Реализация задержек на AVR

TCCR1B = TCCR1B_value; //В настройке таймера

 

const uint16_t static Timer1Presdcaler(void){ //256,1024
    switch(TCCR1B_value & 0b00000111){
        case 0b00000000: return 0UL;
        case 0b00000001: return 1UL;
        case 0b00000010: return 8UL;
        case 0b00000011: return 64UL;
        case 0b00000100: return 256UL;
        case 0b00000101: return 1024UL;
    }
    return 0;
}

 

#define Timer1Freq F_CPU/Timer1Presdcaler()
#define Tick2Wait(s) (Timer1Freq*s)

 

    uint32_t tmp=Tick2Wait(60*15); //так-то Tick2Wait() возвращается u32
    printf(" F_CPU= %u",tmp>>16);
    printf(" F_CPU= %u",tmp);
    
    CheckChargeMult = tmp / my_USHRT_MAX;//тип не мощнее uint16_t
    if (CheckChargeMult==0) {
        uint16_t currentTime = TCNT1;
        OCR1A = (my_USHRT_MAX-currentTime>tmp) ? tmp-(my_USHRT_MAX-currentTime) : tmp;
        
    }
    else CheckChargeTrigger=true;
    
    //Код overflow
    if (CheckChargeTrigger)
    if (CheckChargeMult==0) {
        uint16_t currentTime = TCNT1;
        OCR1A = (my_USHRT_MAX-currentTime>tmp) ? tmp-(my_USHRT_MAX-currentTime) : tmp;
        TIMSK1|=(1<<OCIE1A);//вкл OCR interaption//тут можно проверить, не активирована ли он уже (не занят ли кем-то) if (TIMSK1 & (1<<OCIE1A)) то занят
        }
    else CheckChargeMult--;


    //Код OCR
    //PortA=... делаем действие
    CheckChargeTrigger=false;
    TIMSK1&=~(1<<OCIE1A);//выкл OCR

 

Сделаем аналог delay_s, но с возможностью параллельно что-то делать в цикле, своего рода задача-бездействие. Для этого нам понадобится таймер. Возьмём Timer1 с его 16битным счётчиком TCNT1.

                //задержка на 2
               u16 alarm=GetOCR(Tick2Wait(2))-1;//-1 на случай, если TCNT1==alarm даже после исполнения нескольких команд (вдруг таймер ультра-слоупок), из-за этого погрешность в 1 тик.
                do{
                    externalSupplyLevelADC = adc_read_10bit(ADC_MUX_ADC6, ADC_VREF_AREF);
                    if (externalSupplyLevelADC<externalSupplyLowLevelADC) //смотрим АЦП
                    {};//что-то делаем
                }while(TCNT1!=alarm);

Погрешность 1 тик есть 1/частота таймера. Например, если частота таймера 3600 Hz (это медленный таймер), то погрешность в 1 тик - это 1/3600~0.28 ms.

Категория: My articles | Добавил: DungeonLords (2017-06-10)
Просмотров: 326
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright Forcer, Inc © 2024
    Бесплатный конструктор сайтов - uCoz