Код:$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
Прошу помощи в допиливании программы цифрового стрелочного спидометра.
Сообщений 31 страница 60 из 61
Поделиться312018-03-07 13:44:14
Поделиться322018-03-07 15:27:42
памяти стало занимать в два раза меньше
Остальные case надо бы так же заменить на лукап.
На счет кода, в нём очень много задержек изначально (wait..), с таким подходом всегда будут проблемы, алгоритм надо с нуля весь переписывать.
Предлагаю вам с имеющимся новым опытом начать писать код 2.0. Можно даже здесь попробовать поэтапно начать писать. Вначале написать общую логику работы (механику вывода на индикатор, подсчет времени импульсов), а потом всё соединить.
Я бы индикатор, импульсы (мерку скорости) вывел бы в прерывание. Возможно обработку кнопок и кончину питания - тоже.
В основном теле программы должна быть конструкция обработка собранных данных и сложная математика.
А у вас всё в кучу, да ещё с задержками.
Поделиться332018-03-07 15:58:43
Вначале написать общую логику работы (механику вывода на индикатор, подсчет времени импульсов), а потом всё соединить.
Мои "пять копеек"...
Неплохо было бы раздать приоритеты выполнения.
1 - Обработка ДС, т.к. от него пляшет все остальное.
2 - расчет угла поворота стрелки, т.к. ради этого все и мурыжится.
3 - индикация.
4 - кнопки.
Приоритеты можно сделать на флагах. Примерно так:
Считаем импульсы - выставили флаг 1, при его наличии - плевать на все остальное.
Крутим стрелку - выставили флаг 2, можно отвлечься на подсчет импульсов.
...
Обрабатываем кнопки - флаг 4, можно отвлечься по любому поводу...
Поделиться342018-03-07 16:16:51
Крайне желательно
'**********************подпрограмма чтения данных о частоте и счет пробега***************************
Capt:If F = 0 Then
Timcount = Capture1
Timer1 = 0
Else
Timer1 = 0
Timcount = 0
F = 0
End If
Odo4 = Odo4 + Trip
Odosyt = Odosyt + TripReturn
'**********************подпрограмма сброса таймера по переполнению***************************
Поделиться352018-03-07 16:26:00
У Вас из прерываний только захват, переведите на ASM и всё будет работать.
Зачем эти переменные типа single ?
Odo4 = Odo4 + Trip
Odosyt = Odosyt + Trip
Отредактировано sasha_1973 (2018-03-07 16:27:42)
Поделиться362018-03-07 16:27:39
Ну давайте попробуем.
Общая суть программы понятна.
Измеряется частота импульсов от датчика скорости. И на выходе после математической обработки мы получаем частоты в диапазоне от 0 до 213гц (это на шкалу от 0 до 140км\ч) Согласно этой частоте из таблицы берется значение и стрелка поворачивается на нужный угол. Также считается общий и суточный пробег. Это я сделал в подпрограмме прерывания чтения данных регистра захвата. Т.е. переход в эту подпрограмму происходит по каждому импульсу с датчика скорости. Зная что за один импульс с датчика колесо проходит 17см пути высчитывается пробег.
Это приоритетные задачи.
Дальше остается разложение по разрядам числа для индикации и обработка кнопки. Т.е. передвижение по меню: корректировка длины окружности колеса, вольтметр,суточный пробег, общий пробег. Это все в основном цикле, остальное вынесено.
Помогите разобраться как тогда правильно выстроить алгоритм по другому?
Отредактировано Dnepr_1186 (2018-03-07 16:29:32)
Поделиться372018-03-07 16:33:14
Может пригодится
'===============================================================================
Обработка_прерывания_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 R16Push 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 , R16lds R16 , TIMSK4
ori R16 , &B00000010
sts TIMSK4 , R16lds R16 , {Const_таймер_время_в_пути + 1}
sts {Таймер_время_в_пути + 1} , R16
lds R16 , {Const_таймер_время_в_пути}
sts {Таймер_время_в_пути} , R16ldi 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 {Флаг_прерыв_датчика_скорости} , R16lds R16 , TCCR4B
ori R16 , &B00000101
sts TCCR4B , R16Выход_прерывания_capture4:
clr R16
sts TCNT4H , R16
sts TCNT4l , R16pop R17
POP R16
Out Sreg , R16
POP R16reti
$end Asm
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Обработка_прерывания_compare4a:
'-------------------------------------------------------------------------------
' Stop Timer4
' Timer4 = 0
' Disable Compare4a
' Захват_скорости_word = 0
' Флаг_прерыв_датчика_скорости = 0
' Флаг_данные_захвата_скорости = 1
' Return
'-------------------------------------------------------------------------------
$asm
Push R16
IN R16 , Sreg
Push R16lds R16 , TCCR4B
andi R16 , &B11111000
sts TCCR4B , R16clr R16
Sts Icr4h , R16
sts ICR4l , R16sts {Захват_скорости_word} , R16
sts {Захват_скорости_word + 1} , R16sts {Флаг_прерыв_датчика_скорости} , R16
ldi R16 , 1
sts {Флаг_данные_захвата_скорости} , R16lds R16 , TCCR4B
andi R16 , &B11111000
sts TCCR4B , R16lds R16 , Timsk4
andi R16 , &B11111101
sts Timsk4 , R16POP R16
Out Sreg , R16
POP R16reti
$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 R16lds 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 , R16lds R16 , TIMSK5
ori R16 , &B00000010
sts TIMSK5 , R16ldi R16 , 1
sts {Флаг_данные_захвата_каденса} , R16
inc R16
sts {Флаг_прерыв_датчика_каденса} , R16Обработка_прерывания_capture5_1:
lds R16 , {Флаг_прерыв_датчика_каденса}
inc R16
sts {Флаг_прерыв_датчика_каденса} , R16lds R16 , TCCR5B
ori R16 , &B00000101
sts TCCR5B , R16Выход_прерывания_capture5:
clr R16
sts TCNT5H , R16
sts TCNT5l , R16POP R16
Out Sreg , R16
POP R16reti
$end Asm
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Обработка_прерывания_compare5a:
'-------------------------------------------------------------------------------
' Stop Timer5
' Timer5 = 0
' Disable Compare5a
' Захват_каденса_word = 0
' Флаг_прерыв_датчика_каденса = 0
' Флаг_данные_захвата_каденса = 1
' Return
'-------------------------------------------------------------------------------
$asm
Push R16
IN R16 , Sreg
Push R16lds R16 , TCCR5B
andi R16 , &B11111000
sts TCCR5B , R16clr R16
Sts Icr5h , R16
sts ICR5l , R16sts {Захват_каденса_word} , R16
sts {Захват_каденса_word + 1} , R16sts {Флаг_прерыв_датчика_каденса} , R16
ldi R16 , 1
sts {Флаг_данные_захвата_каденса} , R16lds R16 , TCCR5B
andi R16 , &B11111000
sts TCCR5B , R16lds R16 , Timsk5
andi R16 , &B11111101
sts Timsk5 , R16POP R16
Out Sreg , R16
POP R16reti
$end Asm
'-------------------------------------------------------------------------------
Return
'===============================================================================
Отредактировано sasha_1973 (2018-03-07 16:33:38)
Поделиться382018-03-07 16:35:22
Ну давайте попробуем. Общая суть программы понятна.
Раз пошла такая пьянка, то я настойчиво предлагаю таки установить датчики положения стрелки.
Шкала под ней всяко есть, механически можно к ней зацепиться.
Программа сильно не усложнится, только при старте достаточно убедиться, что стрелка "в 0", если нет - подкорректировать положение.
Зато можно избавиться от кучи корректировок и сохранялок в EEPROM и неизбежного их "убегания"...
Поделиться392018-03-07 16:37:27
sasha_1973
я в ассемблере вообще ноль. Если не сложно помогите перевсти этот кусок? Эти переменные типа single потому что общий пробег может быть большим допустим 40000 и выше.Поэтому сделал с запасом(хотя на прктике столько тяжело наездить.)
Поделиться402018-03-07 16:39:31
Nord, надо думать как туда что подцепить, пока ума не приложу. Попробу выложить фото готовой систмеы. Может что в голову придет
Поделиться412018-03-07 16:46:16
Nord, надо думать как туда что подцепить, пока ума не приложу.
Только что посмотрел ДШ на двигатель. Силенок у него на валу достаточно.
Самый простой вариант, который пришел в голову - на вал посадить шкив, рядом с двигателем поставить переменник, тоже со шкивом на валу.
Положение (угол) можно будет определить при помощи АЦП.
Поделиться422018-03-07 17:46:11
Пока нету возможности сфоткать. На работе. В общем прикинул что в принципе можно какой нибудь микрик подобрать и на валу рычажок сделать, чтобы нажимал когда в нулевом положении. Но пока под руками нету таких кнопочек, а появятся нескоро, когда поеду на радиорынок в столицу. В общем давайте попробуем пока без датчика нуля, потом я думаю дописать его не проблема будет.
Поделиться432018-03-07 17:48:13
Еще вариант "концевиков", самый простой.
На вал двигателя крепим упругий "усик".
Вал достаточно хорошо контактирует с "массой".
В нужных точках "мин"/"макс" на плоскости шкалы на изоляторе ставим две стойки.
Дальше, думаю, объяснять не требуется...
Поделиться442018-03-07 17:49:46
ну да это то что надо. И еще проще. под стрелкой(она металлическая) в районе нулевой отметки делаю выступ изолировнный от минуса, когда стрелка в нуле она касается выступа и таким образом получаем нулевую отметку
Отредактировано Dnepr_1186 (2018-03-07 17:52:56)
Поделиться452018-03-07 17:50:16
В общем давайте попробуем пока без датчика нуля, потом я думаю дописать его не проблема будет.
Проблема будет потом в "выпиливании" из кода ненужного...
Лучше сразу определиться с "железом", а потом его обвязывать программно.
Поделиться462018-03-07 17:53:50
понял. в ближайшие дни займусь этим датчиком нуля.
Поделиться472018-03-07 17:59:18
тобы нажимал когда в нулевом положении
Нинада опять топором стругать, оптику делайте или датчик холла (магнит).
Если вешать на вал мотора резюк (чтобы АЦП потом мерить), то надо прям на один вал их цеплять и никаких пасиков! А хватит там мощи или нет - будет видно. Экспериментально.
Поделиться482018-03-07 18:17:27
Нинада опять топором стругать, оптику делайте или датчик холла (магнит).Если вешать на вал мотора резюк (чтобы АЦП потом мерить), то надо прям на один вал их цеплять и никаких пасиков!
Я же не предлагаю законченную конструкцию...
Вариантов куча.
Контактный - самый простой, но есть жирный "минус" - загрязнение контактов.
Оптика - лучший вариант.
Легонькая заслонка будет рвать оптическую связь или будет служить отражателем.
Магнит тоже хорошо, но ДХ очень меняют свои хар-ки от температуры.
Точка срабатывания будет плавать...
Поделиться492018-03-07 18:18:28
Товарищи, я поразмыслил тут и решил. Если делать грамотно, на ДХ или оптике, то все же надо основательно переделывать все. И плату разводить по другому чтобы этот датчик там стал. Понимаете, там все впритык получается, особо нигде ничего не приколхозишь. Давайте все же попробуем без датчика нуля? Если устройство заработает нормально (с учетом возможности ручной корректировки нуля кнопкой при сбое), то следующий образец я сделаю с учтеом этого датчика. Чтобы все было красиво и на своих местах, а не колхоз, который потом отвалится где-нибудь в пути. И программу под него думаю уже сам скорректирую
Поделиться502018-03-07 18:23:56
Если делать грамотно, на ДХ или оптике, то все же надо основательно переделывать все. И плату разводить по другому чтобы этот датчик там стал.
Датчики эти можно расположить на тыльной части шкалы (я уже спрашивал про ее наличие).
Если устройство заработает нормально (с учетом возможности ручной корректировки нуля кнопкой при сбое), то следующий образец я сделаю с учтеом этого датчика. Чтобы все было красиво и на своих местах, а не колхоз, который потом отвалится где-нибудь в пути. И программу под него думаю уже сам скорректирую
А я так понял, что уже новый вариант строится...
Смысл допиливать старый, если в нем изначально заложены конструктивные недочеты ?
Поделиться512018-03-07 18:31:56
Вот нашел фото. Да этот уже почти сделан. Сезон на нем отъезжу, а следующей зимой сделаю новое устройство с учетом датчика. Программу думаю сам смогу скорректировать. Тут главное сейчас с кодом разобраться, а потом уже будет проще. Пока нету достаточно времени чтобы с железом заниматься. С программой проще возится и на работе тогда можно этим заниматься.
Отредактировано Dnepr_1186 (2018-03-07 18:32:13)
Поделиться522018-03-07 20:05:37
Фигасе, шаговик можно было и поменьше у китаёзов купить.
Поделиться532018-03-07 20:44:27
Я ж говорю устройство делалось с нуля из того что было(а была разобранная печатная машинка Ромашка с этими ШД и несколько микрсохем купленных когда то в столице). Это сейчас открыл для себя много нового но не хочу с нуля опять делать. Этот "бутерброд" четко становится в родной стакан спидометра и по высоте совпадает, да и крутит он четко, стрелку фиг стресешь на ямках или вибрациях. Стоит мертво. Так что имеем что имеем)
Поделиться542018-03-07 20:57:58
Вот нашел фото
Ёханки, Ёптель .......256 этажей !
Монументально ! Производители спидометров сидят в углу и тихо плачут от зависти !
Однозначно, помогаю чем могу.
1. Определитесь с переменными, Single не вариант, замена - DWord, счёт в см, хватит на ~43 000 км
???????????????
Отредактировано sasha_1973 (2018-03-07 20:59:40)
Поделиться552018-03-07 21:14:18
sasha_1973да вышло серьезно) В лучших традициях ламповой техники 60-х)) Dword пойдет. она ж 0 / 4294967295. Хватит с головой причем что счет в километрах
l
Поделиться562018-03-07 21:16:18
причем что счет в километрах
Вы-же писали 17 см на импульс ?
Поделиться572018-03-07 21:17:13
а 7-ми сегментники на Солнце видно ?
Поделиться582018-03-07 21:31:00
там переменная есть Trip, она изменяется в настройках, т.е. под разную длину окружности колеса. Ее думаю тоже можно dword или подобну/ . У меня это значение в килорметрах там.
Залил их красный тонировочным лаком, теперь видно нормально
Поделиться592018-03-07 21:35:58
K = L \ 2100 ' Trip = 0.000181 * K
вот. программа по умолчанию считалась на длину окружности 2100мм. L это параметр длины который можем задать сами. ну и по формуле корректируется показания и пробег под другую длину
Поделиться602018-03-08 11:56:08
вот. программа по умолчанию считалась на длину окружности 2100мм. L это параметр длины который можем задать сами. ну и по формуле корректируется показания и пробег под другую длину
А в чем смысл напрягать МК для этой геометрии ?
Или колеса за поездку не по разу меняются ?
Вводить уже готовый коэффициент.