Страница 6 из 72
Re: Таймеры/счётчики в AVR
Добавлено: Пн мар 03, 2014 20:43:14
Грендайзер
Здравствуйте, товарищи. Никак не могу заставить Timer/Counter1 Atmega16A работать в режиме fast PWM. Что уже только не делал... Он ведь как дойдёт до значения TOP должен сразу обнулиться, а он зараза такая доходит до значения 0x3FF (не обращая внимание на TOP) и начинает считать в обратную сторону
Код: Выделить всё
#include "avr/io.h"
#include<avr/interrupt.h>
#include<avr/boot.h>
#define F_CPU 1000000UL // 1MHz
#include <util/delay.h>
ISR(TIMER1_COMPA_vect) // вектор прерывания (хрен знает зачем, может поможет)
{
//reti();
sei();
}
int main(void)
{
sei(); // устанавливаем флаг глоб. прерывания
DDRA = 0; // Порт A на ввод
DDRB = 0; // Порт B на ввод
PORTA = 0xFF; // Включить внутренние резисторы порта А
PORTB = 0xFF; // Включить внутренние резисторы порта В
ACSR = 0x80; // Отключить компаратор
ADCSRA = 0x80; // Отключить АЦП
DDRC = 0xFF; // Порт С на вывод
PORTC = 1; // выдать на порт С лог. "1"
DDRD = 0xFF; // Порт D на вывод для генерации ШИМ на ногах OC1В и ОС1А (PD4 и PD5)
PORTD = 0; // выдать на порт D лог. "0"
// Нога OC1B должна работать в неинверсном режиме, а нога OC1А в инверсном
// Для этого записываем в в соотв. разряды регистра TCCR1A соотв. уровни
TCCR1A |= _BV(COM1A1);
TCCR1A |= _BV(COM1A0);
// Нога OC1B должна работать в неинверсном режиме, а нога OC1А в инверсном
// Для этого записываем в в соотв. разряды регистра TCCR1A соотв. уровни
TCCR1A |= _BV(COM1B1);
TCCR1A &= ~_BV(COM1B0);
// Значение TOP должно храниться в регистре OCR1A, для этого разряды WGM13:10
// должны быть равны 1
TCCR1A |= _BV(WGM11);
TCCR1A |= _BV(WGM10);
// Значение TOP должно храниться в регистре OCR1A, для этого разряды WGM13:10
// должны быть равны 1
TCCR1B |= _BV(WGM13);
TCCR1B |= _BV(WGM12);
// Записываем значение TOP в OCR1A = 500, а в ICR1 = 500/2 = 250 (скважность ШИМ = 2)
OCR1A = 500;//000;
ICR1 = 250;//000;
//OCR1B = 50;//000;
TIMSK |= _BV(OCIE1A); // Устанавливаем маску прерывания (хрен знает зачем, может поможет)
TCNT1 = 0; // Обнуляем счётный регистр (хрен знает зачем, может поможет)
// Запускаем счётчик выбрав источник тактового сигнала (напрямую от внутреннего генератора
// без использования предделителя )
TCCR1B |= 1;
while(1)
{
PORTC = ~PORTC;
}
}
Re: Таймеры/счётчики в AVR
Добавлено: Вт мар 04, 2014 11:08:31
Gudd-Head
Грендайзер писал(а):и начинает считать в обратную сторону
Дык, это вроде Phase Correct PWM Mode?
Re: Таймеры/счётчики в AVR
Добавлено: Вт мар 04, 2014 11:32:54
Грендайзер
Дык, это вроде Phase Correct PWM Mode?
Ну делал то я фаст пвм... а вот работает то он как то не так...
Правда нашёл тут на форуме ссылочку на другой форум, там товарищ почти с таким косяком столкнулся... так вроде пишет что железка нормально фурычит, что мол косяк симмулятора студии... Вчера не успел в железе посмотреть, сегодня вечером попробую...
Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 08:24:00
ibiza11
Подтверждаю, АВР студии есть косяк с симуляцией режимов ШИМ
Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 10:09:02
Gudd-Head
Грендайзер писал(а):что мол косяк симмулятора студии...
Для этого открываем Хэлп в студии, ищем
Known Issues на симулятор, смотрим:
General Simulator Issues
The issues in this section apply to all AVR devices.
...
Timer/Counters
16-bit Timer/Counters on all devices have several problems with PWM, prescaler and output compare. Output compare registers are not buffered properly.
The Asynchronous Status Register (ASSR) is not supported in timers with asynchronous mode. This is due to lack of a generic external clock implementation.
...
Плюс ещё есть смысл глянуть на
Device specific issues
Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 12:14:44
kotriks
народ можно ли реализовать таймер на включение порта врубился он на минут 5 и выключился на час при этом не мешая работае основной программе тоесть чтобы программа не прекращалла работать.
есть у меня часы счётчик на 1000000 мгц атмега48
Спойлер
Код: Выделить всё
ISR(TIMER0_OVF_vect) {
time++;
if (time==488) {asm("wdr");time=0;seconds++;}
if (seconds==60) {seconds=0; minutes++; }
if (minutes==60) {minutes=0; hours++; }
}
делал так
Код: Выделить всё
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <string.h>
#include <string.h>
#include <util/delay.h>
#define PORT 3
#define PORT_ON PORTC|=1<<PORT
#define PORT_OFF PORTC&=~(1<<PORT)
void ON(){
TIMSK1=0x00;
код
TCNT1H=0x00;
TCNT1L=0xFF;
TCCR1A=0x00;
TCCR1B=0x03;
TIMSK1=0x01;
}
ISR(TIMER1_OVF_vect) {
TIMSK1=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
sei();
PORT_ON;
_delay_ms(100000);
PORT_OFF;
}
int main(void)
{
// Input/Output Ports initialization
PORTB=0xFF;
DDRB=0x00;
// Port C initialization
PORTC=0xFF;
DDRC=0x00;
// Port D initialization
PORTD=0xFF;
DDRD=0x00;
DDRC|=(1<<3); PORT_OFF;
// External Interrupt(s) initialization
// INT0: On
EICRA=0x00;
EIMSK=0x00;
EIFR=0x00;
PCICR=0x00;
// Clock value: 31.250 kHz
TCCR0A=0x00;
TCCR0B=0x02;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
sei();
while (1){
ON();
}
}
но при этом когда вызывается таймер на открытие порта основной код
висит до завершения вызова таймера на открытие порта.
сможет кто нибудь помочь?
Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 15:15:46
Грендайзер
Вчера зашил в железку... Результат - 0. Не работает. Что ж за ерунда

Может кто нить поделится кодиком 100% рабочим, а то уже и не знаючто за ерунда. Попробую ещё в последней студии всё это сделать....
Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 15:21:04
Грендайзер
Gudd-Head писал(а):
...
Timer/Counters
16-bit Timer/Counters on all devices have several problems with PWM, prescaler and output compare. Output compare registers are not buffered properly.
The Asynchronous Status Register (ASSR) is not supported in timers with asynchronous mode. This is due to lack of a generic external clock implementation.
...
Не ну нормально!! И чё теперь?! Зря мы на этих капиталюг бомбу ядрёную не сбросили

Re: Таймеры/счётчики в AVR
Добавлено: Ср мар 05, 2014 22:01:44
Грендайзер
значение WGM10 заменил на "0". Т.е. тот же фаст пвм, только максимальное значение лежит в другом регистре - вроде железка заработала. Заставить счётчик работать в 15 - ом режиме (WGM13:0 = 15) так и не вышло... чудеса

Походу не только наш брат но и за бугром инженеры косячат

Re: Таймеры/счётчики в AVR
Добавлено: Чт мар 06, 2014 09:01:35
kotriks
Вопрос отпадает, сделал так
Код: Выделить всё
ISR(TIMER0_OVF_vect) {
time++;
if (time==488) {asm("wdr");time=0;seconds++;}
if (seconds==60) {seconds=0; minutes++; }
if (minutes==60) {minutes=0; hours++; }
if(minutes==1){
PORT_ON;
}
if(minutes==2){
PORT_OFF;
}
}
через каждый час врубается и вырубается на 2 минуте.
Re: Таймеры/счётчики в AVR
Добавлено: Чт мар 06, 2014 09:27:42
a_skr
Грендайзер писал(а):Заставить счётчик работать в 15 - ом режиме (WGM13:0 = 15) так и не вышло... чудеса

Походу не только наш брат но и за бугром инженеры косячат

Читайте внимательно DS. Этот режим скорее не для ШИМ, а для частотной модуляции. Режим дергания ножками в данном случае можно установить как "поменять на противоположное". Получите меандр. Изменяя OCR1A можно менять частоту.
Код: Выделить всё
int main(void)
{
DDRD = _BV(PD5);
TCCR1A = _BV(COM1A0) | _BV(WGM11) | _BV(WGM10);
TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
OCR1A = 1000;
while(1);
}

Re: Таймеры/счётчики в AVR
Добавлено: Чт мар 06, 2014 09:36:15
Грендайзер
Изменяя OCR1A можно менять частоту.
Это здорово конечно... Но что делать, если на ноге то физически нет сигнала, что там не меняй?

Re: Таймеры/счётчики в AVR
Добавлено: Чт мар 06, 2014 09:42:54
a_skr
Залейте вышеприведенный пример в МК и увидите сигнал на ножке с частотой fcpu/1000/2.

Не устанавливайте COM1A1 или COM1B1 в единицу. См. замечание к таблице 45 DS. Единственный вариант дергать ножкой в этом случае - "поменять на противоположное". Получите меандр.
Re: Таймеры/счётчики в AVR
Добавлено: Чт мар 06, 2014 19:50:32
Грендайзер
a_skr, действительно. Ваш код заработал. На ноге OC1A появился меандр со скважностью 2. И хотя я так и не понял про какую таблицу Вы писали, всё же данный вид работы, это не совсем то, о чём говорится в даташите

Конечно можно поиграться с прерываниями, но тем не менее это не совсем то, что я ожидал от пвм контроллера. Да и подобный сигнал можно и в режиме CTC сгенерить

Таймеры/счетчики МК
Добавлено: Чт апр 10, 2014 22:16:55
Mr.Noiro
Предлагаю детально разобрать нюансы работы с таймерами-счетчиками микроконтроллеров задавая вопросы и давая ответы.
И вот, первый вопрос по коду:
ldi r16,0x05
out TCCR1B,r16
ldi r16,0x02
out TCCR1A,r16
ldi r16,high(pause)
ldi r17,low(pause)
out OCR1AH,r16
out OCR1AL,r17
записав командой out OCR1AH,r16 - значение в регистре появляется. Но после следующей команды - пропадает.
В регистре OCR1AL - сохраняется и не исчезает, МК tiny2313, avrstudio 4. В чем может быть причина?
Re: Таймеры/счетчики МК
Добавлено: Чт апр 10, 2014 23:03:44
Ser60
Поменяйте местами 2 последние строчки кода.
Re: Таймеры/счетчики МК
Добавлено: Чт апр 10, 2014 23:22:01
Flasher
зачем менять? Пишем старший, потом младший.
Re: Таймеры/счетчики МК
Добавлено: Пт апр 11, 2014 00:42:51
Ser60
Да. Вы правы - это у меня переклинило что-то.
Re: Таймеры/счетчики МК
Добавлено: Пт апр 11, 2014 07:50:16
ИС-пытатель
А как Вы, простите, узнали, что пропадает? Это симулятор показал? Или Вы потом командами считали значение и вывели в порт?
Re: Таймеры/счетчики МК
Добавлено: Пт апр 11, 2014 08:28:00
pavel1979
запись идет со сдвигом
записали предустановку,оно сначала в младшем,потом программа сдвигает на 8 разрядов,получается старший,в даташите написано
в меге8 все пишется как захочешь