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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Таймеры, ШИМ и все про них » Генератор с раздельной регулировкой длительности и периода импульсов


Генератор с раздельной регулировкой длительности и периода импульсов

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

1

Всем добрый день.Решил попробовать свои силы в программирование микроконтроллеров.Опыт в этой области-полный ноль.В общем вот попробовал написать небольшую программку,цель-генератор с  раздельной регулировкой длительности и периода импульсов.Генерация в Proteuse есть,вот только не могу сообразить как задействовать регулировку.

'================================ГЕНЕРАТОР======================================

$regfile = "m16def.dat"
$crystal = 10000000
$hwstack = 40
$swstack = 16
$framesize = 32

'==========================КОНФИГУРАЦИЯ ДИСПЛЕЯ=================================

Config Lcd = 20 * 4
Config Lcdpin = Pin , Rs = Portb.7 , E = Portb.6 , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.1 , Db7 = Portb.0
Cursor Off                                                 'курсор выключить

'==========================КОНФИГУРАЦИЯ ПОРТОВ-УСТРОЙСТВ========================
Config Portc.0 = Input
Config Portc.1 = Input
Config Pind.5 = Output

'==========================ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ==============================
Set Portc.0
Set Portc.1

'==========================КОНФИГУРАЦИЯ ТАЙМЕРА=================================

Config Timer0 = Timer , Prescale = 1
On Timer0 Tik
Enable Interrupts                                          'разрешить прерывания
Enable Timer0
Config Debounce = 30                                        'тут задаем время опроса кнопки - 30 милесекунд

'==========================ПРИСВАИВАЕМ ИМЕНА ПИНАМ==============================
Verh Alias Portc.0
Vniz Alias Portc.1
Imp Alias Portd.5

'==========================ОБЪЯВЛЯЕМ ПЕРЕМЕННЫЕ=================================

Dim Period As Word                                         ' для изменения периода импульсов
Dim Dlitel As Word                                         'для изменения длительности импульсов
Dim Pulse As Word                                          'для формирования импульсов

'===========================ОСНОВНАЯ ПРОГРАММА==================================

Do

Period = 155                                               'именение периода
Dlitel = 122                                               'именение длительности

Locate 1 , 1
Lcd "1"

Loop

'===========================ФОРМИРОВАНИЕ ИМПУЛЬСОВ==============================
Tik:

Incr Pulse
If Pulse > Period Then Pulse = 0                           'формирование периода
If Pulse < Dlitel Then                                     'формирование длительности
Imp = 1
Else
Imp = 0
End If

Return

0

2

А не надежнее ли регулировать импульсы самим таймером, а не криво считать это прериванием, которое вполне вероятно может даже не успевать выполняться полностью в заданный период времени (прескайл=1)?

0

3

А как это можно реализовать?

0

4

В прерывание пихаем передергивание бита порта/выхода (1 или 0) + анализ того, сколько держать 1 или 0 (сколько тактов прерывания).
А регулировку частоты делаем через установку таймера в нужное значение и прескэйлом (в зависимости от диапазона) + установку сколько держать 1 или 0.
Вообще всё это напоминает ШИМ... почитайте, может вам этого будет достаточно.

0

5

Спасибо за ответ.Вы наверное имели в виду такой код

Код:
dim x as integer
Config Timer1 = Timer , Prescale = 1024 : On Timer1 Pulse : Enable Interrupts : Enable Timer1' подобрать значение делителя вместо 1024 под себя
config portb.1 = output

do
incr x
waitms 100
loop

Pulse:
togle portb.1
timer1 = x
return

0

6

Не совсем так, Тогл просто всегда инвертирует значение бита, а нам нужно четко держать вначале единицу в порте, потом ноль.
Т.е. как-то так:

Код:
Dim Pd As Byte
Dim S As Byte
Dim T As Byte   ' временное хранение
Config Timer0 = Timer , Prescale = 1024                      ' 1, 8, 64, 256, 1024
On Timer0 Pulse

Timer0 = 255  ' чтобы как можно скорее сработало первое прерывание таймера
T = 0
Pd = 1    ' регулируем частоту импульса
S = 1    ' скважность
Enable Timer0
Enable Interrupts

Do
         ' Тут регулируя значения S и Pd (кнопками или чем там управляем)
Loop

Pulse:
         Timer0 = Pd
         If T = 255 Then T = 0
         If T < S Then
                  PORTB.1 = 1
         Else
                  PORTB.1 = 0
         End If
         Incr T
Return

Как-то так...ещё только инициализацию портов добавьте.

зы: чем меньше делитель таймера (прескэйл) - тем быстрее должен выполняться код в прерывании, если он будет медленным, то всё будет тормозиться/растягиваться.

Отредактировано RDW (2012-02-13 18:08:19)

0

7

А вообще может вам это подойдет: http://avrproject.ru/publ/pwm_bascom/1-1-0-37

0

8

RDW огромное спасибо за участие!Решил пару дней отдохнуть,а то в голове уже каша.Довольно сложно осваивать все это с нуля-тем более что опыта нет вообще.К стати кнопки к своей программе прикрутил,сейчас колдую над отображением периода и длительности на LCD-пока безрезультатно.

'================================ГЕНЕРАТОР======================================

$regfile = "m16def.dat"
$crystal = 10000000
$hwstack = 40
$swstack = 16
$framesize = 32

'==========================КОНФИГУРАЦИЯ ДИСПЛЕЯ=================================

Config Lcd = 20 * 4
Config Lcdpin = Pin , Rs = Portb.7 , E = Portb.6 , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.1 , Db7 = Portb.0
Cursor Off                                                 'курсор выключить
Locate 1 , 1
Lcd " ЎEHEPATOP ҐMЁ©§bCOB"

'==========================КОНФИГУРАЦИЯ ПОРТОВ-УСТРОЙСТВ========================
Config Pinc.0 = Input
Config Pinc.1 = Input
Config Portd.5 = Output

'==========================ПОДТЯГИВАЮЩИЕ РЕЗИСТОРЫ==============================
Set Portc.0
Set Portc.1

'==========================КОНФИГУРАЦИЯ ТАЙМЕРА=================================

Config Timer0 = Timer , Prescale = 1
On Timer0 Tik
Enable Interrupts                                          'разрешить прерывания
Enable Timer0
Config Debounce = 30                                       'тут задаем время опроса кнопки - 30 милесекунд

'==========================ПРИСВАИВАЕМ ИМЕНА ПИНАМ==============================
Verh Alias Pinc.0
Vniz Alias Pinc.1
Imp Alias Portd.5

'==========================ОБЪЯВЛЯЕМ ПЕРЕМЕННЫЕ=================================

Dim Period As Word                                         ' для изменения периода импульсов
Dim Dlitel As Word                                         'для изменения длительности импульсов
Dim Pulse As Word                                          'для формирования импульсов

Dim X As String * 3

Period = 35                                                'именение периода
Dlitel = 15                                                'именение длительности

'===========================ОСНОВНАЯ ПРОГРАММА==================================

Do

Debounce Verh , 0 , Vv , Sub
Debounce Vniz , 0 , Vn , Sub

X = Str(dlitel)
X = Format(x , "000")

Locate 2 , 1
Lcd X
Locate 2 , 5
Lcd "ms"

Loop

End

'===============================================================================
Vv:

Incr Dlitel                                                'прибавляем по 1
Return

'===============================================================================
Vn:

Decr Dlitel                                                'вычитаем по 1
Return

'===========================ФОРМИРОВАНИЕ ИМПУЛЬСОВ==============================
Tik:

Incr Pulse
If Pulse > Period Then Pulse = 0                           'формирование периода
If Pulse < Dlitel Then                                     'формирование длительности
Imp = 1
Else
Imp = 0
End If

Return

0

9

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

Вы кстати в своём коде забываете всё время контролировать таймер (или вам это не нужно)...

Можно кстати "Imp = 1" заменять так же на "Set Imp" и "Reset Imp" соответственно. Так наверное правильнее.

Отредактировано RDW (2012-02-13 21:19:32)

0

10

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

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

Осциллограф на борту имеется.Прекрасно понимаю что Proteus не панацея-в железе отлаживать намного наглядней и надежней.Прежде чем начинать писать большую программу,освоил подключение LCD,написал небольшую менюшку с навигацией ,поморгал светодиодами.Все что удачно получилось сохраняю-типа исходник.Влип именно при освоении таймера,прерываний по таймеру,переменные. В данный момент решил собрать стенд для отладки,вот ссылка Стенд AVR.

0

11

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

Вы кстати в своём коде забываете всё время контролировать таймер (или вам это не нужно)...

Вы не могли бы поточнее объяснить как контролировать таймер?

0

12

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

Вы не могли бы поточнее объяснить как контролировать таймер?

В моём коде строки "Timer0 =", причем при активации прерывания это строка должна быть первой, чтобы сократить влияние алгоритма программы прерывания на сам отсчет прерывания.
Или вы собираетесь регулировать только скважность, а не частоту?

0

13

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

Осциллограф на борту имеется.Прекрасно понимаю что Proteus не панацея-в железе отлаживать намного наглядней и надежней.Прежде чем начинать писать большую программу,освоил подключение LCD,написал небольшую менюшку с навигацией ,поморгал светодиодами.Все что удачно получилось сохраняю-типа исходник.Влип именно при освоении таймера,прерываний по таймеру,переменные. В данный момент решил собрать стенд для отладки,вот ссылка Стенд AVR.

Расширять функционал ещё можно по I2C (там есть: память, АЦП, ЦАП, порты, датчики...).
Идея хороша, только по мне не хватает уменьшения габаритов, на сегодняшний день главное - минимализм.

Отредактировано RDW (2012-02-14 10:30:27)

0

14

Всем добрый вечер.В продолжении темы, решил для регулировки периода и длительности импульсов прикрутить энкодер. В железе попробовал-работает на ура.Хотелось бы услышать мнения по поводу корректности написанного кода.

Код:
'==============================ЭНКОДЕР+ГЕНЕРАТОР================================

  $regfile = "m16def.dat"
  $crystal = 10000000
  $hwstack = 40
  $swstack = 16
  $framesize = 32


'=============================КОНФИГУРАЦИЯ ДИСПЛЕЯ==============================
  Config Lcd = 16 * 2
  Config Lcdpin = Pin , Rs = Portb.7 , E = Portb.6 , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.1 , Db7 = Portb.0
  Cursor Off                                                'курсор выключить
  Locate 1 , 1
  Lcd "   ЎEHEPATOP    "

'=============================ПРИСВАИВАЕМ ИМЕНА ПИНАМ===========================
  Cha Alias Pind.2
  Chb Alias Pind.3
  Vv Alias Pind.0
  Imp Alias Portd.5

'==============================КОНФИГУРАЦИЯ ПОРТОВ==============================
  Config Portd.0 = Input
  Config Portd.2 = Input
  Config Portd.3 = Input
  Config Portd.5 = Output

'=============================ВКЛЮЧИТЬ ВНУТРЕННИЕ РЕЗИСТОРЫ=====================
  Set Portd.0
  Set Portd.2
  Set Portd.3

'=============================КОНФИГУРАЦИЯ ТАЙМЕРА==============================
  Config Timer0 = Timer , Prescale = 1
  On Timer0 Tik
  Enable Timer0
  Timer0 = 255

  Config Debounce = 50                                      'боремся с дребезгом

  Config Int0 = Falling
  Const Debouncetime = 1
  On Int0 Getencoder
  Enable Interrupts
  Enable Int0
'=============================ПЕРЕМЕННЫЕ========================================

  Dim Encounter As Integer
  Dim Button As Bit

  Dim Period As Word
  Dim Dlitel As Word
  Dim Pulse As Word
  Dim X As String * 3
  Dim Y As String * 3

  Period = 35
  Dlitel = 20

  Encounter = 0


'===============================================================================
Do

 Debounce Vv , 0 , Knopka , Sub                             'переход на (Knopka) по нажатию клавиши


 X = Str(dlitel)
 X = Format(x , "000")
 Y = Str(period)
 Y = Format(y , "000")
 Locate 2 , 8
 Lcd Y
 Locate 2 , 12
 Lcd "ms"
 Locate 2 , 1
 Lcd X
 Locate 2 , 5
 Lcd "ms"
Loop


'===============================================================================

Knopka:

Toggle Button                                               'инвертируем переменную Button

Return


'============================ПОДПРОГРАММА ПО ПРЕРЫВАНИЮ=========================
Getencoder:


 Waitms Debouncetime

 If Cha = 0 And Button = 0 Then
 If Chb = 0 And Button = 0 Then Incr Period Else Decr Period
 End If
 If Cha = 0 And Button = 1 Then
 If Chb = 0 And Button = 1 Then Incr Dlitel Else Decr Dlitel
 End If
 Gifr = 64

 Return


'===========================ФОРМИРОВАНИЕ ИМПУЛЬСОВ==============================
Tik:

 Incr Pulse
 If Pulse > Period Then Pulse = 0
 If Pulse < Dlitel Then
 Imp = 1
 Else
 Imp = 0


 End If

 Return



'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Отредактировано angald (2012-03-02 17:02:50)

0


Вы здесь » Программирование ATMEL в BASCOM. » Таймеры, ШИМ и все про них » Генератор с раздельной регулировкой длительности и периода импульсов