Обсуждаем контроллеры компании Atmel.
Ответить

Re: Таймеры/счётчики в AVR

Сб янв 04, 2014 16:08:08

Да..
Код:
TCCR0B = TCCR0B|(1<<CS01)|(0<<CS00);//установка прескалера таймера = 1/8частоте.(т.к. на авывод надо 2 такта.. нам этого хватит)

У Евстифеева немного не внятно про сие таинство описано, а на басурманском и подавно.

Re: Таймеры/счётчики в AVR

Вс янв 12, 2014 12:04:34

Покритикуйте, пожалуйста, кот.
Задача: по кнопке (sbic PinD,4) ксорится порт Б и переключаются светодиоды, но при этом система должна возвращаться из переключенного положения обратно через n секунд, если оставлена в переключенном положении

По задумке программа крутится в цикле, ждет кнопку
По кнопке сбрасывается таймер, переключаем
По прерыванию таймера отсчитывается нужное кол-во секунд, далее проверяется нужный бит порта Б, и если он не в том положении (1), то порт ксорится аналогично нажатию кнопки и таким образом переключается обратно.
Если нужное кол-во секунд не достигнуто или бит сброшен, выходим из прерывания без действия.

Так-то все работает. Переключается обратно как надо.
Баг в том, что при работе светодиод едва уловимо подмигивает без нажатия кнопки.
По частоте вроде как совпадает со срабатыванием прерывания.
Но ведь там стоят досрочные переходы по условию?

Спойлер
Код:
   .include "tn2313def.inc"
    .list

   

   .cseg
   .org 0
   rjmp RESET ; Reset Handler
   .org OVF0addr
   rjmp OVF0Handler ; TIMER0 overflow

;

OVF0Handler:
     cli

    inc r23
    cpi r23,19
     brne ExitInt

     sbis PinB,5
     rjmp ExitInt

    ldi r21,0b00100100
     in r20, PORTB
      eor r20, r21  ;
    out PORTB,r20
    nop
    nop   

     
ExitInt:  sei    
          reti


   
RESET:
      ldi r16, low(RAMEND);    Main program start
       out SPL,r16 ;         Set Stack Pointer to top of RAM


      ldi r16, 0b00001000   ; set up ports
      out DDRD,r16
      nop

      ldi r16, 0b01110111
      out PORTD,r16 ; PULL
      nop


      ldi r16, 0b11111111  ;
      out DDRB,r16
      nop
      ldi r16, 0b00000100   
      out PORTB,r16
      nop

               ; TIMER0 INIT
      ldi r16, 0b00001101 ; PRESCALER
      out TCCR0B,r16
      
      ldi r16, 0b00000000

      ldi r16, 0b11111111
      out TIMSK,r16


      sei

      clr r20
      clr r21
      clr r22
      clr r23               



         
main_cycle:
         
   sbic PinD,4
   rjmp main_cycle
   rcall Delay
        sbic PinD,4
        rcall Togg8
        rjmp main_cycle
   

      
Togg8:
   
    clr r23
    out TCNT0,r23
   

   ldi r21,0b00100100
    in r20, PORTB
   eor r20, r21 
   out PORTB,r20
   nop
   nop   


   rjmp main_cycle




   
   
Delay:
         
; ----------
        ldi r17,0
          ldi r18,100
          ldi r19,1

Loop:     dec r17
          brne Loop

          dec r18
          brne Loop

          dec r19
          brne Loop

      
; ----------
        ldi r17,0
          ldi r18,200
          ldi r19,1

Loop1:     dec r17
          brne Loop1
          dec r18
          brne Loop1
          dec r19
          brne Loop1
          ret   

Atmega8 как привязать таймер 1 к выходу компаратора?

Вс фев 09, 2014 23:24:50

Atmega8 как привязать таймер 1 к выходу компаратора?

http://www.atmel.com/images/atmel-8159- ... asheet.pdf

есть в даташите "17.6.3 Using the Input Capture Unit" - написано в общих чертах, но нет никаких точных указаний в каких регистрах какие биты надо выбрать.
Последний раз редактировалось Gudd-Head Пн фев 10, 2014 10:54:03, всего редактировалось 1 раз.
Причина: Сюда перенёс

Re: Atmega8 как привязать таймер 1 к выходу компаратора?

Пн фев 10, 2014 15:19:08

И возникает вопрос - какой смысл привязывать выход компаратора к таймеру. Какие это дает преимущества.

Ведь изменение выхода компаратора может вызывать собственные прерывания и соответственно там писать программку которая возьмет число из регистра таймера на тот момент.

Re: Таймеры/счётчики в AVR

Пн фев 10, 2014 15:24:04

Да, совершенно верно, но таким способом таймер можно перевести в режим аппаратного захвата значения таймера.

Re: Atmega8 как привязать таймер 1 к выходу компаратора?

Пн фев 10, 2014 15:25:53

amd9800 писал(а):Какие это дает преимущества.

Насколько я понял, в ICRn будет именно то число, которое было в момент возникновения прерывания от компаратора.
А то пока программа скакнёт на вектор обработки (4 такта), пока на саму обработку (2 такта), пока считает значение таймера...

Re: Atmega8 как привязать таймер 1 к выходу компаратора?

Пн фев 10, 2014 15:31:29

Если честно хочу сделать программку которая считает заряд конденсатора до определенного напряжения.
Заряжается конденсатор стабилизированным током.

тестирую но результаты не впечатляют. Если измеряю время заряда 1 микрофарад конденсатора получаю 72 такта. Измеряю 2 микрофарад получаю 84 такта. 3 микрофарад - 96 тактов. Получается 12 тактов на микрофарад.

Но если ставлю 0,01 микрофарада то получаю 57 тактов. И не могу понять логику - почему так происходит?

ICR1 - в этот регистр записывается текущее состояние счётчика при появлении активного входного сигнала на выводе ICP (бит 0 порта B)

Вот я не заметил ICR1. Останавливал таймер и читал TCNT1. - это и есть разница
Последний раз редактировалось amd9800 Пн фев 10, 2014 15:57:24, всего редактировалось 3 раз(а).

Re: Atmega8 как привязать таймер 1 к выходу компаратора?

Пн фев 10, 2014 15:41:06

amd9800 писал(а):И не могу понять логику - почему так происходит?

Встроенный компаратор — гумно. У вас опора внешняя или встроенная? Попробуйте подать внешнюю.

Re: Atmega8 как привязать таймер 1 к выходу компаратора?

Пн фев 10, 2014 15:43:26

Я использую внешнюю опору. Но пока все тесты в протеусе. Так что даже если что то гумно то все ровно пока работает в идеальных условиях.

Re: Таймеры/счётчики в AVR

Пн фев 10, 2014 15:44:18

Цитата правильная, но неполная. Вот пример подключения компаратора в режим захвата значения таймера1

Re: Таймеры/счётчики в AVR

Пн фев 10, 2014 15:49:27

пока результаты в протеусе радуют - линейная зависимость (емкость время заряда) прекрасная.

Re: Таймеры/счётчики в AVR

Пн фев 10, 2014 17:15:37

Схему опубликуйте.. я чет не врублюсь :(

Re: Таймеры/счётчики в AVR

Пн фев 10, 2014 22:56:07

Ну такая схемка еще в разработке.
СпойлерИзображение
Вложения
PSUtester2.PNG
(197.97 KiB) Скачиваний: 1175

Re: Таймеры/счётчики в AVR

Вт фев 11, 2014 01:05:28

нда... лучше отдельно компаратор собрать, на "инструментальных" ОУ, и задействовать INT0,1.
Оно в порядке очередности раньше срабатывает...

Из собственной скудной практики наступал на грабли:
Для тини 2313 регистр ASCR, бит ACIC (2ой бит) но цепляется оно к счетчику T1. а не Т0.

Re: Таймеры/счётчики в AVR

Пн фев 24, 2014 22:29:11

Доброго всем времени суток.
Подскажите по таймеру1. Мучаюсь с обработкой значения регистра TCNT1 счётчика 1. Он считает внешние приходящие имульсы.
Количество подсчитанных ипульсов требуется вывести на экран LCD/
Регистр вмещает в себя 2^16, но после досчитывания до 32768, начинает считать в обратную сторону и появляется знак "-".
Но мне необходимо чтобы на экранчик выводилось число 65130 и т.д. до переполнения регистра. Но на экранчике появляется знак "-".
Пробовал задвать переменную в которую счёт производится как unsigned, но это не дало резульата. Также пробовал задать условие, Что если появляется знак "-" то надо из 2^16 вычесть текущее значение счётчика (которое со знаком "-"). Но результать всё тот же, LCD отображет сначала положительное число до 2^15, затем появляется знка "-" и отображаемое число подсчитанных имульсов уменьшается до 0.
Код прошивки:
СпойлерChip type : ATmega8
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*******************************************************/

#include <mega8.h>
#include <stdio.h>
// Alphanumeric LCD functions
//#include <alcd.h>
#include <alcd_ks0073.h>

// Declare your global variables here
int a;
char lcd_buffer[33];

// Timer1 overflow interrupt service routine

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
PORTD.0=1;
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=Out Bit2=In Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (1<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=0 Bit2=T Bit1=T Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Timer/Counter 1 initialization
// Clock source: T1 pin Rising Edge
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<TOIE0);

lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
{
a=TCNT1;
// if (a<0)
// {
// a=65536+a;
// }

lcd_clear();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%i",a);
lcd_puts(lcd_buffer);
}
}


Программу работы проверяю в протеусе.

Re: Таймеры/счётчики в AVR

Пн мар 03, 2014 12:58:38

Товарищи коты, прошу помощи по ШИМу в attiny13а. Хочу сделать fastPWM. Вроде бы все настроил, но нога от таймера дергаться не желает. Хотя если дергаю ее процессором - поддается. Т.е. КЗ нигде нету и нога живая. Подскажите пожалуйста, чего не хватает? :)

Код:
   DDRB   = CE_3V | CE_5V | PWM_5V;         // pwm_5v - нога на ШИМ. настроена как выход
...........
   while(1)                                  
   {
      //toggle_pin(2);
      
      // настраиваем таймер и начинаем выдавать ШИМ
      TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (1 << WGM00);
      TCCR0B |= (1 << CS02) | (1 << WGM02);
      OCR0A = 20;         // не больше 25
      OCR0B = 20;
      //TCNT0 = 0;
   }



тактовая частота 4.8МГц. Пробовал после инициализации таймера задержку 1 мс поставить - мб ему время раскачаться нужно. Но как-то не помогло :)

Re: Таймеры/счётчики в AVR

Пн мар 03, 2014 14:04:39

Не знаток СИ, но... разве код в
Код:
 while(1)                                 
   {
      ...
   }

не выполняется бесконечно сверху вниз?

Re: Таймеры/счётчики в AVR

Пн мар 03, 2014 14:37:57

Бесконечно выполняться будет, это конечно, неправильно, но здесь это не критично.
Неправильный режим выбран.
(1 << WGM02) - это лишнее

Re: Таймеры/счётчики в AVR

Пн мар 03, 2014 14:45:57

a_skr, похоже на то. когда убрал - полегчало. А почему так? Это же FastPWM c ограничением по OCRx?

Re: Таймеры/счётчики в AVR

Пн мар 03, 2014 14:58:29

COM0A = 3 - Set OC0A on Compare Match, clear OC0A at TOP,
а WGM = 7, значит, TOP=OCR0A, т.е. ножка выключится, не успев включиться.

если ставим WGM=3, то счетчик будет считать до 255, ножка включится по совпадению с OCR0A и выключится, когда счетчик досчитает до 255.
Ответить