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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Прошу помощи в допиливании программы цифрового стрелочного спидометра.


Прошу помощи в допиливании программы цифрового стрелочного спидометра.

Сообщений 31 страница 60 из 61

31

код
Код:
 $regfile = "m32def.dat"
$crystal = 16000000
$hwstack = 60                                               ' default use 32 for the hardware stack
$swstack = 40                                               ' default use 10 for the SW stack
$framesize = 36
'*********************объявление переменных-*******************
Dim Steps As Integer , Bb As Integer , Ccc As Integer , Ee As String * 2
Dim E As Word
Dim Timcount As Word
Dim Period As Single                                        ' период измеряемого сигнала
Dim F11 As Single
Dim Fff As Integer
Dim Rr As Byte
Dim H As Byte
Dim N1 As Byte
Dim N2 As Byte
Dim N3 As Byte
Dim N4 As Byte
Dim N5 As Byte
Dim N6 As Byte
Dim M1 As Long
Dim M2 As Long
Dim M3 As Long
Dim M4 As Long
Dim M5 As Long
Dim M6 As Long
Dim Ugol As Byte
Dim Odo4 As Single
Dim Odosyt As Single
Dim T As Single
Dim A As Single
Dim B As Integer
Dim Shet As Integer
Dim Sk As Long
Dim F As Integer
Dim Speed As Single
Dim Hz As Integer
Dim U As Word
Dim Menu As Integer
Dim Podmenu As Integer
Dim M As Byte
Dim Odomain As Eram Single
Dim Odosytt As Eram Single
Dim Stepss As Eram Integer
Dim Cc As Eram Integer
Dim Eee As Eram Byte
Dim C As Byte
Dim K As Single
Dim L As Integer
Dim Ll As Eram Integer
Dim Z As Byte
Dim Trip As Single
Dim Kspeed As Single
'*********************конфигурация портов*******************
Config Pind.6 = Input                                       'вход импульсов
Config Portd.3 = Output
   'кнопки

Config Pind.0 = Input
Config Pind.1 = Input
Pind.0 = 1
Pind.1 = 1
'управление двигателем
Config Porta.0 = Output
Config Porta.1 = Output
Config Porta.2 = Output
Config Porta.3 = Output
 'порты компаратора
Config Pinb.3 = Input
Config Pinb.2 = Input
     Pinb.2 = 0
     Pinb.3 = 0
     'катоды разрядов индикатора
  Config Portb.0 = Output
  Config Portb.1 = Output
  Config Portb.4 = Output
  Config Portb.5 = Output
  Config Portb.6 = Output
  Config Portb.7 = Output
  'сегменты индикатора
  Config Portc.0 = Output
  Config Portc.1 = Output
  Config Portc.2 = Output
  Config Portc.3 = Output
  Config Portc.4 = Output
  Config Portc.5 = Output
  Config Portc.6 = Output
  Config Portc.7 = Output
Odo4 = Odomain
Steps = Stepss
Ccc = Cc
Odosyt = Odosytt
L = Ll
Enable Interrupts



'******************настройка компаратора****************************
 Config Aci = On , Compare = Off , Trigger = Rising         'Конфигурируем компаратор

  Acsr.6 = 1                                                'включаем сравнение с с внутренним опорным напяржением 1,25в
  Acsr.3 = 1                                                ' разрешаем прерывание по компаратору

  On Aci Button
Config Adc = Free , Prescaler = Auto , Reference = Internal 'настраиваем АЦП
Start Adc



Config Timer1 = Timer , Prescale = 64 , Capture Edge = Rising
       'коэфф.деления 64,импульс по фронту
On Capture1 Capt                                            'подпрог. обработки прерывания
On Timer1 Sbros



Timcount = 0

Const Tt = 0.000004

Shet = 0
Sk = 0
F = 0
H = 0
Menu = 0
M = 0

Z = 0
Enable Capture1
Enable Timer1
K = L \ 2100                                                '
Trip = 0.000181 * K
Kspeed = 0.652 * K
'Odo4 = 0
'Odosyt = 0

 Do



If Pind.0 = 0 And M = 0 And Podmenu = 0 Then                'проверяем длительность нажатия кнопки
Waitms 600
If Pind.0 = 0 And Menu = 0 Then                             'если нажата долго и мы в меню пробега то переход в меню выбора размера колеса
Podmenu = 1
M = 1
End If
If Pind.0 = 0 And Menu = 1 Then                             'если нажата долго и мы в меню сут. пробега то сбрасываем суточный пробег
Odosyt = 0
Odosytt = Odosyt
M = 1
End If
If Pind.0 = 0 And Menu = 2 And Podmenu = 0 Then             'если нажата долго и мы в меню напряжения то переход в подменю скорости
Podmenu = 2
M = 1
Waitms 50
End If
If Pind.0 = 1 And Podmenu = 0 Then                          'если нажата недолго то перелистываем пункты основного меню
Menu = Menu + 1
Podmenu = 0
M = 0
End If
Waitms 300
End If

If Pind.0 = 1 Then                                          ' обнуление переменной програмной "защелки"
M = 0
End If


If Menu = 3 Then                                            ' зацикливание переменной перелистывания меню на значениях от 0 до 2
Menu = 0
End If


'****************************расчет частоты и расчет скорости для стрелки*************************************
   Shet = Shet + 1                                          'усреднение данных регистра захвата за 10 циклов
   If Shet = 10 Then
   Sk = Sk / 9
   E = Sk
   Sk = 0
   Shet = 0
   Else
   Sk = Sk + Timcount
   End If

 Period = E * Tt                                            'расчет частоты
 F11 = 1 / Period
 F11 = F11 * K
 Fff = Int(f11)

 If F = 1 Then                                              ' условие если частота ниже 4гц и таймер переполдняется   то частоту не считать
 Fff = 0
 End If


  If Fff > 212 Then
  Fff = 212
  End If
  Rr = Fff
Ugol = Lookup(rr , Ugol_table)
 If Ugol > 140 Then
 Ugol = 140
 End If



    If Ccc < 0 Or Ccc > 140 Then
    Ccc = 0
    End If


    If Ccc > Ugol Then
    Gosub Stepdecr
    End If
    If Ccc < Ugol Then
    Gosub Stepinc
      End If



'*************************выбор выводимого числа на 7сегм инд.*************************************************
   If Menu = 0 And Podmenu = 0 Then                         'вход в меню основного пробега

    M1 = Odo4 * 10
    H = 1
    C = 0
    End If


    If Menu = 1 And Podmenu = 0 Then                        'вход в меню суточного пробега

    M1 = Odosyt * 10
    H = 1
    C = 0
    End If


    If Menu = 2 And Podmenu = 2 Then                        'вход в подменю скорости
     Speed = Rr * Kspeed
     Speed = Speed \ K
    M1 = Speed
    H = 0
    C = 0
    End If
    If Pind.0 = 0 And Menu = 2 And Podmenu = 2 And M = 0 Then       'выход из подменю скорости в меню напряжения
    Podmenu = 0
    Waitms 300
    End If

 '******************************************разложение числа для вывода на 7сегм***************************************


         M2 = M1
         M3 = M1
         M4 = M1
         M5 = M1
         M6 = M1

         M1 = M1 / 100000                                   'обработка первого числа
         N1 = Abs(m1)



         M2 = M2 Mod 100000                                 'обработка второго числа
         M2 = M2 / 10000
         N2 = Abs(m2)



         M3 = M3 Mod 10000                                  ' обработка третьего числа
         M3 = M3 / 1000
         N3 = Abs(m3)

         M4 = M4 Mod 1000                                   ' обработка третьего числа
         M4 = M4 / 100
         N4 = Abs(m4)

         M5 = M5 Mod 100                                    ' обработка третьего числа
         M5 = M5 / 10
         N5 = Abs(m5)

         M6 = M6 Mod 10                                     ' обработка четвертого числа
         N6 = Abs(m6)

         If Menu = 2 And Podmenu = 0 Then                   'вход в меню напряжения
   '*************************выбор выводимого числа на 7сегм инд.продолжение************************************************
         U = Getadc(6)
         U = U \ 5.33
         M1 = U * 10
         N6 = 10                                            'вывод значка u, тушим ненужные разряды
         N1 = 10
         N2 = 10
         H = 0
         C = 1
         End If

    If Menu = 0 And Podmenu = 1 Then                        'вход в подменю корректировки длины окружности колеса
    M1 = L                                                  'вывод значения длины с еепром
    H = 0                                                   'тушим точку
    C = 0                                                   'тушим точку
    N1 = 10                                                 'тушим первый разряд
    N2 = 10                                                 'тушим второй разряд
    End If
    If Pind.0 = 0 And Menu = 0 And Podmenu = 1 And M = 0 Then       ' корректировка длины окружности в плюс
    If Z = 0 Then
    L = 1800
    Z = 1
    End If
    L = L + 5
    Ll = L
    Waitms 200
    End If
    If U > 1000 Then
    Portd.3 = 0
    Else
    Portd.3 = 1
    End If

          Gosub Led



 Loop

 End
 '*************************подпрограмма кручения двигателя против часовой стрелки*************************
Stepdecr:

 Decr Steps
 Decr Ccc
 If Steps < 1 Then Steps = 4

 Select Case Steps
 Case 1:
 Set Porta.0
 Reset Porta.1
 Set Porta.2
 Reset Porta.3

 Case 2 :
 Reset Porta.0
 Set Porta.1
 Set Porta.2
 Reset Porta.3

 Case 3 :
 Set Porta.0
 Reset Porta.1
 Reset Porta.2
 Set Porta.3
 Case 4 :
 Reset Porta.0
 Set Porta.1
 Reset Porta.2
 Set Porta.3


 End Select
 Waitms 3

 Return
'*************************подпрограмма кручения двигателя по часовой стрелке*************************
 Stepinc:
Incr Ccc
Incr Steps
If Steps > 4 Then Steps = 1


 Select Case Steps
 Case 1:
 Set Porta.0
 Reset Porta.1
 Set Porta.2
 Reset Porta.3

 Case 2 :
 Reset Porta.0
 Set Porta.1
 Set Porta.2
 Reset Porta.3

 Case 3 :
 Set Porta.0
 Reset Porta.1
 Reset Porta.2
 Set Porta.3
 Case 4 :
 Reset Porta.0
 Set Porta.1
 Reset Porta.2
 Set Porta.3

End Select

Waitms 3

Return



'**********************подпрограмма сохранения данных при выключении питания***************************
   Button:
   Portc = 0
Odosytt = Odosyt
Stepss = Steps
Cc = Ccc
Odomain = Odo4
Eee = 0

  Gifr = 64



Return
'**********************подпрограмма чтения данных о частоте и счет пробега***************************
Capt:

If F = 0 Then
Timcount = Capture1
Timer1 = 0
Else
Timer1 = 0
Timcount = 0
F = 0
End If
Odo4 = Odo4 + Trip
Odosyt = Odosyt + Trip



Return
'**********************подпрограмма сброса таймера по переполнению***************************
Sbros:

F = 1
Return


   '* * * подпрограма обработки индикации * * *

     Led:
       Portb.7 = 0
       Portb.0 = 1
       Portb.1 = 0
       Portb.4 = 0
       Portb.5 = 0                                          'зажигаем первое число
       Portb.6 = 0
      Select Case N1
         Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111
         Case 10 : Portc = &B00000000
      End Select
     Waitms 3


       Portb.0 = 0
       Portb.1 = 1
       Portb.4 = 0
       Portb.5 = 0                                          'зажигаем первое число
       Portb.6 = 0
       Portb.7 = 0
      Select Case N2
         Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111
         Case 10 : Portc = &B00000000
        End Select
       Waitms 3


       Portb.0 = 0
       Portb.1 = 0
       Portb.4 = 1
       Portb.5 = 0                                          'зажигаем первое число
       Portb.6 = 0
       Portb.7 = 0

      Select Case N3

        Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111
      End Select

       Waitms 3


       Portb.0 = 0
       Portb.1 = 0
       Portb.4 = 0
       Portb.5 = 1                                          'зажигаем первое число
       Portb.6 = 0
       Portb.7 = 0


           If C = 1 Then
              Select Case N4
         Case 0 : Portc = &B10111111
         Case 1 : Portc = &B10000110
         Case 2 : Portc = &B11011011
         Case 3 : Portc = &B11001111
         Case 4 : Portc = &B11100110
         Case 5 : Portc = &B11101101
         Case 6 : Portc = &B11111101
         Case 7 : Portc = &B10000111
         Case 8 : Portc = &B11111111
         Case 9 : Portc = &B11101111
      End Select
      Else
          Select Case N4
        Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111

                      End Select
      End If


        Waitms 3



       Portb.0 = 0
       Portb.1 = 0
       Portb.4 = 0
       Portb.5 = 0                                          'зажигаем первое число
       Portb.6 = 1
       Portb.7 = 0

                    If H = 1 Then
              Select Case N5
         Case 0 : Portc = &B10111111
         Case 1 : Portc = &B10000110
         Case 2 : Portc = &B11011011
         Case 3 : Portc = &B11001111
         Case 4 : Portc = &B11100110
         Case 5 : Portc = &B11101101
         Case 6 : Portc = &B11111101
         Case 7 : Portc = &B10000111
         Case 8 : Portc = &B11111111
         Case 9 : Portc = &B11101111
      End Select
      Else
          Select Case N5
        Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111

                      End Select
      End If


      Waitms 3


       Portb.0 = 0
       Portb.1 = 0
       Portb.4 = 0
       Portb.5 = 0                                          'зажигаем первое число
       Portb.6 = 0
       Portb.7 = 1

          Select Case N6
        Case 0 : Portc = &B00111111
         Case 1 : Portc = &B00000110
         Case 2 : Portc = &B01011011
         Case 3 : Portc = &B01001111
         Case 4 : Portc = &B01100110
         Case 5 : Portc = &B01101101
         Case 6 : Portc = &B01111101
         Case 7 : Portc = &B00000111
         Case 8 : Portc = &B01111111
         Case 9 : Portc = &B01101111
         Case 10 : Portc = &B00011100
      End Select


      Waitms 3
      Return
      Ugol_table:
Data 0 , 0 , 0 , 0 , 0 , 0 , 3 , 4 , 4 , 5 , 6
data 6, 7, 7, 8, 8, 8, 9, 9, 10, 10
data 11, 11, 11, 12, 13, 13, 14, 14, 15, 15
data 15, 16, 17, 17, 18, 19, 19, 20, 21, 21
data 22 ,23, 23, 24, 25, 25, 26, 27, 27, 28
data 29, 29, 30, 31, 31, 32, 33, 33, 34, 35
data 36, 37, 38, 38, 39, 39, 40, 41, 42, 43
data 44, 45, 45, 46, 46, 47, 47, 48, 49, 50
data 50, 51, 52, 52, 53, 54, 54, 55, 56, 56
data 57, 58, 58, 59, 60, 60, 61, 62, 62, 63
data 64, 64, 65, 66, 66, 67, 68, 68, 69, 70
data 70, 71, 72, 72, 73, 74, 74, 75, 76, 76
data 77, 78, 78, 79, 80, 80, 81, 82, 83, 84
data 84, 85, 86, 86, 87, 88, 88, 89, 90, 90
data 91, 92, 92, 93, 94, 94, 95, 96, 96, 97
data 98, 98, 99, 100, 100, 101, 102, 102, 103, 104
data 104, 105, 106, 106, 107, 108, 108, 109, 110, 110
data 111, 112, 113, 114, 115, 115, 116, 116, 117, 118
data 118, 119, 120, 120, 121, 122, 122, 123, 124, 124
data 125, 126, 127, 128, 129, 129, 130, 131, 131, 132
data 133, 133, 134, 135, 135, 136, 137, 137, 138, 139
data 139, 140

0

32

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

памяти стало занимать в два раза меньше

Остальные case надо бы так же заменить на лукап.
На счет кода, в нём очень много задержек изначально (wait..), с таким подходом всегда будут проблемы, алгоритм надо с нуля весь переписывать.
Предлагаю вам с имеющимся новым опытом начать писать код 2.0. :) Можно даже здесь попробовать поэтапно начать писать. Вначале написать общую логику работы (механику вывода на индикатор, подсчет времени импульсов), а потом всё соединить.
Я бы индикатор, импульсы (мерку скорости) вывел бы в прерывание. Возможно обработку кнопок и кончину питания - тоже.
В основном теле программы должна быть конструкция обработка собранных данных и сложная математика.
А у вас всё в кучу, да ещё с задержками.

0

33

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

Вначале написать общую логику работы (механику вывода на индикатор, подсчет времени импульсов), а потом всё соединить.

Мои "пять копеек"... ;)

Неплохо было бы раздать приоритеты выполнения.
1 - Обработка ДС, т.к. от него пляшет все остальное.
2 - расчет угла поворота стрелки, т.к. ради этого все и мурыжится.
3 - индикация.
4 - кнопки.

Приоритеты можно сделать на флагах. Примерно так:
Считаем импульсы - выставили флаг 1, при его наличии - плевать на все остальное.
Крутим стрелку - выставили флаг 2, можно отвлечься на подсчет импульсов.
...
Обрабатываем кнопки - флаг 4, можно отвлечься по любому поводу...

0

34

Крайне желательно

вот это на ASM AVR

'**********************подпрограмма чтения данных о частоте и счет пробега***************************
Capt:

If F = 0 Then
Timcount = Capture1
Timer1 = 0
Else
Timer1 = 0
Timcount = 0
F = 0
End If
Odo4 = Odo4 + Trip
Odosyt = Odosyt + Trip

Return
'**********************подпрограмма сброса таймера по переполнению***************************

0

35

У Вас из прерываний только захват, переведите на ASM и всё будет работать.

Зачем эти переменные типа single ?

Odo4 = Odo4 + Trip
Odosyt = Odosyt + Trip

Отредактировано sasha_1973 (2018-03-07 16:27:42)

0

36

Ну давайте попробуем.
Общая суть программы понятна.
Измеряется частота импульсов от датчика скорости. И на выходе после математической обработки мы получаем частоты в диапазоне от 0 до 213гц (это на шкалу от 0 до 140км\ч) Согласно этой частоте из таблицы берется значение и стрелка поворачивается на нужный угол. Также считается общий и суточный пробег. Это я сделал в подпрограмме прерывания чтения данных регистра захвата. Т.е. переход в эту подпрограмму происходит по каждому импульсу с датчика скорости. Зная что за один импульс с датчика колесо проходит  17см пути высчитывается пробег.
Это приоритетные задачи.
Дальше остается  разложение по разрядам числа для индикации и обработка кнопки. Т.е. передвижение по меню: корректировка длины окружности колеса, вольтметр,суточный пробег, общий пробег. Это все в основном цикле, остальное вынесено.
Помогите разобраться как тогда правильно выстроить алгоритм по другому?

Отредактировано Dnepr_1186 (2018-03-07 16:29:32)

0

37

Может пригодится

скорость + каденс для велокомпьютера

'===============================================================================
  Обработка_прерывания_capture4:
'-------------------------------------------------------------------------------
'    If Флаг_прерыв_датчика_скорости > 1 Then
'        Захват_скорости_word = Capture4
'        Compare4a = Захват_скорости_word + Задержка_обнуления_скорости
'        Enable Compare4a
'        Пройденный_путь_long = Пройденный_путь_long + Диаметр_колеса_в_мм
'        Флаг_данные_захвата_скорости = 1
'        Флаг_прерыв_датчика_скорости = 2
'      Else
'        Incr Флаг_прерыв_датчика_скорости
'        Start Timer4
'    End If
'    Timer4 = 0
'  Return
'-------------------------------------------------------------------------------
    $asm
      Push R16
      IN R16 , Sreg
      Push R16

      Push R17

      lds R16 , {Флаг_прерыв_датчика_скорости}
      cpi R16 , 2
      BRLO Обработка_прерывания_capture4_1       ' Перейти если меньше

      lds R16 , ICR4l
      sts {Захват_скорости_low_byte} , R16
      lds R16 , ICR4H
      sts {Захват_скорости_high_byte} , R16

'      Loadadr Задержка_обнуления_скорости , X
'      ld R20  , X+
'      ld R21 , X
'      add R16 , R20
'      adc R17 , R21
'      sts OCR4AH , R17
'      sts OCR4AL , R16

      lds R16 , TIMSK4
      ori R16 , &B00000010
      sts TIMSK4 , R16

      lds R16 , {Const_таймер_время_в_пути + 1}
      sts {Таймер_время_в_пути + 1} , R16
      lds R16 , {Const_таймер_время_в_пути}
      sts {Таймер_время_в_пути} , R16

      ldi R16 , 1
      sts {Флаг_считаем_время_в_пути} , R16
      sts {Флаг_данные_захвата_скорости} , R16
      inc R16
      sts {Флаг_прерыв_датчика_скорости} , R16

      ' Пройденный_путь_long = Пройденный_путь_long + Диаметр_колеса_в_мм_word
      ' Время выполнения операции 26 тактов
      lds R16 , {Пройденный_путь_1_byte}       ' Время выполнения инструкции 2 такта
      lds R17 , {Диаметр_колеса_в_мм_low_byte}       ' Время выполнения инструкции 2 такта
      add R16 , R17       ' Время выполнения инструкции 1 такт
      sts {Пройденный_путь_1_byte} , R16       ' Время выполнения инструкции 2 такта

      lds R16 , {Пройденный_путь_2_byte}       ' Время выполнения инструкции 2 такта
      lds R17 , {Диаметр_колеса_в_мм_high_byte}       ' Время выполнения инструкции 2 такта
      adc R16 , R17       ' Время выполнения инструкции 1 такт
      sts {Пройденный_путь_2_byte} , R16       ' Время выполнения инструкции 2 такта

      lds R16 , {Пройденный_путь_3_byte}       ' Время выполнения инструкции 2 такта
      clr R17       ' Время выполнения инструкции 1 такт
      adc R16 , R17       ' Время выполнения инструкции 1 такт
      sts {Пройденный_путь_3_byte} , R16       ' Время выполнения инструкции 2 такта

      lds R16 , {Пройденный_путь_4_byte}       ' Время выполнения инструкции 2 такта
      clr R17       ' Время выполнения инструкции 1 такт
      adc R16 , R17       ' Время выполнения инструкции 1 такт
      sts {Пройденный_путь_4_byte} , R16       ' Время выполнения инструкции 2 такта
      rjmp Выход_прерывания_capture4

     Обработка_прерывания_capture4_1:
      lds R16 , {Флаг_прерыв_датчика_скорости}
      inc R16
      sts {Флаг_прерыв_датчика_скорости} , R16

      lds R16 , TCCR4B
      ori R16 , &B00000101
      sts TCCR4B , R16

     Выход_прерывания_capture4:
      clr R16
      sts TCNT4H , R16
      sts TCNT4l , R16

      pop R17

      POP R16
      Out Sreg , R16
      POP R16

      reti
    $end Asm
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Обработка_прерывания_compare4a:
'-------------------------------------------------------------------------------
'    Stop Timer4
'    Timer4 = 0
'    Disable Compare4a
'    Захват_скорости_word = 0
'    Флаг_прерыв_датчика_скорости = 0
'    Флаг_данные_захвата_скорости = 1
'  Return
'-------------------------------------------------------------------------------
    $asm
      Push R16
      IN R16 , Sreg
      Push R16

      lds R16 , TCCR4B
      andi R16 , &B11111000
      sts TCCR4B , R16

      clr R16
      Sts Icr4h , R16
      sts ICR4l , R16

      sts {Захват_скорости_word} , R16
      sts {Захват_скорости_word + 1} , R16

      sts {Флаг_прерыв_датчика_скорости} , R16

      ldi R16 , 1
      sts {Флаг_данные_захвата_скорости} , R16

      lds R16 , TCCR4B
      andi R16 , &B11111000
      sts TCCR4B , R16

      lds R16 , Timsk4
      andi R16 , &B11111101
      sts Timsk4 , R16

      POP R16
      Out Sreg , R16
      POP R16

      reti
    $end Asm
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Обработка_прерывания_capture5:
'-------------------------------------------------------------------------------
'    If Флаг_прерыв_датчика_каденса > 1 Then
'        Захват_каденса_word = Capture5
'        Compare5a = Захват_каденса_word + Задержка_обнуления_каденса
'        Enable Compare5a
'        Флаг_данные_захвата_каденса = 1
'        Флаг_прерыв_датчика_каденса = 2
'      Else
'        Incr Флаг_прерыв_датчика_каденса
'        Start Timer5
'    End If
'    Timer5 = 0
'  Return
'-------------------------------------------------------------------------------
    $asm
      Push R16
      IN R16 , Sreg
      Push R16

      lds R16 , {Флаг_прерыв_датчика_каденса}
      cpi R16 , 2
      BRLO Обработка_прерывания_capture5_1       ' Перейти если меньше

      lds R16 , ICR5l
      sts {Захват_каденса_low_byte} , R16
      lds R16 , ICR5H
      sts {Захват_каденса_high_byte} , R16

'      Loadadr Задержка_обнуления_каденса , X
'      ld R20  , X+
'      ld R21 , X
'      add R16 , R20
'      adc R17 , R21
'      sts OCR5AH , R17
'      sts OCR5AL , R16

      lds R16 , TIMSK5
      ori R16 , &B00000010
      sts TIMSK5 , R16

      ldi R16 , 1
      sts {Флаг_данные_захвата_каденса} , R16
      inc R16
      sts {Флаг_прерыв_датчика_каденса} , R16

     Обработка_прерывания_capture5_1:
      lds R16 , {Флаг_прерыв_датчика_каденса}
      inc R16
      sts {Флаг_прерыв_датчика_каденса} , R16

      lds R16 , TCCR5B
      ori R16 , &B00000101
      sts TCCR5B , R16

     Выход_прерывания_capture5:
      clr R16
      sts TCNT5H , R16
      sts TCNT5l , R16

      POP R16
      Out Sreg , R16
      POP R16

      reti
    $end Asm
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Обработка_прерывания_compare5a:
'-------------------------------------------------------------------------------
'    Stop Timer5
'    Timer5 = 0
'    Disable Compare5a
'    Захват_каденса_word = 0
'    Флаг_прерыв_датчика_каденса = 0
'    Флаг_данные_захвата_каденса = 1
'  Return
'-------------------------------------------------------------------------------
    $asm
      Push R16
      IN R16 , Sreg
      Push R16

      lds R16 , TCCR5B
      andi R16 , &B11111000
      sts TCCR5B , R16

      clr R16
      Sts Icr5h , R16
      sts ICR5l , R16

      sts {Захват_каденса_word} , R16
      sts {Захват_каденса_word + 1} , R16

      sts {Флаг_прерыв_датчика_каденса} , R16

      ldi R16 , 1
      sts {Флаг_данные_захвата_каденса} , R16

      lds R16 , TCCR5B
      andi R16 , &B11111000
      sts TCCR5B , R16

      lds R16 , Timsk5
      andi R16 , &B11111101
      sts Timsk5 , R16

      POP R16
      Out Sreg , R16
      POP R16

      reti
    $end Asm
'-------------------------------------------------------------------------------
  Return
'===============================================================================

Отредактировано sasha_1973 (2018-03-07 16:33:38)

0

38

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

Ну давайте попробуем. Общая суть программы понятна.

Раз пошла такая пьянка, то я настойчиво предлагаю таки установить датчики положения стрелки.
Шкала под ней всяко есть, механически можно к ней зацепиться.

Программа сильно не усложнится, только при старте достаточно убедиться, что стрелка "в 0", если нет - подкорректировать положение.

Зато можно избавиться от кучи корректировок и сохранялок в EEPROM и неизбежного их "убегания"...

0

39

sasha_1973
я в ассемблере вообще ноль. Если не сложно помогите перевсти этот кусок? Эти переменные типа single потому что общий пробег может быть большим допустим 40000 и выше.Поэтому сделал с запасом(хотя на прктике столько тяжело наездить.)

0

40

Nord, надо думать как туда что подцепить, пока ума не приложу. Попробу выложить фото готовой систмеы. Может что в голову придет

0

41

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

Nord, надо думать как туда что подцепить, пока ума не приложу.

Только что посмотрел ДШ на двигатель.  Силенок у него на валу достаточно.

Самый простой вариант, который пришел в голову - на вал посадить шкив, рядом с двигателем поставить переменник, тоже со шкивом на валу.

Положение (угол) можно будет определить при помощи АЦП.

0

42

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

0

43

Еще вариант "концевиков", самый простой.

На вал двигателя крепим упругий "усик".
Вал достаточно хорошо контактирует с "массой".

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

Дальше, думаю, объяснять не требуется... ;)

0

44

ну да это то что надо. И еще проще. под стрелкой(она металлическая)  в районе нулевой отметки делаю выступ изолировнный от минуса, когда стрелка в нуле она касается выступа и таким образом получаем нулевую отметку

Отредактировано Dnepr_1186 (2018-03-07 17:52:56)

0

45

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

В общем давайте попробуем пока без датчика нуля, потом я думаю дописать его не проблема будет.

Проблема будет потом в "выпиливании" из кода ненужного... ;)

Лучше сразу определиться с "железом", а потом его обвязывать программно.

0

46

понял. в ближайшие дни займусь этим датчиком нуля.

0

47

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

тобы нажимал когда в нулевом положении

Нинада опять топором стругать, оптику делайте или датчик холла (магнит).
Если вешать на вал мотора резюк (чтобы АЦП потом мерить), то надо прям на один вал их цеплять и никаких пасиков! А хватит там мощи или нет - будет видно. Экспериментально.

0

48

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

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

Я же не предлагаю законченную конструкцию... ;)
Вариантов куча.
Контактный - самый простой, но есть жирный "минус" - загрязнение контактов.

Оптика - лучший вариант.
Легонькая заслонка будет рвать оптическую связь или будет служить отражателем.

Магнит тоже хорошо, но ДХ очень меняют свои хар-ки от температуры.
Точка срабатывания будет плавать...

0

49

Товарищи, я поразмыслил тут и решил. Если делать грамотно, на ДХ или оптике, то все же надо основательно переделывать все. И плату разводить по другому чтобы этот датчик там стал. Понимаете, там все впритык получается,  особо нигде ничего не приколхозишь. Давайте все же попробуем без датчика нуля? Если устройство заработает нормально (с учетом возможности ручной корректировки нуля кнопкой при сбое), то следующий образец я сделаю с учтеом этого датчика. Чтобы все было красиво и на своих местах, а не колхоз, который потом отвалится где-нибудь в пути. И программу под него думаю уже сам скорректирую

0

50

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

Если делать грамотно, на ДХ или оптике, то все же надо основательно переделывать все. И плату разводить по другому чтобы этот датчик там стал.

Датчики эти можно расположить на тыльной части шкалы (я уже спрашивал про ее наличие).

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

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

А я так понял, что уже новый вариант строится... ;)
Смысл допиливать старый, если в нем изначально заложены конструктивные недочеты ?

0

51

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

http://s5.uploads.ru/t/jmHTC.jpg
http://s7.uploads.ru/t/HxUCQ.jpg
http://s3.uploads.ru/t/BcUv7.jpg
http://s8.uploads.ru/t/pUY1B.jpg

Отредактировано Dnepr_1186 (2018-03-07 18:32:13)

+1

52

Фигасе, шаговик можно было и поменьше у китаёзов купить. :)

0

53

Я ж говорю устройство делалось с нуля из того что было(а была разобранная печатная машинка Ромашка с этими ШД и несколько микрсохем купленных когда то в столице). Это сейчас открыл для себя много нового но не хочу с нуля опять делать. Этот "бутерброд" четко становится в родной стакан спидометра и по высоте совпадает, да и крутит он четко, стрелку фиг стресешь на ямках или вибрациях. Стоит мертво. Так что имеем что имеем)

0

54

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

Вот нашел фото


Ёханки, Ёптель .......256 этажей !

Монументально ! Производители спидометров сидят в углу и тихо плачут от зависти !

Однозначно, помогаю чем могу.

1. Определитесь с переменными, Single не вариант, замена - DWord, счёт в см, хватит на ~43 000 км

???????????????

Отредактировано sasha_1973 (2018-03-07 20:59:40)

0

55

sasha_1973да вышло серьезно) В лучших традициях ламповой техники 60-х)) Dword пойдет. она ж 0 / 4294967295. Хватит с головой причем что счет в километрах
l

0

56

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

причем что счет в километрах


Вы-же писали 17 см на импульс ?

0

57

а 7-ми сегментники на Солнце видно ?

0

58

там переменная есть Trip, она изменяется в настройках, т.е. под разную длину окружности колеса. Ее думаю тоже можно dword или подобну/ . У меня это значение в килорметрах там.
Залил их красный тонировочным лаком, теперь видно нормально

0

59

Код:
K = L \ 2100                                                '
Trip = 0.000181 * K

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

0

60

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

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

А в чем смысл напрягать МК для этой геометрии ?
Или колеса за поездку не по разу меняются ? ;)
Вводить уже готовый коэффициент.

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Прошу помощи в допиливании программы цифрового стрелочного спидометра.