CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Сообщения: 822
Зарегистрирован: Вс июн 02, 2013 12:23:03

Сообщение amd9800 »

у меня 3 прерывания

прерывание от нажатия кнопки на int1

таймер который вызывает прерывание по переполнению раз 10 мили секунд. - timer 1.

и прерывание после АЦП.

ну и сама программа main в цикле while.

Теперь хочу понять как работают инструкции.

Например выполнил инструкции в основном цикле программы и отправил MK в sleep. Но например sleep перед последней инструкцией.

Просыпается МК по переполнению. Какую инструкцию выполнит МК? последнею инструкцию в основном цикле или сразу войдет в прерывание, и после выполнит инструкцию в основном цикле?

А если в прерывании по таймеру последняя команда sleep. То опять не выполниться команда в main, а после этого будет прерывание АЦП.

Main
Sleep
Timer
Sleep
ADC
Main
Sleep
Timer

Такой будет схема выполнения программы.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

amd9800 писал(а):Просыпается МК по переполнению. Какую инструкцию выполнит МК? последнею инструкцию в основном цикле или сразу войдет в прерывание, и после выполнит инструкцию в основном цикле?
6.7 Reset and Interrupt Handling
...
When the AVR exits from an interrupt, it will always return to the main program and execute one
more instruction before any pending interrupt is served.
Использование команды #asm("sleep") в то место где функция idle(); просто заводит чип в полное зависание.
Исключительно ваш косяк.
В качестве примера рекомендую посмотреть дизасм той же самой ф-ции idle() чтобы было примерно ясно что к чему.
Реклама
Опытный кот
Сообщения: 822
Зарегистрирован: Вс июн 02, 2013 12:23:03

Сообщение amd9800 »

uk8amk писал(а):Исключительно ваш косяк.
Ясно что не соседа ))).
uk8amk писал(а):В качестве примера рекомендую посмотреть дизасм той же самой ф-ции idle() чтобы было примерно ясно что к чему.
Как его посмотреть не подскажете?
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Листинг асм обычно кладётся в файл .asm или .a для каждого модуля.
Реклама
Эиком - электронные компоненты и радиодетали
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев

Сообщение RusikOk »

как использовать глобальную переменную из main.c в других модулях программы?
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев

Сообщение RusikOk »

uk8amk писал(а):extern
http://www.c-cpp.ru/books/extern
я не могу в другом файле подключать main.c т.к. выскочит ошибка redeclaration type...
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Как оформлять модули
http://www.pic24.ru/doku.php/osa/articles/modules
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев

Сообщение RusikOk »

uk8amk писал(а):Как оформлять модули
http://www.pic24.ru/doku.php/osa/articles/modules
т.к. main.h нету а если я его самостоятельно добавлю то компилятор его и не заметит. добавил в main.c

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

#ifndef _MAIN_C_
#define _MAIN_C_

...

#endif
и подключил main.c в заголовочном файле другого модуля. теперь выдает ошибку: #included from: main.c: can't open #include file: main.c
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Вы читали невнимательно.
Через #include подключаются заголовки, Си-шные файлы - через настройку проекта.

С вашим подходом создаётся как-бы единый файл main.c, его же вы пытаетесь включить в самого себя. Отсюда и лезут все ошибки.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 197
Зарегистрирован: Пн янв 24, 2011 01:51:48
Откуда: Украина, Киев

Сообщение RusikOk »

uk8amk писал(а):Вы читали невнимательно.
Через #include подключаются заголовки, Си-шные файлы - через настройку проекта.

С вашим подходом создаётся как-бы единый файл main.c, его же вы пытаетесь включить в самого себя. Отсюда и лезут все ошибки.
разобрался в чем дело. переменную extern нельзя инициализировать при объявлении
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Сообщение Wolf_X »

Подскажите как сделать аппаратный ШИМ для плавного включения светодиода в течение 20 минут на ATMEGA8515. Там 2 таймера, нулевой занят у меня под динамическую индикацию, в теле стоят задержки, там инкрементировать нельзя как я понимаю. Можно ли сделать ШИМ на первом таймере. Если не сложно киньте хотя бы примерный код.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Для светодиода можно и программный сделать. Не такая уж и большая частота нужна, чтобы не видеть мерцания.
А это уже на любом таймере.
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Сообщение Wolf_X »

Аlex писал(а):Для светодиода можно и программный сделать. Не такая уж и большая частота нужна, чтобы не видеть мерцания.
А это уже на любом таймере.

А если так попробовать, будет ли работать? (Нужно сделать рассвет закат для аквариума)
Спойлер#include <mega8515.h>
#include <delay.h>
#define led OCR1A
unsigned char n;

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
led++;
delay_ms(4700); //(20 мин *60 сек)/255= 4.7 сек или 4700 мс (0,064мс не учитывал)
}

void main(void)
{
DDRD=(0<<DDD7) | (0<<DDD6) | (1<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 4000,000 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Non-Inverted PWM
// OC1B output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 0,064 ms
// Output Pulse(s):
// OC1A Period: 0,064 ms Width: 0 us
// OC1B Period: 0,064 ms Width: 0 us
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<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=(1<<TOIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TICIE1) | (0<<TOIE0) | (0<<OCIE0);

#asm("sei")
while (1)
{

}
}
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Какой смысл от delay_ms в обработчике таймера ?
Погуглите программный ШИМ, там нет ничего сложного.
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Сообщение Wolf_X »

С программным ШИМом вроде понятно. Интересно было аппаратный реализовать. Задержка для того что бы растянуть регулирование яркости на 20 минут, каждые 4700 мс OCR1A ++, или это так не работает?
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Интересно было аппаратный реализовать
Вы, для начала, его реализуйте тогда, а по плавному наростанию - это уже будет другая задача.
У Вас будет обработчик прерываний от таймера, он будет вызываться периодически. Достаточно туда воткнуть переменную и ей отсчитывать кол-во вызовов. Тогда не придётся вешать наглухо программу на хз сколько секунд.
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 41
Зарегистрирован: Чт окт 23, 2014 04:12:56

Сообщение Wolf_X »

Я только учусь программированию, поэтому могу не понимать как правильно. изменил на:

unsigned int n;
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
n++;
if (n==65535) { led++; }
}

То есть если период таймера 0,064 ms, каждые 4,2 сек(65535*0,064) OCR1A прибавляет единичку. Выходит 17 минут на изменение яркости (4,2*255). Так правильно будет?
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Ну вот, уже что-то похоже на правду :)

PS: Вы сначала сам ШИМ запустите, чтобы он работал. Или он уже заработал у Вас ?
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Кстати, Вы сказали, что у Вас есть дин. индикация на таймере. Вот и воткните туда свой счётчик с инкрементом.
Никчему ещё один таймер тратить на такую ерунду.
Контактная информация:
Ответить

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