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

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь

Сообщение prinv »

Продолжаю мучать Atmega88
На пин 6 даю сигнал с частотой 1 Гц.
Хочу уходить в прерывание по каждому возрастающему фронту сигнала.
Не уходит в прерывание по совпадению. Почему?

Код: Выделить всё


	DDRB	|=	_BV(PINB7);
	// Настраиваем 8-битный таймер 0
	TCCR0A		=	_BV(WGM01);						// Режим подсчета импульсов (сброс при совпадении)
	TCCR0B		=	_BV(CS02)|_BV(CS01)|_BV(CS00);	// Источник тактирования - внешний источник на выводе T0 (6 ножка) по возрастанию сигнала
	OCR0A		=	1;								// Считаем до 1
	TIMSK0		|=	_BV(OCIE0A);					// Прерывание при совпадении с A

Код: Выделить всё

ISR (TIMER0_COMPA_vect)
{
	PORTB			|=	_BV(PINB7);
	_delay_ms(50);
	PORTB			^=	_BV(PINB7);
	TCNT0			=	0;
}
Никакая контра не уйдёт от нас
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

А счет-то идет? Может там тактирования нет? Попробуйте посмотреть значения TCNT0 либо настроить таймер на внутреннее тактирование чтобы проверить настройки.
Что говорят симуляторы (Студия, Протеус)?
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь

Сообщение prinv »

В Протеусе и смотрю.

При тактировании от CLK с делителем /256 (TCCR0B = _BV(CS02);) на выходе PB7 виден сигнал.
Вложения
2016-05-05 10.33.17.jpg
(254.41 КБ) 593 скачивания
Никакая контра не уйдёт от нас
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 677
Зарегистрирован: Чт янв 20, 2011 09:07:08
Откуда: Пермь

Сообщение prinv »

Переписал в чистый проект с исправлениями - заработало.
Почему изначально не работало - ХЗ.

Код: Выделить всё

#define	F_CPU		8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#include "i2c.h"
#include "ds1307.h"

ISR (TIMER0_COMPA_vect)
{
	PORTB			^=	_BV(PINB7);
}

void DS1307Init()									// запускаем ход часов
{
	uint8_t temp;
	DS1307Read(0x00,&temp);
	temp &= ~(1 << 7);								// обнуляем 7 бит
	DS1307Write(0x00,temp);
	DS1307Read(0x07,&temp);
	temp &= ~(_BV(0)|_BV(1));						// Пуск меандра 1 Гц
	temp |= _BV(4);
	DS1307Write(0x07,temp);
} //  DS1307Init

int main(void)
{
	I2CInit();
	DS1307Init();
	DDRB	|= _BV(PINB7);
	// Настраиваем 8-битный таймер 0
	TCCR0A		=	0;								// Остановили таймер T0
	TCCR0A		=	_BV(WGM01);						// Режим подсчета импульсов (сброс при совпадении)
	TCCR0B		=	_BV(CS02)|_BV(CS01)|_BV(CS00);	// Источник тактирования - внешний источник на выводе T0 (6 ножка) по возрастанию сигнала
	OCR0A		=	0;								// Считаем до 1
	TIMSK0		|=	_BV(OCIE0A);					// Прерывание при совпадении с A
		
    sei();
    while (1) 
    {
    }
}
Никакая контра не уйдёт от нас
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 135
Зарегистрирован: Ср фев 04, 2015 21:08:59

Сообщение креазот »

привет.
не пойму сколько таймеров 16 битных у ATmega64A, один или два, или же полтора?
смотрю даташит на этот мк. в самом начале есть вот такой перечень (см. картинку) в котором почему-то числится только 1 16ти битный таймер, хотя потом указаны и пины с выводами к таймеру3 и описываются регистры таймера3.

а вот еще что показывает AvrStudio4 (см. другую картинку) не пойму что такое "na" которое стоит рядом с адресом регистров? помоему в студии таймер3 не работает

английский не знаю, поэтому сложно разобраться самому
пролейте свет
Вложения
tgtgtgt.png
(26.63 КБ) 569 скачиваний
lolololo.png
(78.86 КБ) 549 скачиваний
Реклама
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

В официальном даташите написано по два таймера.
Станислав
Реклама
Встал на лапы
Сообщения: 135
Зарегистрирован: Ср фев 04, 2015 21:08:59

Сообщение креазот »

скриншот который я выложил выше сделан с официального даташита на атмегу64А.
в том то и дело, что в таблице этой указан 1 16битный таймер, а ниже в даташите речь идет как о 2х вроде.
не могли же они такую ошибку не заметить.. неспроста это..

и студия как то странно показывает таймер3
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

креазот писал(а):не могли же они такую ошибку не заметить..
А че нет то? :roll:

Пробуйте Таймер3 запустить, там и узнаете. :)
У меня АВРСтудио 4.19 вроде нормально показывает. Да, не одинаково. Но там и надо смотреть, что регистры у этих (флаги всякие) разные. Таймер 3 находится в расширенных регистрах, поэтому и другие картинки.

А про НА вот вроде оно у Ди-Халта:
Правда тут возникает еще один прикол. Дело в том, что с каждым годом появляются все новые и новые камни от AVR и мяса в них все больше и больше. А каждой шкварке нужно свои периферийные регистры ввода-вывода. И вот, дожили, в ATMega88 (что пришла на замену Mega8) периферии уже столько, что ее регистры ввода-вывода уже не умещаются в лимит адресного пространства 3F.

Опаньки, приплыли. И вот тут у тех кто пересаживается с старых камней на новые начинаются недоуменные выражения — с чего это команды OUT/IN на одних периферийных регистрах работают, а на других нет?

А все просто — разрядности не хватило.

А ядро то единое, его уже не переделать. И вот тут ATMELовцы поступили хитро — они ввели так называемые memory mapped регистры. Т.е. все те регистры, что не влезли в лимит 3F доступны теперь только одним способом — через Load/Store.

Вот такой прикол. Если открыть какой нибудь m88def.inc то там можно увидеть какие из регистров ввода-вывода «правильные» а какие memory mapped.
http://easyelectronics.ru/avr-uchebnyj- ... h-rom.html
Станислав
Встал на лапы
Сообщения: 135
Зарегистрирован: Ср фев 04, 2015 21:08:59

Сообщение креазот »

спасибо
Идёт направо - песнь заводит, Налево - сказку говорит.
Аватара пользователя
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Сообщение СКАЗОЧНИК »

Точно оно...
Спойлер

Код: Выделить всё

; ***** I/O REGISTER DEFINITIONS *****************************************
; NOTE:
; Definitions marked "MEMORY MAPPED"are extended I/O ports
; and cannot be used with IN/OUT instructions
.equ	UCSR1C	= 0x9d	; MEMORY MAPPED
.equ	UDR1	= 0x9c	; MEMORY MAPPED
.equ	UCSR1A	= 0x9b	; MEMORY MAPPED
.equ	UCSR1B	= 0x9a	; MEMORY MAPPED
.equ	UBRR1H	= 0x98	; MEMORY MAPPED
.equ	UBRR1L	= 0x99	; MEMORY MAPPED
.equ	UCSR0C	= 0x95	; MEMORY MAPPED
.equ	UBRR0H	= 0x90	; MEMORY MAPPED
.equ	ADCSRB	= 0x8e	; MEMORY MAPPED
.equ	TCCR3C	= 0x8c	; MEMORY MAPPED
.equ	TCCR3A	= 0x8b	; MEMORY MAPPED
.equ	TCCR3B	= 0x8a	; MEMORY MAPPED
.equ	TCNT3L	= 0x88	; MEMORY MAPPED
.equ	TCNT3H	= 0x89	; MEMORY MAPPED
.equ	OCR3AL	= 0x86	; MEMORY MAPPED
.equ	OCR3AH	= 0x87	; MEMORY MAPPED
.equ	OCR3BL	= 0x84	; MEMORY MAPPED
.equ	OCR3BH	= 0x85	; MEMORY MAPPED
.equ	OCR3CL	= 0x82	; MEMORY MAPPED
.equ	OCR3CH	= 0x83	; MEMORY MAPPED
.equ	ICR3L	= 0x80	; MEMORY MAPPED
.equ	ICR3H	= 0x81	; MEMORY MAPPED
.equ	ETIMSK	= 0x7d	; MEMORY MAPPED
.equ	ETIFR	= 0x7c	; MEMORY MAPPED
.equ	TCCR1C	= 0x7a	; MEMORY MAPPED
.equ	OCR1CL	= 0x78	; MEMORY MAPPED
.equ	OCR1CH	= 0x79	; MEMORY MAPPED
.equ	TWCR	= 0x74	; MEMORY MAPPED
.equ	TWDR	= 0x73	; MEMORY MAPPED
.equ	TWAR	= 0x72	; MEMORY MAPPED
.equ	TWSR	= 0x71	; MEMORY MAPPED
.equ	TWBR	= 0x70	; MEMORY MAPPED
.equ	OSCCAL	= 0x6f	; MEMORY MAPPED
.equ	XMCRA	= 0x6d	; MEMORY MAPPED
.equ	XMCRB	= 0x6c	; MEMORY MAPPED
.equ	EICRA	= 0x6a	; MEMORY MAPPED
.equ	SPMCSR	= 0x68	; MEMORY MAPPED
.equ	PORTG	= 0x65	; MEMORY MAPPED
.equ	DDRG	= 0x64	; MEMORY MAPPED
.equ	PING	= 0x63	; MEMORY MAPPED
.equ	PORTF	= 0x62	; MEMORY MAPPED
.equ	DDRF	= 0x61	; MEMORY MAPPED
.equ	SREG	= 0x3f
.equ	SPL	= 0x3d
.equ	SPH	= 0x3e
.equ	XDIV	= 0x3c
.equ	EICRB	= 0x3a
.equ	EIMSK	= 0x39
.equ	EIFR	= 0x38
.equ	TIMSK	= 0x37
.equ	TIFR	= 0x36
.equ	MCUCR	= 0x35
.equ	MCUCSR	= 0x34
.equ	TCCR0	= 0x33
.equ	TCNT0	= 0x32
.equ	OCR0	= 0x31
.equ	ASSR	= 0x30
.equ	TCCR1A	= 0x2f
.equ	TCCR1B	= 0x2e
.equ	TCNT1L	= 0x2c
.equ	TCNT1H	= 0x2d
.equ	OCR1AL	= 0x2a
.equ	OCR1AH	= 0x2b
.equ	OCR1BL	= 0x28
.equ	OCR1BH	= 0x29
.equ	ICR1L	= 0x26
.equ	ICR1H	= 0x27
.equ	TCCR2	= 0x25
.equ	TCNT2	= 0x24
.equ	OCR2	= 0x23
.equ	OCDR	= 0x22
.equ	WDTCR	= 0x21
.equ	SFIOR	= 0x20
.equ	EEARL	= 0x1e
.equ	EEARH	= 0x1f
.equ	EEDR	= 0x1d
.equ	EECR	= 0x1c
.equ	PORTA	= 0x1b
.equ	DDRA	= 0x1a
.equ	PINA	= 0x19
.equ	PORTB	= 0x18
.equ	DDRB	= 0x17
.equ	PINB	= 0x16
.equ	PORTC	= 0x15
.equ	DDRC	= 0x14
.equ	PINC	= 0x13
.equ	PORTD	= 0x12
.equ	DDRD	= 0x11
.equ	PIND	= 0x10
.equ	SPDR	= 0x0f
.equ	SPSR	= 0x0e
.equ	SPCR	= 0x0d
.equ	UDR0	= 0x0c
.equ	UCSR0A	= 0x0b
.equ	UCSR0B	= 0x0a
.equ	UBRR0L	= 0x09
.equ	ACSR	= 0x08
.equ	ADMUX	= 0x07
.equ	ADCSRA	= 0x06
.equ	ADCH	= 0x05
.equ	ADCL	= 0x04
.equ	PORTE	= 0x03
.equ	DDRE	= 0x02
.equ	PINE	= 0x01
.equ	PINF	= 0x00
Станислав
Прорезались зубы
Сообщения: 218
Зарегистрирован: Ср дек 02, 2015 15:06:01

Сообщение BEST-83154 »

вот тут вписан вольтметр,амперметр,ваттметр,таймер и разложения чисел
и мне хотелось бы видеть еще и замер емкости акб в А/Ч
кто может помогите!!!
Вложения
45.c
(5.22 КБ) 538 скачиваний
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 16, 2009 14:23:59

Сообщение NebelWefer »

товарищи, подскажите, пожалуйста, где ошибаюсь:
атмега8, хочу просто запустить 8битный таймер - при включении зажигаю светодиод, а по переполнению таймера он должен гаснуть.
atmel studio 7

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
ISR( TIMER0_OVF_vect)
{
PORTB = 0b00010000;
}
int main(void)
{   
	
	DDRB = 0b10110000;  
	PORTB = 0b10000000;  
	TCCR0 = (1<<CS12)|(0<<CS11)|(1<<CS10); //xtall/1024
	TIMSK |= (1<<TOIE0); 
	sei();
    while (1) {}
}
диод загорается при старте и не думает гаснуть :( (диод подключен между Vcc и ногой мк)
ЗЫ: смотрю по дебагу - все биты записываются куда надо, но таймер ни разу не тикает, в TCNT0 глухой 0x00
ЗЫЫ: разобрался)) все работает, вешал диод не на тот порт, почему-то был уверен, что порты нумеруются 1-8 :dont_know:
вообщем :facepalm: :facepalm: :facepalm:
Открыл глаза
Сообщения: 50
Зарегистрирован: Пн июл 28, 2014 20:23:22

Сообщение Mixail_BM »

Не знаю даже, куда и писать. Попробую сюда.
Задумал я сделать себе тахометр на светодиодах. Все хорошо, захожу на сайт, ищу - 46 статей.
Открываю первую - на 7-ми сегментных индикаторах. Нехорошо будет, думаю, ненаглядно. Как и писали в той статье цифровая информация доходит дольше, чем аналоговая, да и не так демонстративно.
Зашел на вторую статью, третью - тоже самое с вариациями.
На четвертой повезло - МК atmega8, замечательно, смотрю дальше - дисплей. И как только не искал, на МК, но с выходом через линейку светодиодов что-то не нашел.
Ну, думаю, делать нечего, хоть отвлекусь перед сдачей диплома. Полез в ДШ, по сайтам посмотрел и стыдно стало, чтой-то я ничего не понимаю.
На сайтах либо только прошивка, т.е. исходника нет, чтоб посмотреть что там и как, либо написано не в cvavr.
Ну присел, значит на стул и пишу на листочек что надо. Писал-писал и написал. И вроде что-то считает, да не то. Оказывается я "слегка" нестандартно писал - счетчик Т1 отсчитывает время, за которое изменится Т0 к которому подключен вход. на Т1 предделитель 8, тактовая частота 6МГц. получаем 1/750000сек=1имп Т1.
На машине максимальное число тиков при МИНИМАЛЬНЫХ оборотах, например 420 оборотов=14 срабатываний трамблера в секунду, т.е. 0,071428571сек при 0,08738сек счетчик сбросится, т.е. его должно хватать. Однако я чего-то закосил, видать мозги переклинило. Был бы благодарен помощи.
P.S. шкала разводится от сдвиговых регистров 74hc595 как самых дешёвых. файлы проекта в cvavr и proteus прилагаю а также примерные обороты двигателя (чтоб целое число в расчетах) в экселе. кстати в исходнике немного лишнего кода, не обращайте внимания.
P.P.S. Был бы ОЧЕНЬ благодарен не столько за решение, сколько за подробное объяснение.
Вложения
tahometr3.rar
(74.5 КБ) 152 скачивания
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18741
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Mixail_BM писал(а):Был бы ОЧЕНЬ благодарен не столько за решение, сколько за подробное объяснение
если вы возьмете проект, в котором индикация осуществляется на любой индикатор (дисплей), и дополните ее всего двумя функциями, вы легко решите свою задачу.
1-я функция должна брать то число, которое имеющаяся программа выводит на индикатор и превращать его в "полоску". как будет кодироваться эта полоска, сколько в ней будет градаций и какова цена каждого элемента - это полностью зависит от вашего желания.
2-я функция должна выпихнуть полученный первой функцией результат в цепочку сдвиговых регистров.

вот и все. вы просто замените один способ индикации на другой.

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

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 50
Зарегистрирован: Пн июл 28, 2014 20:23:22

Сообщение Mixail_BM »

М-м-м-м а не могли бы вы привести пример относительно того, что в архиве?
Вложения
input_capture.rar
(36.37 КБ) 178 скачиваний
Открыл глаза
Сообщения: 50
Зарегистрирован: Пн июл 28, 2014 20:23:22

Сообщение Mixail_BM »

Спасибо, что никто не ответил (кроме 1), зато сам разобрался с счетчиком. Правда код получился большой(800байт), ну так работает..... все еще впереди.
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

необходимо настроить 16 разрядный счетчик: в режиме FastPWM он должен считать до 0xFFFF
по таблице вижу что он может быть только 8,9 или 10 разрядным
как сделать чтобы он считал до 0xFFFF ?
Изображение
Tell Me The Truth
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18741
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вы не досмотрели таблицу до конца: режим 14 и 15 - самое ваше
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

правда ваша, спасибо !
Изображение
Tell Me The Truth
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 183
Зарегистрирован: Вт сен 14, 2010 23:07:10
Откуда: Ростов

Сообщение baron_P »

Доброго времени суток.
Есть странный затуп с МК ATMega8. Хочу использовать для генерации ШИМ-сигнала Т/С1 в режиме FastPWM со счетом до ICR1. Инициализирую это дело так:
Спойлер

Код: Выделить всё

//Процедура инициализации Т/С1 (формирование ШИМ-выхода)
void init_TC1(void)
{
    //На выводе OC1A  при совпадении "0" при возрастании и "1"
    //при убываниии, режим 16-битного FastPWM cо счетом до ICR1
    TCCR1A |= (1 << COM1A1) | (1 << WGM11);
    TCCR1B |= (1 << WGM13) | (1 << WGM12);
    //Максимум счета Т/С1
    ICR1 = 100;
    //Предделитель 0 - ШИМ остановлен
    TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));
    //PB1 - выход ШИМ
    DDRB |= (1 << PB1);   
    //Начальное задание ШИМ
    OCR1A = 0;
}
В коде программы есть обработчик нажатия кнопки такого вида:
Спойлер

Код: Выделить всё

//Функция изменения режима работы по нажатию кнопки (со сбросом состояния)
unsigned char mod_chg_but_reset(unsigned char mod_name, unsigned char port_num)
{
    //Задержка на дребезг контактов кнопки
    _delay_ms(TIME_MS);
    
    //Если на соотв. выводе "0" (кнопка нажата)...
    if ((PINC & (1 << port_num)) == 0)
    {
        //Если соотв. режим выкл...
        if (mod_name == 0)
            mod_name = 1;  //то включаем его
        else  //...иначе...
            mod_name = 0;  //выключаем
    }

    //Ждем отпускания кнопки
    while ((PINC & (1 << port_num)) == 0)
        asm volatile ("nop"::);

    //Выводим полученный по состоянию кнопки режим
    return mod_name;
}
При вызове я даю ему имя переменной, в которую пишется выбранный режим и номер порта, с которого нужно считывать нажатие кнопки. В зависимости от выбранного режима, приведенная ниже функция запускается с параметром запуска или останова ШИМ.
Спойлер

Код: Выделить всё

//Процедура запуска/останова вывода заданной ШИМ
void PWM_out(unsigned char PWM_ref, unsigned char start_stop)
{
    //Если дан сигнал останова...
    if (start_stop == 0)
    {   
        //Гасим индикатор работы
        PORTB |= (1 << PB0);
        //Выдаем нулевое ШИМ
        OCR1A = 0;
        //Ждем пока на выводе ШИМ будет 0
        while ((PINB & (1 << PB1)) != 0)
            asm volatile ("nop"::);
        //Останавливаем ШИМ
        TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));
    }
    else  //...иначе...
    {
        //Зажигаем индикатор работы
        PORTB &= ~(1 << PB0);
        //Запускаем ШИМ с предделителем 64
        TCCR1B |= (1 << CS11) | (1 << CS10);
        //Выдаем ШИМ заданной скважности
        OCR1A = PWM_ref;
    };
}
Вся эта штука работает правильно, если выбран обычный FastPWM или, например, PhaseCorrectPWM c отсчетом до ICR1. А если выбрать нужный мне FastPWM с отсчетом до ICR1, то не работает функция считывания нажатия кнопок. Если режим переключить переменной, то все ок (запускается ШИМ и тд.), а включить вручную никак: состояние PINC (на котором висят кнопки и входные сигналы) ни в какую не хочет считываться.
Подскажите, пожалуйста, куда примерно думать. Что-то совсем не могу понять, как это может быть связано между собой.
We do what we must because we can (c) GLaDOS
Ответить

Вернуться в «AVR»