Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

мдэ...

Отправлено nestandart 22 октября 2009, г. 23:12
В ответ на: Мега8 Встроенный ген-р 1МГц. Листинг прилагается. отправлено пользователем Fantomas 22 октября 2009, г. 22:55

видимо 36 кГц для "TSOP" ...
вот примерно обьяснено, как сделать эти 36 кГц
правда сделано на прерывании переполнения.
на асм сам справишься перевести.


для светодиода лучше будем использовать ножку C0.
т.к. альтернативная функция предложенной ножки D2
является внешнее прерывание INT0. Лучше подобные
интересные ножки экономить для чего то более важного.


имеем
период частоты тактирования микроконтроллера:
T(8MHz) : 1/800000000Гц = 0,000000125 sek
период частоты 36 кГц:
T(36kHZ) : 1/36000Гц = 0,000027777 sek
длительность импульса или длительность паузы между импульсами частоты 36 кГц при коэффициенте заполнения равному 50%:
T(36kHZ/2) : (1/36000)/2 = 0,000013888 sek

предделитель таймера-0 ставим равным единице:
в регистре TCCR0 в биты
Bit 2:0 – CS02:0: Clock Select записываем 001
TCCR0 = 0b00000001

расчитаем период переполнения таймера-0.
мы установили у таймера-0 предделитель равный 1, то есть он считает с тактовой частотой µC. поэтому получаем:
T(OVF)=256*1/800000000Гц = 0,000032 sek
(256 - это число тактовых импульсов для заполнения всех восьми бит таймера-0, т.к. он восьмибитный)

находим число предустановки таймера-0.
длительность импульса частоты 36 кГц делим на период тактирования таймера-0:
T(36kHZ/2)/T(8MHz) = 0,000013888 sek / 0,000000125 sek = 111,04
округляем до целой доли, получаем число 111.
т.к. восьмибитный таймер считает от нуля, вычитаем:
256-111 = 145

ради этого 145 и все расчёты:)



грубые вычисления окончены.
пишем код.

; настраиваем ножку C0 на выход.
DDRC0=OUT
; настраиваем ножку D3 на вход.
DDRD3=IN

; инициализация таймера-0
TCCR0 = 0b00000001 ; устанавливаем предделитель таймера-0 равным единице.

; инициализируем внешнее прерывание на низкий уровень (т.к. у TSOP активный уровень - низкий, нуль)
;Bit 3, 2 – ISC11, ISC10: Interrupt Sense Control 1 Bit 1 and Bit 0
MCUCR = 0b00000000 ; поэтому биты #3 и #4 должны быть нулём.


MAIN_LOOP:
; тут идёт основной цикл основной программы
; светим, управляем, гасим, включаем
; или просто обогреваем окружающую среду,
; можно отправить микроконтроллер в спячку
; коммандой sleep, или выполнять какие либо вычисления...
; bla - bla - bla
; можно пройтись проверкой по нужным флажкам,
; например проверить и что то сделать (не забыть его потом сбросить!),
; если флаг "TSOP_IS_ACTIV" установлен.

; в какой то момент решаем посветить светодиодом
; и проверить TSOP. для этого переходим на подпрограмму TEST_TSOP
rcall INIT_TSOP

; bla - bla - bla
; тут дальше шуруем в основном цикле
; bla - bla - bla
; bla - bla - bla
; пока не упрёмся в его конец
rjmp MAIN_LOOP ; конец основного цикла, прыгаем на начало.


; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
; тут ниже идут подпрограммы, прерывания и всякая требуха...
; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

; !!! ИНИЦИАЛИЗАЦИЯ ПРОВЕРКИ TSOP !!!
INIT_TSOP:
; инициализируем количество вспышек в пачке:
flash_counter=40 ; ставим удвоенное число.
; разрешаем прерывание по переполнению таймера-0:
; Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable
TIMSK = 0b00000001 ; для этого устанавливаем бит #0 в регистре TIMSK
; сбрасываем µC-флаги прерывания INT1 (это очень важно! повышает надёжность от непредусмотренных прерываний):
; Bit 7 – INTF1: External Interrupt Flag 1
GIFR = 0b10000000 ; для этого устанавливаем бит #7 в регистре GIFR
; разрешаем внешнее прерывание INT1:
; Bit 7 – INT1: External Interrupt Request 1 Enable
GICR = 0b10000000 ; для этого устанавливаем бит #7 в регистре GICR
RET ; возвращаемся


; !!! ПРЕРЫВАНИЕ ПО ПЕРЕПОЛНЕНИЮ ТАЙМЕРА-0 !!!
; TIMER0 OVF Timer/Counter0 Overflow
T0_OVFL_INT:
; во-первых загружаем в счётчик расчётное число предустановки:
TCNT0=145
; во-вторых убавим счётчик вспышек на один:
flash_counter=flash_counter-1
; и проверим, не обнулился ли он:
if flash_counter==0
then { ; если обнулился ...
; 1. запрещаем прерывание по переполнению таймера-0
; Bit 0 - TOIE0: Timer/Counter0 Overflow Interrupt Enable
TIMSK = 0b00000000 ; для этого сбрасываем бит #0 в регистре TIMSK
; 2. запрещаем внешнее прерывание INT1
; Bit 7 - INT1: External Interrupt Request 1 Enable
GICR = 0b00000000 ; для этого сбрасываем бит #7 в регистре GICR
; 3. выходим из прерывания
RETI
}
else{ ; а если счётчик вспышек не обнулился...
; инвертируем удобным нам способом ножку для светодиода
invert LED_PIN ; LED_PIN мы определили для C0!!
; и выходим из переывния
RETI
}

; !!! ВНЕШНЕЕ ПРЕРЫВАНИЕ INT1 !!!
;INT1 External Interrupt Request 1
TSOP_INT:
; если мы тут оказались , это значит что:
; 1. внешнее прерывание INT1 разрешено
; 2. на выходе TSOP оказался низкий уровень сигнала
set flag "TSOP_IS_ACTIV" ; устанавливаем флаг "TSOP_IS_ACTIV"
; и выходим из прерывания
RETI



после написания кода. компилируем. и контролируем в симуляторе период прерывания.
(или период вспышек светодиода в пачках)
если надо - корректируем число 145 в ту или другую сторону.


Составить ответ | Вернуться на конференцию.

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
введите число 69:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru