Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Приборы, средства и способы измерения величин » Регулируемый генератор импульсов


Регулируемый генератор импульсов

Сообщений 1 страница 30 из 36

1

Доброго времени суток уважаемые форумчане!
Возникла необходимость в генераторе прямоугольных импульсов, обшарив нет я ненашел генераторов частотой выше 500 килогерц (вернее есть один до 4 мегагерц но там регулировка идет ступенями - 31 ступень (джамперами выставляется двоичный код)). Поэксперементировал с таймерами (прочитал с примерами на "Декаде"), по ихним примерам получить частоту больше 490 герц несмог (кварц на тиньке стоит 12 мегагерц)
Сабж хочу собрать на тиньке 2313, регулировка частоты энкодером в обе стороны, частота-ну хотябы до 4 мегагерц, дискретность - пока нерешил(эксперементально).
Поковыряв фьюзы выставил на порт PD2 частоту кварца (12 мегагерц) померял частотомером все в норме есть все 12.
Теперь собственно вопрос - можно ли использовав частоту кварца на порту перехватывать ее и делить получив тем самым нужную мне частоту или всетаки есть какой либо способ получить верхний предел (4 мегагерца) используя таймеры и имея при этом возможность плавной регулировки частоты?
Энкодер думаю поставить на прерывания int0, int1 и обрабатывая прерывания получать в переменные коэффициент деления исходной частоты.
Если есть какие либо мысли помогите пожалуйста (если можно то и код), если что не так прошу не пинать-я только учусь.

0

2

http://www.530.ru/electronics/projects.php?do=p072. Генератор прямоугольных импульсов на AVR. Ридико Л.И. Правда на ассемблере, но идея готовая. AT90S2313 та же тинька 2313.

0

3

Посмотрел я этот генератор, честно говоря я непонял какой у него верхний предел :huh:
Да и к тому же хочется своими руками и мозгами (конечно же и с вашей помощью) дойти к этому и понять как это работает.
Пока вот только удалось получить частоту в 749,9 килогерц на тиньке с 12 мегагерцовым кварцем.
Если вообще без паузы тогда 1 мегагерц но без регулировки.
Вот собственно код.

$crystal = 12000000
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 8
$framesize = 32

Config Pind.6 = Output
Do
Toggle Portd.6
Waitus 0.1
Loop

Честно говоря я недоволен результатом.
Меняя  паузу с шагом в 0,1 всеравно получается большая дискретность.
Пробовал на таймре сделать, так чтобы таймер считал не от нуля (записую в него значение (чем больше тем быстрее переполнение)) и по переполнению переключаю порт-результат еще хуже.
Максимальное чего я добился от таймера 5 килогерц - смех.

Пока ума не приложу как выдавить из тиньки хотябы 4 мегагерца с приемлемой дискретностью  :tired:
Мажет на асме какую нить вставочку можно притулить чтобы пошустрее бегала тинька?
Помогите плис, всю голову уже сломал, мыслей пока никаких . :confused:

Отредактировано lan44 (2012-01-24 00:11:02)

0

4

Вот ссылочка http://radioparty.ru/index.php/device-a … attiny2313 это генератор до 4 мегагерц, исходники  на баскоме,
я пока недостаточно квалифицирован для переделки исходника (пока еще не все понял), посмотрите плис может это поможет.

0

5

Если добавить к ATMEGE88 две микросхемы 74HC4046A(генератор до 20 МГц с фаз.детектором) и 74Hc74 (2 триггера - делитель на 4),
то можно получить генератор до 16 МГц с разрешающей около способностью 20 Гц (1.2*10^-6).
Как:
1 программный DDS регулируемую формирует опорную частоту до 16.00000 кГц. Тактовая частота 200 кГц (5 мкс) формируется таймером 2. Сумматор и частотное число 24 битное.
2 Частота DDS с помощью с ФАПЧ умножается на 1000 = 4(74hc74 в первом каскаде) * 250(на таймер 0)
Еще  масса вариантов

0

6

Спасибо, поковырял даташиты - перевариваю. С одной стороны - высокий вехний предел это хорошо но многовато микросхем да и ехать за ними нужно   а это в ближайшее время не предвидится.
С другой стороны - есть микроконтролер и исходники которые (я так думаю) можно довести до ума, и плюс к этому выучить баском.
Я вот с этими исходниками сижу и немогу понять, каким образом осуществляется выборка нужного значения из таблицы данных, до этого я невидел примеров в баскоме по работе с таблицами.

Вот весь код

Код:
$crystal = 8000000
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 8
$framesize = 32

Dim F As Byte , F_input As Byte , Clkpr_prescale As Byte
Dim Ocr1a_value As Word , Ocr0a_value As Byte
Dim Clock_prescale As Word

Config Pinb.2 = Output
Config Pinb.3 = Output
Config Portd = Input
Portd = &HFF

F = 255

Do
   F_input = Pind And &H1F                                  'check switch combination
   If F <> F_input Then                                     'if changed,
      F = F_input
      Gosub Set_f                                           'set new frequency
   End If
Loop

Set_f:
   Stop Timer0
   Stop Timer1
   Timer0 = 0
   Timer1 = 0
   Ocr0a_value = Lookup(f , Ocr0a_table)
   Ocr1a_value = Lookup(f , Ocr1a_table)
   Clock_prescale = Lookup(f , Clock_prescale_table)
   Clkpr_prescale = 0
   While Clock_prescale > 1
      Shift Clock_prescale , Right
      Incr Clkpr_prescale
   Wend
   Clkpr = &B10000000
   Clkpr = Clkpr_prescale
   If F < 31 Then                                           'f <= table_entries #
      If Ocr0a_value = 0 Then
         Gosub Set_high_f
      Else
         Gosub Set_low_f
      End If
   Else
      Set Portb.3
   End If
Return

Set_high_f:                                                 '4MHz-1Hz
   Decr Ocr1a_value
   Compare1a = Ocr1a_value
   Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1       'start Timer1
Return

Set_low_f:                                                  '0.8Hz-0.1Hz
   Decr Ocr0a_value
   Ocr0a = Ocr0a_value
   Config Timer0 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1       'start Timer0
   Decr Ocr1a_value
   Compare1a = Ocr1a_value
   Config Timer1 = Counter , Edge = Falling , Compare A = Toggle , Clear Timer = 1       'start Timer1
Return

'for $crystal = 8MHz & table_entry 0-26:
'f = 8000000 / (2*clock_prescale*(1+ocr1a_value))

'for $crystal = 8MHz & table_entry 27-30:
'f = 8000000 / (2*clock_prescale*(1+ocr1a_value)) / (2*(1+ocr0a_value))

Clock_prescale_table:                                       '[1-256]
Data 1%                                                     '0: 4 MHz
Data 2%                                                     '1: 2 MHz
Data 4%                                                     '2: 1 MHz
Data 1%                                                     '3: 800 kHz
Data 2%                                                     '4: 400 kHz
Data 4%                                                     '5: 200 kHz
Data 8%                                                     '6: 100 kHz
Data 2%                                                     '7: 80 kHz
Data 4%                                                     '8: 40 kHz
Data 8%                                                     '9: 20 kHz
Data 16%                                                    '10: 10 kHz
Data 4%                                                     '11: 8 kHz
Data 8%                                                     '12: 4 kHz
Data 16%                                                    '13: 2 kHz
Data 32%                                                    '14: 1 kHz
Data 8%                                                     '15: 800 Hz
Data 16%                                                    '16: 400 Hz
Data 32%                                                    '17: 200 Hz
Data 64%                                                    '18: 100 Hz
Data 16%                                                    '19: 80 Hz
Data 32%                                                    '20: 40 Hz
Data 64%                                                    '21: 20 Hz
Data 128%                                                   '22: 10 Hz
Data 32%                                                    '23: 8 Hz
Data 64%                                                    '24: 4 Hz
Data 128%                                                   '25: 2 Hz
Data 256%                                                   '26: 1 Hz
Data 32%                                                    '27: 0.8 Hz
Data 64%                                                    '28: 0.4 Hz
Data 128%                                                   '29: 0.2 Hz
Data 256%                                                   '30: 0.1 Hz
Data 256%                                                   '31: stop


Ocr1a_table:                                                '[1-65535], Ocr1a = Ocr1a_table_entry - 1
Data 1%                                                     '0: 4 MHz
Data 1%                                                     '1: 2 MHz
Data 1%                                                     '2: 1 MHz
Data 5%                                                     '3: 800 kHz
Data 5%                                                     '4: 400 kHz
Data 5%                                                     '5: 200 kHz
Data 5%                                                     '6: 100 kHz
Data 25%                                                    '7: 80 kHz
Data 25%                                                    '8: 40 kHz
Data 25%                                                    '9: 20 kHz
Data 25%                                                    '10: 10 kHz
Data 125%                                                   '11: 8 kHz
Data 125%                                                   '12: 4 kHz
Data 125%                                                   '13: 2 kHz
Data 125%                                                   '14: 1 kHz
Data 625%                                                   '15: 800 Hz
Data 625%                                                   '16: 400 Hz
Data 625%                                                   '17: 200 Hz
Data 625%                                                   '18: 100 Hz
Data 3125%                                                  '19: 80 Hz
Data 3125%                                                  '20: 40 Hz
Data 3125%                                                  '21: 20 Hz
Data 3125%                                                  '22: 10 Hz
Data 15625%                                                 '23: 8 Hz
Data 15625%                                                 '24: 4 Hz
Data 15625%                                                 '25: 2 Hz
Data 15625%                                                 '26: 1 Hz
Data 15625%                                                 '23: 0.8 Hz
Data 15625%                                                 '24: 0.4 Hz
Data 15625%                                                 '25: 0.2 Hz
Data 15625%                                                 '26: 0.1 Hz
Data 0%                                                     '31: stop

Ocr0a_table:                                                '[1-255, 0=not used], Ocr0a = Ocr0a_table_entry - 1
Data 0                                                      '0: 4 MHz
Data 0                                                      '1: 2 MHz
Data 0                                                      '2: 1 MHz
Data 0                                                      '3: 800 kHz
Data 0                                                      '4: 400 kHz
Data 0                                                      '5: 200 kHz
Data 0                                                      '6: 100 kHz
Data 0                                                      '7: 80 kHz
Data 0                                                      '8: 40 kHz
Data 0                                                      '9: 20 kHz
Data 0                                                      '10: 10 kHz
Data 0                                                      '11: 8 kHz
Data 0                                                      '12: 4 kHz
Data 0                                                      '13: 2 kHz
Data 0                                                      '14: 1 kHz
Data 0                                                      '15: 800 Hz
Data 0                                                      '16: 400 Hz
Data 0                                                      '17: 200 Hz
Data 0                                                      '18: 100 Hz
Data 0                                                      '19: 80 Hz
Data 0                                                      '20: 40 Hz
Data 0                                                      '21: 20 Hz
Data 0                                                      '22: 10 Hz
Data 0                                                      '23: 8 Hz
Data 0                                                      '24: 4 Hz
Data 0                                                      '25: 2 Hz
Data 0                                                      '26: 1 Hz
Data 5                                                      '27: 0.8 Hz
Data 5                                                      '28: 0.4 Hz
Data 5                                                      '29: 0.2 Hz
Data 5                                                      '30: 0.1 Hz
Data 0                                                      '31: stop

На первый взгляд код небольшой (большую часть занимают таблицы), вот если бы можно было бы переделать его так чтобы выборка значений шла не из таблиц  а из переменной и отучить контролер смотреть на конфигурацию входных пинов.

0

7

Это программа - просто шарманка.
Максимум, что можно добиться на этом принципе - делить кварц на 2, на 3, на 4 и т.д. до 65535. На 1 получается убогий пичек

0

8

Просматривал форумы по поводу генератора Ридико Л.И. стало ясно - каждая операция занимает такт, чем больше процедур (соответственно длинна программы) тем меньше шансов получить
более высокую частоту на выходе, возникает вопрос - можно ли вообще на баскоме написать достойный генератор меандра (скажем при кварце 20 мегагерц на тиньке) частотой хотябы до 2 мегагерц?
Может это можно реализовать только на асме?
Одного только немогу понять, таймеры, все вроди бы должно было бы работать, сокращай себе время заполнения и получай то что хотел но, чет неработает  :angry:
Может я чет делаю не так? Кто нить пробовал на таймерах выжать максимум?

0

9

Сколько не пробовал - пока немогу получить желаемого.
Вопрос к уважаемому dmm - учитывая ваш профессионализм и знания в асме скажите плис, можно ли добится от этого генератора частоты в 2 мегагерца написав код на асме? Можно ли это организовать в баскоме? Если можно то как?
Я помню ваше высказывание о том что нужно не просто спрашивать а и что либо делать самому, поверьте, в силу своих знаний в баскоме испробовал все что знал (знаю немного) пока не получил результата, надеюсь на вашу помощь.
Я не прошу готовый код, просто небольшой пример который можно развить дальше.

Отредактировано lan44 (2012-02-01 00:54:32)

0

10

Генератор аппаратный, на таймере 0, 1 или 2. Режим FAST PWM. программа его только загружает

0

11

Порыл информацию о режимах, при работе таймера в режиме Fast PWM меняется скважность (отношение периода импульса к его длительности) тоесть ШИМ.
Каким образом можно менять частоту в этом режиме если мне к примеру нужно получить симетричный меандр?

0

12

В режиме FAST PWM (MODE 14) можно регулировать и длительность периода, и длительность импульса. Например, период - ICR1,  длительность - OCR1A, выход - OC1A. Выдерживай соотношение их 1/2 - это меандр.

0

13

Здравствуйте, нужен генератор с регулировкой от 1 до 50 Гц и регулировкой скважности от 25 до 75%, может у кого то есть? Схему (как я её вижу) прилагаю http://s1.uploads.ru/i/26jU1.png

0

14

У меня есть на меге48.

0

15

$regfile = "attiny45.DAT"
$crystal = 1000000

Config Adc = Single , Prescaler = Auto , Reference = Avcc

  Dim V As Word
  Dim W As Single
  Dim R As Byte
  Dim V1 As Word
  Dim W1 As Single
  Dim R1 As Byte

Clkpr = &H80
Clkpr = &H8              'делит частоту
                                             
Tccr0a = &HB1
Tccr0b = &H09
Tcnt0 = 0

Config Portb = Output
Start Adc
          Do
V = Getadc(2)
W = V / 4
R = Round(w)

V1 = Getadc(3)
W1 = V1 / 4
R1 = Round(w1)

Ocr0a = R
Ocr0b = R1                                                  'всё, на выходе оcr0b выход генератора Значение Ocr0a должно быть больше Ocr0b .
' "В эти значения загоняем число от 0 до 255 и получаем частоту."

                            'выводим числовое значение переменной
Loop
End

0

16

Получение сигнала произвольной скважности
Чтобы получить на выходе генератора сигнал произвольной скважности, т.е. сигнал, для которого длительности импульса и промежутка между импульсами не равны, необходимо производить перезагрузку регистра сравнения два раза за период. Это уже требует некоторых действий от программы. Главным здесь является то, что формирование сигнала по-прежнему происходит на аппаратном уровне. Программа лишь загружает нужные значения длительностей, от нее просто требуется успеть это сделать вовремя.
http://s2.uploads.ru/brtkj.gif
Метод получения такого сигнала проиллюстрирован на рисунке. Для примера рассматривается режим генерации положительных импульсов. В момент возникновения события совпадения переключается состояние выхода OC1, который настроен на переключение по совпадению (режим «toggle»). В данном примере он переключается с нуля в единицу. Перезагрузка регистра сравнения OCR1A осуществляется в обработчике прерывания, который вызывается с некоторой задержкой  (эта задержка называется interrupt latency). Перезагрузка должна быть произведена обязательно до того момента, когда должно произойти новое совпадение. Именно время выполнения обработчика прерывания ограничивает минимальную длительность импульсов в данном режиме. Поэтому принят ряд мер для уменьшения этого времени. Перезагрузка осуществляется величиной, которая определяет длительность единицы, в данном примере это длительность импульса d. При следующем совпадении выход OC1 переключается из единицы в ноль и осуществляется перезагрузка регистра сравнения длительностью нуля, в данном примере это разность периода и длительности P-d. Никаких вычислений в прерывании не производится, длительности нуля и единицы основная программа передает сразу «готовыми к употреблению».
Взято отсюда http://www.530.ru/electronics/projects.php?do=p072. Сам использовал такой метод для формирования импульсов. Правда НЧ, но мне так нужно было.

Отредактировано sva-don (2013-04-09 09:25:43)

0

17

Здравствуйте, у меня появилась подобная потребность в генераторе, я его реализовал таким образом, работает, но есть одно но, таймер иногда переполняется по кругу (при малых значениях АЦП) самостоятельно, судя по выводу в терминал, может кто подскажет,в чем проблема?

$regfile = "m32def.dat"
$crystal = 16000000

$baud = 9600

dim set_time as Word

Config Adc = Single , Prescaler = auto , Reference = avcc
Enable Interrupts

Enable Timer1

start adc
Do

set_time = Getadc(0)

Compare1a = set_time

Config Timer1 = Timer , Prescale = 1024 , Compare A = Toggle , Clear Timer = 1
print Timer1;  " "; set_time
loop
end

Отредактировано stas732 (2019-12-07 19:47:09)

0

18

stas732 написал(а):

таймер иногда переполняется по кругу (при малых значениях АЦП) самостоятельно

Если я правильно понял, то у вас таймер заскакивает выше значения set_time. Было у меня такое на Меге8, когда делал MP3 плеер. Победить не смог, пришлось программно игнорировать эти значения.
А зачем вы в главном цикле постоянно конфигурируете таймер? Достаточно сделать это один раз в начале программы.

0

19

Конфигурацию делал по одному из примеров, перенес в начало,при инициализации, эффект тот же

0

20

Пока ограничил  с помощью

Код:
if timer1 > set_time then timer1= set_time

но это костыль

0

21

Код:
if timer1 > set_time then goto подпрограмма

А в этой подпрограмме производите измерение АЦП. У меня так все работает четко.

+1

22

То есть перенести

Код:
set_time = Getadc(0)

в подпрограмму при переходе goto  ?

0

23

Ну, я не знаю, как у вас код устроен. GOSUB подразумевает выход из п/п по RETURN'у. А у вас есть куда выходить?
У меня так сделано:

Код:
 Main:
        Stop Timer1
        Track_number = Timer1 
        If Track_number = 0 Or Track_number > All_tracks Then   ' если значение = 0 или больше максимального
        Start Timer1
        Goto Main 
        End if             
     

0

24

Попробуйте "FREE" режим в АЦП, ибо если сингл, то в режиме "авто" быстрее 1 мс работать скорее всего не будет (1КГц).

0

25

К сожалению ,этот фокус не работает, таймер продолжает заказываться за "горизонт" моей уставки переполнения

0

26

Вы бы выложили весь код, так проще было бы.

0

27

Выложу еще раз,немного изменив

Код:
$regfile = "m32def.dat"
$crystal = 16000000
                                         
$baud = 9600

dim set_time as Word

Config Portd.7 = Output:Portd.7 =0

Config Adc = free , Prescaler = auto , Reference = avcc
Config Timer0 = Timer , Prescale = 1024
Config Timer1 = Timer , Prescale = 1024 , Compare A = Toggle , Clear Timer = 1                                                                        
Enable Interrupts

Enable Timer0
Enable Timer1

On Timer0 button

start adc
main:
   set_time = Getadc(0)
   Compare1a = set_time
goto main
end


button:
   print Timer1;  " ";set_time
return

Отредактировано stas732 (2019-12-09 20:23:04)

0

28

Если указать размер переполнения вручную, в основном цикле, то все в порядке, таймер не переполняется, все работает отлично

0

29

А если так:

Код:

Do
main:
   set_time = Getadc(0)
   Compare1a = set_time
if Timer1 > set_time then goto main
print Timer1;  " ";set_time
loop

0

30

У вас после отсчета таймера, на каждом цикле выполняется "print" (да ещё в прерывании и вешает всю систему), если он работает не через буфер, а напрямую, то происходит как раз задержка и сбивка. Таймер т.к. аппаратный, он успевает за время софтовой отправки данных насчитать.
Выводить данные лучше один раз и в основном теле программы, а как раз в таймер поместить "Compare1a = set_time". Второй таймер можно не использовать. Что-то вроде:

Код:
Config Timer1 = Timer , Prescale = 1024 , Compare A = Toggle , Clear Timer = 1                                                                        
Dim Mem_time as Word
Enable Interrupts

Enable Timer1

On Timer1 L00

start adc
Do
   set_time = Getadc(0)
   If Mem_time<>set_time Then
      Mem_time=set_time
      print Timer1;  " ";set_time
   End If
Loop
End


L00:
   Compare1a = set_time
return

Впрочем по идеи можно и ещё проще:

Код:
Config Timer1 = Timer , Prescale = 1024 , Compare A = Toggle , Clear Timer = 1                                                                        
Dim Mem_time as Word
Enable Interrupts

Enable Timer1

start adc
Do
   set_time = Getadc(0)
   If Mem_time<>set_time Then
      Mem_time=set_time
      Compare1a = set_time
      print Timer1;  " ";set_time
   End If
Loop
End

В общем, на время изменения параметра сравнения, надо останавливать таймер, иначе он сравнивать будем скажем с числом 15, а таймер уже пролетел это число и получается пропуск (полный цикл). Конечно первый вариант кода более синхронный, т.к. загрузка изменения происходит на новом цикле.

0


Вы здесь » Программирование ATMEL в BASCOM. » Приборы, средства и способы измерения величин » Регулируемый генератор импульсов