нет, я просто хотел сделать генератор для разных целей.
расчет брал из книги по AVR контроллерам, но не пойму или я чего то не понимаю, или там не правильно написано)
OCR1A = 32; //число сравнения для таймера T1 для формирования прерываний с частотой 250000Гц
TIMSK = (1<<OCIE1A); //разрешить прерывание по совпадению T1
TCCR1A =(0<<WGM11)| (0<<WGM10); //режим таймера T1 = CTC сброс при совпадении
TCCR1B =(0<<WGM13)| (1<<WGM12)| //режим таймера T1 = CTC сброс при совпадении
(0<<CS12)| (0<<CS11)| (1<<CS10); //предделитель = 1
Чтобы получить частоту 125000, надо прерывания вызывать в 2 раза чаще.... за 2 вызова как раз получим 2 изменения уровня, т.е. один период частоты 125000.
Но с такой частотой на Си скорее всего не будет работать, т.к. прерывания могут просто не успевать выполнятся (ну прям если только в прерывании инвертирование вывода и все, то успеет, а если там еще чего то будет, то нет)
Такую функцию лучше сделать на железной функции таймера, инвертирования вывода порта (там есть несколько выводов, у которых есть такая функция)
OCR1A = 32; //число сравнения для таймера T1 для формирования прерываний с частотой 250000Гц
TIMSK = (1<<OCIE1A); //разрешить прерывание по совпадению T1
TCCR1A =(0<<WGM11)| (0<<WGM10); //режим таймера T1 = CTC сброс при совпадении
TCCR1B =(0<<WGM13)| (1<<WGM12)| //режим таймера T1 = CTC сброс при совпадении
(0<<CS12)| (0<<CS11)| (1<<CS10); //предделитель = 1
Чтобы получить частоту 125000, надо прерывания вызывать в 2 раза чаще.... за 2 вызова как раз получим 2 изменения уровня, т.е. один период частоты 125000.
Но с такой частотой на Си скорее всего не будет работать, т.к. прерывания могут просто не успевать выполнятся (ну прям если только в прерывании инвертирование вывода и все, то успеет, а если там еще чего то будет, то нет)
Такую функцию лучше сделать на железной функции таймера, инвертирования вывода порта (там есть несколько выводов, у которых есть такая функция)
Проверял в Proteus'е у меня получилось 121213 Гц
вот исходник:
.include "tn2313def.inc"
.list
.def tmp = r16
.def _out = r17
.equ _ctc = 32
.cseg
.org 0
main: rjmp res
.org 4
rjmp int_tm1
.org 19
res: ldi tmp,RAMEND
out SPL,tmp
ser tmp
out DDRB,tmp
out PORTB,tmp
ldi tmp,0x09
out TCCR1B,tmp
clr tmp
out TCCR1A,tmp
ldi tmp,high(_ctc)
out OCR1AH,tmp
ldi tmp,low(_ctc)
out OCR1AL,tmp
ldi tmp,0x40
out TIMSK,tmp
ldi tmp,0x80
out ACSR,tmp
sei
ldi _out,1
m1: rjmp m1
int_tm1: ldi r18,1
eor _out,r18
mov r18,_out
out PORTB,_out
reti
дело не в 125кГц, просто я не пойму почему режется частота в 4 раза (8000000/256=31250) а у меня получается 7812
Oleg7771 писал(а):сделал ещё проще, взял формулу из datasheet и по ней написал программу )
Прииииикольно... спасибо.
А мне чет в голову не пришло программку накалякать, хотя мелкие программки для PC тоже ваял.
Я еще проще делал, формулу в EXCEL вставил, тоже не плохо было...
Попробую теперь твоей попользоваться.
PS Ошибочку углядел.....
Там где у тебя окошко OCR1AH написано ORC1AH.....
Ничего.... мож для прикола так и оставить.....
Когда будут обращать внимание на это, говори что это проверка на невнимательность...
спасибо что указал на ошибку, я как то не обратил внимания. В EXEL тоже делал, мне показалось что не очень удобно.
Хочу доработать программку чтобы можно было вводить OCR1A и сразу видеть реальную частоту, в этой же программе просто сделаю ещё одно поле для ввода и немного мелких доделок.
Меня ещё один вопрос интересует, хочу сделать регулятор мощности (фазо-импульсный) т.е. чтобы сетевая частота 20мс вызывала внешнее прерывание (синхронизация), и по этому импульсу в обработчике прерывание с помощью ШИМ генерировать импульс определенной ширины (менять угол открытия) на выход для управления симистором.
Только вот не знаю как правильно это синхронизировать?
по первой ссылке нашел исходник, судя по нику похоже твой) переделал его под CAVR, сразу не компилировался кучу матюков писал) собрал схему, регулирует, но с мерцанием как один полупериод, и почти перед самым максимумом тухнет лампа.
хотел спросить, может быть дело в детекторе нуля? на другом форуме нашел диммер на pic16f629 там в место детектора подается сетевое напряжение через резистор 10М и я так сделал, так же пробовал по схеме http://forum.easyelectronics.ru/downloa ... =10066&t=1 тоже самое
Твой детектор не выделяет переход через 0, а просто помечает одну полуволну как 0, другую полуволну как 1, поэтому надо ловить изменения на выходе резистора, это и будет переход через 0.
И еще, резистор 10М наверное многовато, при таком большом сопротивлении уже будет сказыватся емкость дорожек, входа контроллера, может переход не правильно ловить.... поставь 1М...
всё равно мерцает, буду делать детектор нуля ) А на счет того что в крайнем положении ближе к максимуму симистор закрывается, это тоже от этого может быть?
схема та же и осталась, что была с исходником на сайте. Сделал детектор нуля всё равно мерцает, в чем проблема не пойму в proteus работает правильно. Схема детектора нуля что я собрал (файл zero.jpg) в архиве, также проект proteus и исходник для CAVR.
Изменил в протеусе форму сигнала детектора нуля, раскомментировал новый фрагмент, который выше показал, закомментировал старый...
Все как и положено сейчас....
Сделай просто резистор 1М и не заморачивайся, сейчас я сделал для резистора...
А частота в железе 8МГц? может 1МГц стоит....
А вообще если нужна гальваническая развязка то лучше на оптроне...
извиняюсь, это я протупил, когда ввел твоё изменение забыл скомпилировать зашил тоже самое что было. С исправлением заработало без детектора нуля, через 10М. спасибо за помощь )