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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Измеритель двух частот на одном МК


Измеритель двух частот на одном МК

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

1

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

Код:
Enable Timer1
Enable Timer0
Config Timer1 = Timer , Prescale = 1024
Config Timer0 = Timer , Prescale = 1024
 Enable Interrupts
 Enable Int0
 Enable Int1
 Config Pind.2 = Input
Config Int0 = Falling
Config Pind.3 = Input
Config Int1 = Falling
On Int0 Speed
On Int1 Oboroty
Dim A As Word
Dim B As Word
Dim I As Integer
Dim O As Integer
Dim Speed2 As Single
Dim Speed1 As Single
Dim Ob As Single
Dim Ob1 As Single
Dim Text As String * 14
Dim Ccc As String * 5
  Do
Speed1 = 1 / A

Speed2 = Speed1 * 468720

 I = Int(speed2)
Ob = 1 / B

Ob = Ob * 468720
If Ob < 300 Then
Ob = 0
End If
 O = Int(ob)


Upperline
Lcd "speed:" ; I ; "   "
Lowerline
Lcd "oboroty:" ; O ; "   "
Waitms 100
Loop

Speed:
 Stop Timer1
 A = Timer1
 Timer1 = 0
  Start Timer1
Return
Oboroty:
 Stop Timer0
 B = Timer0
 Timer0 = 0
 Start Timer0

Return

0

2

Если напишите частоту и тип контроллера, может кто-нибудь и поможет.

0

3

в протеусе поглядите переполняется или нет. или по уарту выведите если есть возможность.  На какой тактовой хотябы работа идет?

Отредактировано RN6LHC (2014-12-27 22:08:14)

0

4

контроллер амтега8 тактовая 8мгц, но я так понимаю можно ее понизить и до 1мгц? Ведь для измерения частот до 300гц это не критично?
В протеусе смотрел, там цифры прыгают, при кручении ручки генератора в хаотичном порядке.

0

5

Даже при тактовой в 1мгц,  таймер стабильно измеряет начиная с 3,9Гц, а хотелось бы с 1гц хотя бы. Это реально без дальнейшего повышения тактовой частоты?

Отредактировано Dnepr_1186 (2014-12-27 23:08:24)

0

6

Судя по "Speed2 = Speed1 * 468720", тактовая 12Мгц. Так как при такой частоте, Timer0 без делителя переполняется как раз каждую почти секунду. Только правильное число не 468720, а 468750.

Если есть свободная пара ног, то можно обойтись одним таймером, но дополнительной обвязкой.

http://sf.uploads.ru/b2R39.jpg

В обработке проверять, какой порт в нуле, и значение счетчика записывать в соответствующую переменную.
Конденсатор емкостью единицы нанофарад, резисторы килоОм по 10. Подбором этих параметров добиться устойчивого определения в прерывании, какой пин в нуле. Только не забыть проверку на одновременность нуля на обоих пинах.

P.S.: 10 килоОм все-таки может быть маловато. Уже не помню, какое сопротивление у внутренней подтяжки к питанию. КилоОм 50 бы надо, не забыв включить внутреннюю подтяжку.

Отредактировано SIvan (2014-12-27 23:29:02)

0

7

Хотя на счет 468720/468750 уже не уверен. При тактовой 12МГц, Timer0 без делителя будет переполняться с частотой 46875 Гц.

Отредактировано SIvan (2014-12-27 23:37:57)

0

8

вот мой готовый тахометр + вольтметр с возможностью усреднять . возможно поможет

Код:
$regfile = "m8def.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
Config Lcd = 16 * 2
Config Portb.4 = Output
Config Portb.3 = Output

Config Pinb.0 = Input
Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Const Number_arr_min = 2                                    'количество-элементов массива
Const Tick = 0.00000025                                     'время одного тика с учетом делителя таймера
Const P = 9                                                 'число пар полюсов
Const I = 1.825                                             ' передаточное число
Const Lcd_bar_style = 3
Const Max_scale = 4                                         'максимум шкалы оборотов/1000
Const Adc_dig = 0.004887585

Dim Timecounter As Word
Dim Arr_min(number_arr_min) As Word
Dim N As Byte
Dim Mean_oborot As Word                                     'среднее арифметическое
Dim Mean_oborot_one As Word                                 'значение оборотов (десятки)
Dim Mean_oborot_no_one As Word                              'значение оборотов- десятки оборотов
Dim Mean_oborot_one_new As Word                             'подмена десяток оборота
Dim Mean_oborot_out As Word                                 'вывод оборотов с шагом 50 оборотов
Dim Period As Single
Dim Ss As String * 4
Dim Ss_volt As String * 4
Dim Freq As Single
Dim Freq_wr As Byte
Dim Oborot As Single
Dim Oborot_wr As Word
Dim Oborot_min_out As Word
Dim Oborot_scale_wr As Word
Dim Oborot_scale_by As Byte
Dim Voltage_adc As Word
Dim Voltage As Single
Dim Volt_scale As Single
Dim Volt_scale_by As Byte

$include "lcd_bar.bas"

 Cursor Off
 Cls
 Locate 1 , 7
 Lcd "VOLVO"
 Locate 2 , 5
 Lcd "244 GL D6"
 Waitms 2000
       Cls
       Enable Interrupts
       Enable Capture1
       On Capture1 Antdr



Do

      If Timecounter > 60000 Then                           '14000                    'ограничиваем начальные обороты
      Oborot_wr = 0
      Else

      Period = Timecounter * Tick                           'расчет периода пришедшего импульса

      Timecounter = 0                                       'сбрасываем счетчик на всякий слуай
      Freq = 1 / Period                                     'расчет частоты пришедшего импульса
      Freq = Freq / I                                       'учитываем передаточное число
      Freq = Freq / P                                       'учитываем число пар полюсов генератора
      Oborot = Freq * 60                                    'вычисляем обороты в минуту word
      Oborot_wr = Oborot                                    'переводим обороты в byte
      End If



      Incr N                                                'наращиваем счетчик массива
      Arr_min(n) = Oborot_wr / 10                           'наполняем массив значениями/10
      If N = Number_arr_min Then                            'определяем размер массива, если пришли в максимум массива выводим минимальное значение массива
      Oborot_min_out = Min(arr_min(1))




Rem * * * * * * * * * * * * * * * * * * * * * * * * *

      Oborot_scale_wr = Oborot_min_out / Max_scale          'расчитываем максимум шкалы индикатора
      If Oborot_scale_wr > 100 Then Oborot_scale_wr = 101   'проверка на перегрузку числа 101 (необходимо для библиотеки барграфа)
      Oborot_scale_by = Oborot_scale_wr                     'переводим word в  byte
      N = 0                                                 ' сбрасываем счетчик массива в 0
      End If



Rem * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *




Rem ***************округление отображения оборотов по 50****************************

      Mean_oborot_one = Oborot_min_out Mod 10               'находим еденицы от оборотов для округления отображения по 50 оборотов
      If Mean_oborot_one < 5 Then                           ' если еденицы оборотов меньше 5 тогда
      Mean_oborot_one_new = 0
      Else
      Mean_oborot_one_new = 5
      End If
      Mean_oborot_no_one = Oborot_min_out - Mean_oborot_one ' находим изменение оборотов без первого разряда (без едениц)
      Mean_oborot_out = Mean_oborot_no_one + Mean_oborot_one_new

Rem * * * * * * * * * * * * * * * / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

      If Mean_oborot_out > 0 Then                           'проверяем условие если обороты есть тогда выводим их
      Ss = Str(mean_oborot_out)
      Ss = Format(ss , "    ")
      Locate 1 , 4                                          '    на дисплей
      Lcd Ss ; "0 RPM"                                      '
      Locate 2 , 1                                          '
      Lcd_bar Oborot_scale_by , 16                          '

      Else                                                  ' в противном случае включаем режим вольтметра


     Voltage_adc = Getadc(7)                                'считываем значение АЦП
     Voltage = Voltage_adc * Adc_dig                        'преобразуем в вольты через константу
     Voltage = Voltage * 3                                  'делитель напряжения на 3
     Volt_scale = Voltage - 11.9                            '
     If Volt_scale < 0 Then Volt_scale = 0                  'расчет длинны шкалы для вывода напряжения
     Volt_scale = Volt_scale * 45                           '
     Volt_scale_by = Volt_scale                             '
     If Volt_scale_by > 99 Then Volt_scale_by = 99          '
     Ss_volt = Fusing(voltage , "##.#")                     ' округляем до десятых
     Ss_volt = Format(ss_volt , "    ")                     'форматируем строку
                                               ' задержка перед выводом на дисплей
     Locate 1 , 4                                           '
     Lcd Ss_volt ; " VOLT"                                  '   вывод на дисплей напряжения и шкалы
     Locate 2 , 1                                           '
     Lcd_bar Volt_scale_by , 16                             '


      End If

      Loop

        End


      Antdr:
      Timecounter = Timer1
      Timer1 = 0
                Return

0

9

Спасибо

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Измеритель двух частот на одном МК