Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
05.03.2012, 14:11
|
|
Частый гость
Регистрация: 05.03.2012
Сообщений: 13
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Изучаю Atmega48
На старость лет решил заняться изучением микроконтроллеров
Раньше никогда ими не занимался и не программировал, как и схемотехникой.
Оказалась под рукой Atmega48, скачал avr studio, решил заняться.
Поначалу писал простые програмки на подобие обрабоки нажатия на кнопки и зажигания светодидов. Проверял в proteus - все работало как задумал. Решил усложнить задачу и застрял.
Зачада следующая.
На вход контроллера PD1 подается ШИМ сигнал, с периодом Т=22мс, время импульса с начальном состоянии t=1.64мс. При увеличении длительности сигнала более (1,64+х)мс - свтодиоды на порту С включаем, при уменьшении длительности сигнала менее (1,64-х)мс - светодиоды на С отключаем, где х - диапазон "мертвой точки", где нет реакции на входной сигнал.
Форма сигнала
Схема устройства
Написал программу
Код:
|
#define F_CPU 1000000 // задаем частоту процессора 1МГц
#include ‹avr/io.h›
#include ‹util/delay.h›
int main(void)
{
DDRC = 0xff; // порт С на выход
DDRD = 0x00; // порт Д на вход
PORTD = 0xff; // устанавливаем 1 на порту Д
while (1)
{
if (PIND1) // если на входе PD1 установлен 1, то включим таймер
{
if (TCNT0==0x00) // включим таймер если выключен
{
TCCR0B =(1‹‹CS00)|(1‹‹CS01)|(0‹‹CS02); // CSx, ставим делитель счета 64
}
}
else // если PD1 сброшен в 0, проверим таймер
{
TCCR0B =(0‹‹CS00)|(0‹‹CS01)|(0‹‹CS02); // CSx, ставим делитель счета 0, выключаем таймер
if (TCNT0›0x1b) // включить порт С если таймер›(27*64=)1728ms
{
PORTC=0xff;
}
if (TCNT0‹0x16) // выключить порт С если таймер‹(22*64=)1408ms
{
PORTC=0x00;
}
}
}
} |
Запустил отладку программы.
Пошагово прохожу установку регистров, далее курсор минуя while и первый if сразу встает на условие if (TCNT0==0x00), далее это условие выполняется, на идет на ключение таймера и сразу же возвращается обратно на условие if (TCNT0==0x00), при этом судя по регистрам - таймер не включился, продолжаю делать шаги, avr studio несколько раз подряд проходит это условие и каждый раз идет на строку включения таймер. Через 4 таких прохода таймер включается и при следующих шагах курсор (желтая строка) всегда стоит на условии if (TCNT0==0x00), таймер успешно крутится и не останавливается даже если на вход PD1 ручками записать 0. Попробовал в в avr studio 5 и 6 - одинаково.
Пробовал в proteus, менял длительность импульсов - не работает.
В чем моя ошибка? Контроллеры раньше не программировал, но по моей логике все должно работать. В железе еще не далал, т.к. вижу что уже не работает
|
|
|
|
05.03.2012, 14:19
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Изучаю Atmega48
Я бы эту галимотью всю в прерывании написал. В основном коде ей делать нечего.
|
|
|
|
05.03.2012, 15:18
|
|
Супер-модератор
Регистрация: 03.05.2007
Сообщений: 2,695
Сказал спасибо: 28
Сказали Спасибо 4,509 раз(а) в 956 сообщении(ях)
|
Re: Изучаю Atmega48
Сообщение от alexnzak
|
В чем моя ошибка?
|
В том, что вы пытаетесь IF-ом, т.е. программно отследить конкретное значение АППАРАТНОГО таймера, т.е. пытаетесь мухе на лету оторвать лапку. Другими словами, как водитель блондинка пытаетесь на ходу машины переодеть колготки
|
|
|
|
05.03.2012, 15:31
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.10.2010
Сообщений: 1,752
Сказал спасибо: 158
Сказали Спасибо 640 раз(а) в 364 сообщении(ях)
|
Re: Изучаю Atmega48
Сообщение от Halex07
|
В том, что вы пытаетесь IF-ом, т.е. программно отследить конкретное значение АППАРАТНОГО таймера, т.е. пытаетесь мухе на лету оторвать лапку. Другими словами, как водитель блондинка пытаетесь на ходу машины переодеть колготки
|
Отследить состояние счетчика аппаратного таймера, который тикает раз в 64 мкс,
программно совсем не проблема.
Это все равно, что "оторвать лапки у дохлой мухи".
Программа у ТС не работает по другим причинам.
|
|
|
|
05.03.2012, 15:42
|
|
Частый гость
Регистрация: 05.03.2012
Сообщений: 13
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Изучаю Atmega48
ну пока на написания сразу правильных программ не претендую
прерывания пока пробовал только на кнопках, думал и эту задачу с таймером переделать потом на прерываниях.
состояние таймера проверяю только когда он стоит.
Ar-Gen-Tum, а в чем ошибка?
|
|
|
|
05.03.2012, 16:42
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,035
Сказал спасибо: 3,037
Сказали Спасибо 3,207 раз(а) в 2,177 сообщении(ях)
|
Re: Изучаю Atmega48
1. Красивее - было-бы сделать через захват внешнего сигнала. Таймер 1 крутится постоянно, в регистре TCCR1B настраиваете захватываемый переход. При переходе значение TCNT1 сохранено. Считываете его, меняете захватываемый переход, дожидаете нового захвата, вычитаете значения.
2. Что за компилятор? В GCC таких PIND1, вроде, не предусмотрено. КМК, что-то с условиями (PIND1) не так.
|
|
|
|
05.03.2012, 17:04
|
|
Частый гость
Регистрация: 05.03.2012
Сообщений: 13
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Изучаю Atmega48
ну видимо придется делать правильно
компилятор avr studio 5/6
|
|
|
|
05.03.2012, 17:18
|
|
Супер-модератор
Регистрация: 03.05.2007
Сообщений: 2,695
Сказал спасибо: 28
Сказали Спасибо 4,509 раз(а) в 956 сообщении(ях)
|
Re: Изучаю Atmega48
Сообщение от Ar-Gen-Tum
|
Отследить состояние счетчика аппаратного таймера, который тикает раз в 64 мкс, программно совсем не проблема.
|
Согласен, если в основном только этим и заниматься. Но не думаю, что ТС делает детскую игрушку, которая только и будет включать/выключать светодиод. Как только разовъется программа этот вариант заведет в тупик. Ну и конечно, прав
ForcePoint, на захвате таймера это будет и красивее и надежнее.
Сообщение от alexnzak
|
компилятор avr studio 5/6
|
Так и хочется спросить, как в "операции Ы" - какой-какой матери? Для Вас Atmel персонально, что ли разрабатывает... На офсайте последняя версия 5.1. И потом, может все-таки у Вас инсталирован WinAVR, а тогда про GCC все остается в силе.
Последний раз редактировалось Halex07; 05.03.2012 в 17:27.
|
|
|
|
05.03.2012, 17:22
|
|
Частый гость
Регистрация: 05.03.2012
Сообщений: 13
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Изучаю Atmega48
пока делается игрушка
на радиоуправляемом самолете включать/отлкючать фары, форма сигнала - это сигнал с выхода приемника снятый осцилографом
|
|
|
|
05.03.2012, 17:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.02.2008
Сообщений: 1,812
Сказал спасибо: 126
Сказали Спасибо 605 раз(а) в 422 сообщении(ях)
|
Re: Изучаю Atmega48
Сообщение от alexnzak
|
if (PIND1) // если на входе PD1 установлен 1, то включим таймер
{
if (TCNT0==0x00) // включим таймер если выключен
{
TCCR0B =(1‹‹CS00)|(1‹‹CS01)|(0‹‹CS02); // CSx, ставим делитель счета 64
}
}
|
Может не
if (TCNT0==0x00) // включим таймер если выключен
а проверить TCCR0B на 0? А в условии просто обнулить TCNT0 и включить TCCR0B ?
Думаю так вернее будет, если использовать данный алгоритм.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:04.
|
|