Страница 1 из 1

Не получается генерация 40кГц

Добавлено: Вт июн 30, 2009 12:40:08
Gozi
Здраствуйте! Пытаюсь генерировать сигнал с частотой 40кГц с помощью таймера1 на мега16 и подавать этот сигнал на вывод PA1. Вроде всё легко и ясно но на практике не получается(осциллограф показывает на выводе две сплошные полосы даже при минимальном значении время/ деление(0.1 мкс) ).
PS первый раз в жизни чтото программирую,но до этого прочитал какойто красочный курс по микроконтролерам и вроде даже понял

Добавлено: Вт июн 30, 2009 14:36:34
Alex72
Лучше для такой задачи использовать аппаратный ШИМ таймера1 на выводах PD5 или PD4, а PA1 оставить в покое. К тому же МК практически не будет загружен. С кодом вот помочь не смогу, СИ не знаю.

Добавлено: Вт июн 30, 2009 20:42:07
asteroid7
И как эта строчка должна работать?

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

PORTA.0 = !(PINA.0);
СИ - не бейсик. Напишите, лучше, изменение порта по человечески, по СИшному:
PORTA ^= (1 << PA0);

Добавлено: Вт июн 30, 2009 20:47:41
urry
Cогласен с Алексом - такие вещи делать нельзя на таймере. Дело в том, что для получения меандра - прерывания должны происходить с частотой уже не 40, а 80 килогерц. Это через каждые 12 с копейками микросекунд. На Си, при отработке прерывания. происходят незаметные для программиста операции - кроме тех, что описаны в коде - например, в этом случае - сохранение контекста прерывания при вхождении в него и восстановление обратно. Ничего путного Ваш мк в данном случае сделать уже не успеет, кроме того, как формировать эти 40 килогерц .
Именно для этих вещей и придумали ШИМ. :)
Проект прилагаю.

Добавлено: Ср июл 01, 2009 14:09:16
Барсик
А ещё для таймера придумали режим CTC. И никакие прерывания не нужны. Один раз загрузил регистр сравнения и всё. В присоединённом файле пример для таймера 0. Меандр будет на выходе порта B бит 3. ( OC0 ). Таймер считает системную частоту до 50 (0x32) и изменяет уровень на выходе на противоположный.

Добавлено: Ср июл 01, 2009 14:20:59
ikarab
asteroid7 писал(а):И как эта строчка должна работать?

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

PORTA.0 = !(PINA.0);
СИ - не бейсик. Напишите, лучше, изменение порта по человечески, по СИшному:
PORTA ^= (1 << PA0);
Вы б сами попробовли ! Прежде чем такую ЛАБУДЕНЬ не работающую ( в том виде как вы написали ) рекомендовать.

Добавлено: Ср июл 01, 2009 16:26:33
Danko
Согласен с Alex77 и urry, но если частоту поднять до 8 МГц и выше, то может получится и с таймером.

Если 40 кГц для ИК - пульта.
Тогда без таймера не обойтись, ведь с ШИМ подсчитать количество импульсов будет затруднительно.

Добавлено: Чт июл 02, 2009 07:20:18
asteroid7
удалил...

Добавлено: Сб июл 04, 2009 22:43:08
BCluster
ikarab писал(а):
asteroid7 писал(а):И как эта строчка должна работать?

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

PORTA.0 = !(PINA.0);
СИ - не бейсик. Напишите, лучше, изменение порта по человечески, по СИшному:
PORTA ^= (1 << PA0);
Вы б сами попробовли ! Прежде чем такую ЛАБУДЕНЬ не работающую ( в том виде как вы написали ) рекомендовать.
А правильно будет написать PORTA^=0x01

Поясню.

^ - это XOR, он же "ИСКЛЮЧАЮЩЕЕ ИЛИ", он же Сложение по модулю 2
Вспомним его таблицу истинности:

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

x1 x2 y
0  0  0
0  1  1
1  0  1
1  1  0
Пример:

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

PORTA = 0b01100111
XOR     0b00000001 // (это наше 0x01 в бинарном коде)
результ 0b01100110
Как видим поменялся только последний бит. Т.е. если второе слагаемое по модулю 2 "0" оно не влияет на бит. Если он был "1" он "1" и останется. Если был "0" - "0" и останется. Зато если бит будет равен "1" он инвертирует первое слагаемое по модулю 2.
[/code]