Обсуждаем контроллеры компании Atmel.
Ответить

Atmega128 Timer3 режим захвата

Сб июл 29, 2017 08:15:07

Всем доброго дня! Возникла небольшая проблема с Timer3 Atmega128 в режиме захвата. С данным МК работаю впервые. Проблема в том, что Timer 3 при вычислении направления ветра выдает какие-то непонятные, изменяющие цифры, а скорость кажет правильно.
20170728_.jpg
(16.58 KiB) Скачиваний: 652

Все это реализовано следующим образом:
МК измеряет направление и скорость ветра. Измерения производятся с помощью прямоугольных сигналов, которые поступают от ветроуказателя(М63М-1). Поступают два сигнала с одинаковой частотой, но 2-ой сдвинут по фазе относительно 1-го. По частоте определяем V ветра, а по фазе направление.
Ветер.jpg
(29.61 KiB) Скачиваний: 611

Программа в Bascom написано по следующему алгоритму:
1 Конфигурируем Timer1 и Timer3 режим захвата, по нараставшему фронту сигнала;
2. На вход IC1(PD4) подается 1-ый сигнал, а на IC3(PE7) 2-ой - сдвинутый по фазе;
3. По приходу импульса на IC1 останавливаем Timer1 берем значение Timer1 – вычисляем частоту. Тут же останавливаем Timer3 берем значение – вычисляем фазу по формуле t=(фаза/180)*период => фаза = (t*180)/period , где t - время для Timer3
Частота вычисляется точно(измерял осциллографом, а вот с фазой беда. Формулы взяты из технического описания М63М-1
Код:
$regfile = "m128def.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 32
$framesize = 32
'----------
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5

'----------
Dim Errord1 As Bit , Errord2 As Bit                                                                  'переменные  для температуры
Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte

Dim A As Byte , A2 As Byte , N As Byte                                                                'переменные  для температуры
Dim B As Byte , B2 As Byte
Dim Ss1 As Byte , Ss2 As Byte
Dim D As Byte , D2 As Byte
Dim E As Byte , E2 As Byte
Dim Zahvatvrem As Word , Zahvatvrem1 As Word , Perphazi As Word , Ugol1 As Word ,Phaza As Word   'переменные  для ветра                                                                                           
Dim Period1 As Single , Per1 As Single , Ugol As Single , Sdvig As Single
Dim Chastota As Single
Dim Sd As String * 3                                                                                            'скорость   ветра
Dim Znak As String * 1 , Znak1 As String * 1 , Znak2 As String * 1                         'переменные  для температуры


'----------
Config Timer1 = Timer , Prescale = 1024 , Capture Edge = Rising , Noise Cancel = 1 , Clear Timer = 1
Config Portd.4 = Input
Enable Interrupts
Enable Capture1
Enable Timer1
Start Timer1
Zahvatvrem = 0
'----------
Config Timer3 = Timer , Prescale = 1024 , Capture Edge = Rising , Noise Cancel = 1           
Config Porte.7 = Input..
Enable Capture3
Enable Timer3
Start Timer3
Zahvatvrem1 = 0

'----------
Config Pinc.7 = Input
Config Portd.7 = Output
Config Portd.2 = Output
Yug Alias Pinc.7                    ' Вход для сигнала от геркон
Osnovnaya Alias Portd.2        ' Сигналы на входы IC1,IC3 МК входы подаются через оптопары.  Через этот порт коммутируем
Sdvinut Alias Portd.7             ' То же самое
Reset Osnovnaya
Reset Sdvinut
Reset Yug
'----------

On Capture3 Zahvat3
On Capture1 Zahvat1
Const Pha = 0 , 01152                                       '   180* 0.000064   для удобства вычислений
Const T = 0.000064                                          '   (1024*65536/16 000 000)/65536  -примерное время за
                                                             '  которое  значение Timer1,Timer3 увеличивактся на 1

Do

Set Osnovnaya 
Reset Sdvinut
Gosub Skorost
Gosub Napravlenie
Gosub Datchik1
Gosub Datchik2
Gosub Pokaz
Loop

End

Napravlenie:
If Yug = 1 Then                                             'добавлено временно, чтобы узнать где юг. В М63М в этом положении есть геркон
Ugol1 = 180
Else
  If Period1 = 0 Then
      Ugol1 = 0
       Else                                                 ' Ugol=(180*t)/period1  ,где t= Phaza*T    Pha=180*T
Per1 = Phaza / Period1
Ugol = Pha * Per1
Ugol1 = Round(ugol)
    End If

End If
Phaza = 0
Return

'----------
Skorost:
Period1 = Zahvatvrem * T                                    'получаем время для вычисления частоты
If Period1 = 0 Then
Chastota = 0
Else
Chastota = 1 / Period1
End If
Sd = Fusing(chastota , "#.#")
Return
'----------
'----------
'----------
'Тут код для датчиков температуры
----------
Pokaz:
Locate 1 , 1
If Ugol1 < 100 Then Lcd Chr(7) ; " " ; Sd ; " m/c" ; "  " ; "0" ; Ugol1 ; Chr(2) ; " "       'выводим на LCD
If Ugol1 < 10 Then Lcd Chr(7) ; " " ; Sd ; " m/c" ; "  " ; "00" ; Ugol1 ; Chr(2) ; " "
If Ugol1 > 99 Then Lcd Chr(7) ; " " ; Sd ; " m/c" ; "  " ; Ugol1 ; Chr(2) ; "     "
Ugol1 = 0

Locate 2 , 1
If Errord1 = 1 Or Errord2 = 1 Then
   If Errord2 = 1 Then
      Errord2 = 0
   Lcd Chr(1) ; " " ; Znak1 ; Ss1 ; Chr(2) ; "C" ; "  " ; Chr(0) ; "-Error"
       Else
    If Errord1 = 1 Then
       Errord1 = 0
    Lcd Chr(1) ; "-Error" ; "  " ; Chr(0) ; " " ; Znak2 ; Ss2 ; Chr(2) ; "C "
      End If
   End If
Else
Lcd Chr(1) ; " " ; Znak1 ; Ss1 ; Chr(2) ; "C" ; "  " ; Chr(0) ; " " ; Znak2 ; Ss2 ; Chr(2) ; "C "
End If
Return

'*******************************************************************************


Zahvat1:
Stop Timer1
Stop Timer3
Zahvatvrem = Timer1                                         'берем значение для вычисления скорости ветра
Phaza = Timer                                              'берем значение для вычисления напрвления ветра
Timer1 = 0
Start Timer1
Start Timer3
Return


Zahvat3:
Timer3 = 0                                                  'обнуляем значение Timer 3
Return

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 09:13:22

Для определения фазы не надо так усложнять.
Я Ваш код не глядел. В обработчике прерывания захвата от таймера 1, считайте значения порта второй частоты. Если 1 - это в одну сторону, если 0, то в другую.

Добавлено after 6 minutes 9 seconds:
Картинку с импульсам потом поглядел. Если импульсы действительно такие узкие, то такой метод может и не сработать.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 09:21:25

В обработчике прерывания захвата от таймера 1, считайте значения порта второй частоты

Так тут я так и делаю:
Код:
Zahvat1:
Stop Timer1
Stop Timer3
Zahvatvrem = Timer1                                         'берем значение для вычисления скорости ветра
Phaza = Timer3                                              'берем значение для вычисления напрвления ветра
Timer1 = 0
Start Timer1
Start Timer3


В прерывании Timer1 остонавливаю Timer3 и беру его значение в переменную Phaza для определения фазы

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 09:27:53

Нет. Вы не поняли. Я Вам предлагал считать не значение таймера, а логический уровень на порте. Но так сработает только если скважность следования импульсов близка к 50%, а на картинке (которую я поглядел позже) это не так.

Я уже немного поглядел описание на "вентилятор". Я гляжу там герконы. Они могут дребезжать.

Добавлено after 3 minutes 12 seconds:
Я баском не знаю.

В обработчике прерывания захвата таймера 1 не надо останавливать таймер.

Вошли в прерывание таймера 1. Сразу обнулили оба таймера. Для расчетов используйте захваченные данные обоих таймеров.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 09:35:09

Герконы - это в новой версии. У меня старая версия "вентилятора" с блокинг генераторами. Там сигнал приходит без всяких помех.
Я Вам предлагал считать не значение таймера, а логический уровень на порте.


Для определения фазы предлагаете значение Timer1 брать , когда Timer3 прерываться по возрастанию фронта?

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 09:43:18

У Вас импульсы точно такие узкие? Если скважность 50% , то одного таймера хватит.

По таймерам.
Когда происходит событие захвата. Оно не только генерирует прерывание, а еще и аппаратно записывает значение таймера в регистр захвата ICR. Значения из этих регистров и надо использовать для расчета.

По таймеру 1 Вы считаете частоту. По таймеру 3 фазу.

Обработчик прерывания таймера 3 не нужен.
В обработчике захвата таймера 1. Обнуляете оба таймера, а для расчетов используете захваченные данные и регистров захвата.

Еще надо предусмотреть возможность переполнения таймеров. Ну например когда частота очень низкая.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 10:12:14

Сейчас измерю осциллографом сигнал и скину скрин

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 11:03:29

По поводу обработки переполнения таймеров при измерении длительности периода вот тут поглядите. Там ассемблер, но это не имеет значение, такой алгоритм можно организовать на любом языке.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 12:14:51

Снимок11.jpg
(214.3 KiB) Скачиваний: 642


Осциллограмма сигналов на входах МК. Со скважностью проблем нет.
Согласно этой осциллограмме у меня должно показать где-то 30 градусов( на рисунке измерение взято по спаду, а надо было по нарастанию Timer1 ) Ветроуказатель примерно так и стоит. А показывает черти знает что.
По поводу обработки переполнения таймеров при измерении длительности периода вот тут поглядите.

Хорошо, прочитаю.
Последний раз редактировалось Ramis12 Сб июл 29, 2017 12:20:03, всего редактировалось 1 раз.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 12:19:00

А если вращать в обратную сторону, не снимали осциллограмму?

Добавлено after 2 minutes 46 seconds:
Вот я туплю сегодня. Я вчера валерьянки нализался. Я почему то думал про направления вращения пропеллера. Так что про измерение на одном таймере забудьте что я говорил. Извиняюсь за путаницу свою.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 12:21:36

В обратную сторону картина меняется на +180

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 12:25:41

Попробуйте сделать с таймерами как я Вам сказал. Даже пока не пересчитывайте в нужные Вам единицы измерения. Просто выводите на экран захваченные данные таймеров.

Re: Atmega128 Timer3 режим захвата

Сб июл 29, 2017 12:27:55

Хорошо. Попробую, отпишусь.

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 08:18:13

Проблема ,вроде, решил. Убрал оптопару, диод через которые подавался сигнал на вход IC3. Подключил порту и к земле конденсатор на 68nF.
Для вычисление фазы при прерывании Timer3 записываю в переменную значение Timer1.
Код:
Zahvat1:
Zahvatvrem = Timer1  ' переменная для вычисления скорости
Timer1 = 0
Return


Zahvat3:
Phaza = Timer1  'переменная для вычисления направления
Timer3 = 0
Return


Только засада появилась... При изменении направления вращения вентилятора значение изменяется ровно на 360- a, где a- угол до изменения направления вращения
Осциллограммы для 55 грдусов при вращении по часовой и против. Желтая осциллограмма - вход Timer1, зеленая -Timer3
55.JPG
(147.48 KiB) Скачиваний: 325

55против.JPG
(150.39 KiB) Скачиваний: 594


Что-то не могу придумать к чему сделать привязку "по часовой" и "против" :dont_know:

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 08:27:47

А он может в реальных условиях вращаться в обратную сторону?

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

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 08:38:08

Да , может вращаться. И вращается часто.

"..у Вас получается вместо захвата просто внешнее прерывание." - я что-то не понимаю.
Код:
Zahvat3:                          ' Это подпрограмма , которая выполняется при прерывании Timer3
Phaza = Timer1                 "Тут я захватываю значение Timer1 , когда происходит прерывание Timer3
Timer3 = 0                       ' обнуляю значение Timer3
Return


Как еще можно захватить значение?

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 09:02:19

Я же писал про регистр захвата ICR. Давайте еще раз попробую написать.

Вы настроили для таймеров захваты по фронту.

В момент события этого фронта, МК скидывает значение таймера в регистр ICR и включает флаг события захвата. Т.е. в регистре ICR будет значение таймера на момент захвата.
Как я Вам уже и предлагал, в обработчике прерывания от таймера 1. Вы сразу же сбрасываете оба таймера и работаете со значениями в регистрах ICR1 и ICR3.
Обработчик прерывания от захвата таймера 3 не нужен.

У Вас такая штука? Если такая, то непонятно обратное вращение.

Добавлено after 10 minutes 39 seconds:
По тем осциллограммам, что Вы приложили, направление вращения легко определить. В обработчике прерывания захват 1, считываете значение порта, с которого происходит захват таймера 3. Один логический уровень будет означать одно направление, другой - другое.

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 09:20:12

У меня такая
img-c8rs1S (1).png
(13.92 KiB) Скачиваний: 548




"Вы сразу же сбрасываете оба таймера и работаете со значениями в регистрах ICR1 и ICR3" - т.е. получается, что если я в прерывании Timer1 сделаю Тimer3=0 у меня в ICR3 зпишется значение Тimer3? Даже если не произошло прерывание Тimer3?


PS: По-моему , я что-то туплю :idea: В другую сторону он будет вращаться только в том случае если повернется в протвоположную сторону. Или если ветер будет дуть с противоположной стороны.

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 09:45:26

Ramis12 писал(а):Даже если не произошло прерывание Тimer3?
Не путайте события и прерывания.

Конкретно в Вашем случай, например, для таймера3, когда он настроен на захват.

Произошло событие - фронт сигнала. МК сам (без участия программы), захватит данные таймера в регистр ICR3 (вернее в два регистра ICR3H и ICR3L) и установит флаг события ICF3: Timer/Counter3, Input Capture Flag в регистре ETIFR. Обрабатывать это событие не обязательно. Т.е. если у Вас не включена маска разрешения прерывания TICIE3: Timer/Counter3, Input Capture Interrupt Enable, прерывание программы не произойдет, но данные то будут захвачены и именно на момент события.

Я Баском не знаю, но пока создалось впечатление, что этот язык далеко не лучший для программирования AVR. Вот Вы считываете текущие данные с таймера так Zahvatvrem = Timer1. На самом деле происходит считывание данных с регистровой пары TCNT1. Зачем давать имена отличные от даташит непонятно. :dont_know:

Re: Atmega128 Timer3 режим захвата

Вс июл 30, 2017 10:40:37

Я понял о чем Вы. B Баскоме каждое прерывание должно иметь свою подпрограмму обработки. Я беру те же значения регистра захвата ICR. В принципе да, неточности могут быть, потому что текущее знчение сначала записывается в ICR и потом вырабатывается запрос на прерывание, а я по прерыванию считываю значение Timer.

"Зачем давать имена отличные от даташит непонятно"- так, чтобы удобно было. Зачем мне писать TCN1 , а потом открыв через пару лет думать "что это такое". Обьявив переменную Zahvatvrem -я буду знать , что тут захватываю время .Так языки высокого уровня для этого и служать, чтобы близко быть к человеку :roll:
Ответить