Страница 5 из 72
Re: Таймеры/счётчики в AVR
Добавлено: Сб янв 04, 2014 16:08:08
c2n
Да..
Код: Выделить всё
TCCR0B = TCCR0B|(1<<CS01)|(0<<CS00);//установка прескалера таймера = 1/8частоте.(т.к. на авывод надо 2 такта.. нам этого хватит)
У Евстифеева немного не внятно про сие таинство описано, а на басурманском и подавно.
Re: Таймеры/счётчики в AVR
Добавлено: Вс янв 12, 2014 12:04:34
Denkot
Покритикуйте, пожалуйста, кот.
Задача: по кнопке (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
amd9800
Atmega8 как привязать таймер 1 к выходу компаратора?
http://www.atmel.com/images/atmel-8159- ... asheet.pdf
есть в даташите
"17.6.3 Using the Input Capture Unit" - написано в общих чертах, но нет никаких точных указаний в каких регистрах какие биты надо выбрать.
Re: Atmega8 как привязать таймер 1 к выходу компаратора?
Добавлено: Пн фев 10, 2014 15:19:08
amd9800
И возникает вопрос - какой смысл привязывать выход компаратора к таймеру. Какие это дает преимущества.
Ведь изменение выхода компаратора может вызывать собственные прерывания и соответственно там писать программку которая возьмет число из регистра таймера на тот момент.
Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 10, 2014 15:24:04
akl
Да, совершенно верно, но таким способом таймер можно перевести в режим аппаратного захвата значения таймера.
Re: Atmega8 как привязать таймер 1 к выходу компаратора?
Добавлено: Пн фев 10, 2014 15:25:53
Gudd-Head
amd9800 писал(а):Какие это дает преимущества.
Насколько я понял, в ICRn будет именно то число, которое было в момент возникновения прерывания от компаратора.
А то пока программа скакнёт на вектор обработки (4 такта), пока на саму обработку (2 такта), пока считает значение таймера...
Re: Atmega8 как привязать таймер 1 к выходу компаратора?
Добавлено: Пн фев 10, 2014 15:31:29
amd9800
Если честно хочу сделать программку которая считает заряд конденсатора до определенного напряжения.
Заряжается конденсатор стабилизированным током.
тестирую но результаты не впечатляют. Если измеряю время заряда 1 микрофарад конденсатора получаю 72 такта. Измеряю 2 микрофарад получаю 84 такта. 3 микрофарад - 96 тактов. Получается 12 тактов на микрофарад.
Но если ставлю 0,01 микрофарада то получаю 57 тактов. И не могу понять логику - почему так происходит?
ICR1 - в этот регистр записывается текущее состояние счётчика при появлении активного входного сигнала на выводе ICP (бит 0 порта B)
Вот я не заметил ICR1. Останавливал таймер и читал TCNT1. - это и есть разница
Re: Atmega8 как привязать таймер 1 к выходу компаратора?
Добавлено: Пн фев 10, 2014 15:41:06
Gudd-Head
amd9800 писал(а):И не могу понять логику - почему так происходит?
Встроенный компаратор — гумно. У вас опора внешняя или встроенная? Попробуйте подать внешнюю.
Re: Atmega8 как привязать таймер 1 к выходу компаратора?
Добавлено: Пн фев 10, 2014 15:43:26
amd9800
Я использую внешнюю опору. Но пока все тесты в протеусе. Так что даже если что то гумно то все ровно пока работает в идеальных условиях.
Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 10, 2014 15:44:18
akl
Цитата правильная, но неполная. Вот пример подключения компаратора в режим захвата значения таймера1
Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 10, 2014 15:49:27
amd9800
пока результаты в протеусе радуют - линейная зависимость (емкость время заряда) прекрасная.
Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 10, 2014 17:15:37
c2n
Схему опубликуйте.. я чет не врублюсь

Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 10, 2014 22:56:07
amd9800
Ну такая схемка еще в разработке.
Спойлер

Re: Таймеры/счётчики в AVR
Добавлено: Вт фев 11, 2014 01:05:28
c2n
нда... лучше отдельно компаратор собрать, на "инструментальных" ОУ, и задействовать INT0,1.
Оно в порядке очередности раньше срабатывает...
Из собственной скудной практики наступал на грабли:
Для тини 2313 регистр ASCR, бит ACIC (2ой бит) но цепляется оно к счетчику T1. а не Т0.
Re: Таймеры/счётчики в AVR
Добавлено: Пн фев 24, 2014 22:29:11
dima81
Доброго всем времени суток.
Подскажите по таймеру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
slavokhire5
Товарищи коты, прошу помощи по ШИМу в 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
Gudd-Head
Не знаток СИ, но... разве код в
не выполняется бесконечно сверху вниз?
Re: Таймеры/счётчики в AVR
Добавлено: Пн мар 03, 2014 14:37:57
a_skr
Бесконечно выполняться будет, это конечно, неправильно, но здесь это не критично.
Неправильный режим выбран.
(1 << WGM02) - это лишнее
Re: Таймеры/счётчики в AVR
Добавлено: Пн мар 03, 2014 14:45:57
slavokhire5
a_skr, похоже на то. когда убрал - полегчало. А почему так? Это же FastPWM c ограничением по OCRx?
Re: Таймеры/счётчики в AVR
Добавлено: Пн мар 03, 2014 14:58:29
a_skr
COM0A = 3 - Set OC0A on Compare Match, clear OC0A at TOP,
а WGM = 7, значит, TOP=OCR0A, т.е. ножка выключится, не успев включиться.
если ставим WGM=3, то счетчик будет считать до 255, ножка включится по совпадению с OCR0A и выключится, когда счетчик досчитает до 255.