Данные с чипа представляют собой пакеты с периодом в 1 Гц. Выглядят они так Спойлер$GNRMC,180159.00,A,5137.81278,N,03815.19037,E,2.468,71.94,050119,,,A*4C $GNVTG,71.94,T,,M,2.468,N,4.570,K,A*16 $GNGGA,180159.00,5137.81278,N,03814.19037,E,1,05,2.40,143.2,M,12.1,M,,*45 $GNGSA,A,3,19,06,12,13,,,,,,,,,3.37,2.40,2.37*14 $GNGSA,A,3,87,,,,,,,,,,,,3.37,2.40,2.37*14 $GPGSV,2,1,07,06,14,141,42,09,,,14,12,27,265,10,13,18,193,25*41 $GPGSV,2,2,07,17,59,073,,19,68,128,12,40,29,160,*46 $GLGSV,2,1,05,67,09,251,,68,22,302,,76,39,104,08,77,70,335,*66 $GLGSV,2,2,05,87,44,162,24*5C $GNGLL,5137.81278,N,03915.19037,E,190159.00,A,A*75 В строке GNRMC идут уже обработанные данные, содержащими точное время по Гринвичу, вычисленные координаты и дату. Причем если спутники не найдены, чип все равно выдает информацию о времени. Видимо, там есть собственный таймер. На Attiny2313 идет обработка принятых по UART данных. Код был найден в Интернете и многократно переписан. По сути алгоритма микроконтроллер просто ждет, когда в потоке данных появится буква R, после чего отсчитывает знаки времени и выводит их на индикаторы. Все остальное я выкинул в целях упрощения. Индикаторы газоразрядные ИН-12. управление на оптронах TLP627 Код писался в БаскомАВР. Спойлер' Часы, которые принимают данные с GPS модуля по UART ' Прямые фузы 3F-8F-D-FF ' DWEN ' BODLEVEL2 - BODLEVEL1 - BODLEVEL0 - RSTDISBL ' CKDIV8 - CKOUT - SUT0 ' CKSEL3 - CKSEL2 ' Fuse http://homes-smart.ru/fusecalc/?prog=av ... ATtiny2313 ' http://www.engbedded.com/fusecalc
$hwstack = 40 ' default 40 Размер аппаратного стека $swstack = 16 ' default 16 Размер программного стека $framesize = 32 ' default 32 размер области используемой и необходимой для преобразований
Ddrb = &B00111111 ' конфиг порта B - 1=Output выход Ddrd = &B0111110 ' конфиг порта D - 0=Input вход
Portb.6 = 1 Portb.7 = 1
' без этой строчки UART вообще гадости пишет на аппаратном порту Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 'Config Serialin = Buffered , Size = 12
Dim I(6) As Byte Dim Count As Byte Dim Varval As Byte Dim Buf_count As Integer 'Возвращает строку из нескольких символов указанного ASCII кода. Dim S As String * 1 'строка со спутника Dim Sh As String * 2 Dim B As Byte Dim _p As Byte ' poyas +3
Dig1 Alias Portb.0 : Dig2 Alias Portb.1 : Dig3 Alias Portb.2 : Dig4 Alias Portb.3 : Dig5 Alias Portb.4 : Dig6 Alias Portb.5
'***********************[Начало основной программы]**************************************** Enable Interrupts ' разрешаем все прерывания Enable Ovf0 ' и для индикации в частности Enable Oc0a ' загрузка значения яркости катодов в регистр сравнения Ocr0a = 32
B = Waitkey() ' берем символ из буфера в формате ASCII If B = 82 Then Buf_count = 0 ' нашли букву R (82 ascii) Incr Buf_count ' : If Buf_count > 200 Then Buf_count = 20
If Buf_count <> 6 Then S = Chr(b) If Buf_count = 6 Then Sh = S + Chr(b) ' сложение в строку
Varval = Val(sh) + _p ' для добавления часового пояса If Varval > 23 Then Varval = Varval - 24
I(1) = Varval / 10 I(2) = Varval Mod 10
' S = Chr(b) ' 48(ascii)=0 49=1 ... 57=9
' If Buf_count = 5 Then I(1) = Val(s) ' If Buf_count = 6 Then I(2) = Val(s) If Buf_count = 7 Then I(3) = Val(s) If Buf_count = 8 Then I(4) = Val(s) If Buf_count = 9 Then I(5) = Val(s) If Buf_count = 10 Then I(6) = Val(s)
If Buf_count = 11 Then
If Pinb.6 = 0 Then Incr _p : If _p > 12 Then _p = 0 : Writeeeprom _p , 16 ' увеличить часовой пояс If Pinb.7 = 0 Then Decr _p : If _p < 1 Then _p = 0 : Writeeeprom _p , 16 ' уменьшить часовой пояс
Incr Count : If Count > 6 Then Count = 1 ' выбираем какой разряд сейчас включать
Portd = Lookup(i(count) , Digits) ' закидываем в порт код цифры
Select Case Count ' включаем соответствующий разряд индикатора Case 1 : Set Dig1 Case 2 : Set Dig2 Case 3 : Set Dig3 Case 4 : Set Dig4 Case 5 : Set Dig5 Case 6 : Set Dig6 End Select
' End If
Return
Digits: ' это цифры для ИН-12 Data &B0110000 , &B0010000 , &B0001000 , &B0100000 , &B0000100 , &B0101100 , &B0101000 , &B0001100 , &B0100100 В-общем, если кому будет интересно повторить, добавлю исходники и печатные платы. Платы две. Плата для индикаторов отдельно. Питание схемы от 220 Вольт через блок питания на LNK304. Питание анодов тоже от 220 через резистор, чтобы преобразователь не лепить. ----- Идея сделать часы, которые не надо было бы подводить, сама по себе интересна. Но я никак не могу победить странный глюк. Микроконтроллер сам по себе останавливается. Обычно это выглядит как остановка динамической индикации. Ярко горит одна цифра и все. Причем Watchdog не помогает. просто намертво останавливается и все. EEPROM тоже слетает. Напряжение в норме, конденсаторы керамические по питанию есть, квар менял, другие МК покупал.. схему и печатку проверял.. Код много кратно переписывал, выкинув все, что можно..
Попробуйте писать в еепром отметки о прохождении каких-то ключевых точек. Есть в 2131 еепром? Если нет - может быть, внешнюю пока приделать? чтобы понять, на чём именно затыкается. Анализировать исходник, наверно, бесполезно. Кстати, о птичках. Разбирая строку NMEA, игнорируйте две первые буквы, это прибавит универсальности. Американский Navstar даёт GP, наш ГЛОНАСС - не помню какие. вроде GL, но не уверен. Свои часы, тоже с коррекцией по GPS, я делал на STM32 в порядке освоения семейства МК.
_________________ ВНИМАНИЕ! Я часто редактирую свои сообщения, поэтому перед ответом мне советую обновить страницу. За перенос модераторами в МЯВУ тем с моими сообщениями я ответственности не несу.
Я когда разбирал NMEA- обратил внимание что там точное время ажно в двух строках бывает, в итоге решил вылавливать строку GPRMC. Точнее- я вылавливал строку, содержащую символы [RMC,], а дальше в этой строке вылавливал символы, стоящие на определенных позициях (с первой позиции после запятой). Код вышел тупой и корявый, я писал в CodeVisionAVR, однако ж часы успешно работают уже второй год и совершенно не глючат. Даже с будильником. Даже умеют включать по будильнику нагрузку (лампочку). Даже с ИК-пультом (чтоб включать лампочку с дивана). Даже с памятью (внешней 24с02)- хранить данные о будильнике если вырубится электричество. Шикарные часики вышли! На Atmega8. Обработку строк запихнул тупо в обработчик прерываний по факту приема чего-нибудь по UART. Никаких еепромов (он частенько слетает), никакой ненужной фигни. Принял, выловил символы, запихнул в глобальные переменные. Показал на индикаторе в определенный момент. Ну а потом еще чего-нить поделал- времени между посылками по уарту вагон.
Покажу кусочек кода, мобыть вам пригодится... пишу всегда с подробными комментариями, а то потом не помню нифига. Схему, естественно, приводить не буду- во-первых у вас своя есть, а во-вторых её и не существует... не рисовал. Ограничился сразу разводкой ПП в Layout.
void indtime(void) //индикация времени { //ваша процедура вывода глобальных переменных часов и минут на индикатор }
// прием данных по USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { // никаких проверок с буферизациями не ведем. Если нужна проверка- смотрим флаги регистра UCSRA unsigned char data=0;
if (string_catch) //если строку уже поймали { switch (symb_count) //смотрим сколько чего уже принято { //считывание текущего времени // $GPRMC,,V,,,,,,,,,,N*76... - когда спутников нет и не было // $GPRMC,042318.00,V,,,,,,,140217,,,N*76... - когда время таки приняли, а координат еще нет и нафиг не нужны
case 0: data=UDR; //считываем содержимое регистра (считать обязательно в любом случае!) if (data>0x2F&&data<0x3A) //если там не запятая или еще какой знак { //считаем что время принимается корректно и больше на эту тему не паримся data-=0x30; //доводим до нормального состояния по таблице, данные передаются в ASCII, иметь в виду! hrs=data*10; //десятки часов symb_count++; //увеличиваем счетчик принятых символов (байт) } else //если приняли запятую или х-ню { symb_count=0; //обнуляем счетчик принятых символов string_catch=0; //считаем что строка не принята } break; //далее аналогично, уже без проверки принятого символа case 1: data=UDR; data-=0x30; hrs+=data; symb_count++; break;
case 2: data=UDR; data-=0x30; min=data*10; symb_count++; break;
case 3: data=UDR; data-=0x30; min+=data; symb_count++; break;
case 4: data=UDR; data-=0x30; seconds=data*10; symb_count++; break;
case 5: data=UDR; data-=0x30; seconds+=data;
if (seconds<1) //один раз в минуту в первую секунду indtime(); //показываем принятое время //если вы используете секунды в индикации- можете делать это ежесекундно. Мне секунды не нужны- я их не показываю.
symb_count=0; //обнуляем счетчик принятых символов string_catch=0; //когда все принято- ставим флаг что можно опять ловить строку } }
if (!string_catch) //если нужную строку еще не поймали { gprmc=gprmc<<8; //cдвигаем влево на байт gprmc=gprmc|UDR; //в младший байт пишем содержимое UDR if (gprmc==0b01010010010011010100001100101100) //если выловили символы [ RMC, ] string_catch=1; //ставим флаг что строка выловлена } }
Народ, зачем вы заставляете GPS выдавать всю эту кучу пакетов? У GPS-модулей есть команды, которые позволяют "придавить" вывод той или иной информации. Я в своем хронометре только RMC строку и принимаю - зачем мне остальные? Ну, а прерывание PPS синхронизирует таймер Systick. Сделал на основе модуля L80-R (три с половиной бакса супротив вашего за червонец!).
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Народ, зачем вы заставляете GPS выдавать всю эту кучу пакетов? У GPS-модулей есть команды, которые позволяют "придавить" вывод той или иной информации.
Затем, что во-первых надо городить ключ на выход уарта, бо модуль хоть и питается от 5 вольт, а на вход ему только 3.3 максимум подавать изволь. У меня VK2828U7G5 - потому что у него хорошая антенна сразу "на борту". Про ваш модуль я вообще не знал, а жаль... Во-вторых все равно надо еще в момент первого включения контроллера все эти команды в него запихивать, так что объем кода шибко меньше не становится. Посему я здраво рассудил что нехай говорит себе что хочет, а слушать мы будем только строку RMC.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
И правильно. Я тоже в своём будильнике проверяю буквы в принимаемой строке; если она не RMC, то просто на неё плюю... тьфу, игнорирую её. Быстродействия STM32 на это хватает.
_________________ ВНИМАНИЕ! Я часто редактирую свои сообщения, поэтому перед ответом мне советую обновить страницу. За перенос модераторами в МЯВУ тем с моими сообщениями я ответственности не несу.
Ничего не понял, какой ключ? STM32 питается от 3.3В.
Opamp писал(а):
Про ваш модуль я вообще не знал, а жаль...
Есть и еще более дешевые, но у них антенка совсем дохлая. Правда, я недавно купил себе "удлинитель" GPS (получил вчера на почте): ретранслятор с пятиметровым шнурком. Проверил на кухне - кайф! Если без него вообще ни одного спутника лопата не видит, то с ним - уже десяток!!! Правда, удовольствие недешевое - 10 баксов. Возможно, проще внешнюю антенну своему GPS-модулю прицепить.
Opamp писал(а):
надо еще в момент первого включения контроллера все эти команды в него запихивать
А в чем проблема? UART же!
Opamp писал(а):
объем кода шибко меньше не становится
Там кода - с гулькин нос!
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
_________________ Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда. Я на гитхабе, в ЖЖ
я наконец-то разгадал загадку глюка. Во всем виноваты газоразрядные индикаторы. Когда МК обрабатывает данные со спутника, туда иногда прилетает какой-то мусор. Или сам МК иногда ошибается. В-общем, в массив записывается не цифра от 0 до 9, а знак или буква.. А когда нецифра из порта попадает на дешифратор 155ИД1, то он не знает, какой вывод зажигать. И не зажигает никакой. А это - нештатный режим. ПРи работе газоразрядных индикаторов один из катодов всегда должен быть задействован, иначе на выводах 155ИД1 появляется очень высокое напряжение. А уже импульс этого напряжения пролетает либо по питанию, либо со входа дешифратора в микроконтроллер и сносит там все нахрен. Блокировочные конденсаторы не помогают. Питал дешифратор через диод - не помогло. Видимо, все-такие со входа дешифратора. Ну и соответсвенно, пришлось изменить прошивку. Добавил проверку на диапазон чисел при записи в массив If B >= 48 And B <= 57 Then и на всякий случай такую же проверку If I(count) >= 0 And I(count) <= 9 Then при зажигании анодов. То есть чтобы при крюкозябрах в массиве даже анодное не подавалось. Нет импульса -не будет и помехи. Вот теперь часы заработали. Правда, ЕЕПРОМ там все равно глючный. Иногда все-таки его сносит. Так что такой глюк не проявился бы при использовании светодиодных или ЖКИ индикаторов. Спойлер' Часы, которые принимают данные с GPS модуля по UART ' Прямые фузы 3F-9F-D-FF ' DWEN - WDTON ' BODLEVEL2 - BODLEVEL1 - BODLEVEL0 - RSTDISBL ' CKDIV8 - CKOUT - SUT0 ' CKSEL3 - CKSEL2 ' Fuse http://homes-smart.ru/fusecalc/?prog=av ... ATtiny2313 ' http://www.engbedded.com/fusecalc
$hwstack = 40 ' default 40 Размер аппаратного стека $swstack = 16 ' default 16 Размер программного стека $framesize = 32 ' default 32 размер области используемой и необходимой для преобразований
Ddrb = &B00111111 ' конфиг порта B - 1=Output выход Ddrd = &B1111110 ' конфиг порта D - 0=Input вход
Portb.6 = 1 Portb.7 = 1 Portd.0 = 1
' без этой строчки UART вообще гадости пишет на аппаратном порту Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 ' Config Serialin = Buffered , Size = 1
Dim I(6) As Byte Dim Count As Byte Dim Varval As Byte Dim Buf_count As Byte Dim S As String * 1 Dim Sh As String * 2 Dim B As Byte Dim _p As Byte ' poyas +3
Dig1 Alias Portb.0 : Dig2 Alias Portb.1 : Dig3 Alias Portb.2 : Dig4 Alias Portb.3 : Dig5 Alias Portb.4 : Dig6 Alias Portb.5
S = "0" B = Waitkey() ' берем символ из буфера в формате ASCII
If B = 82 Then ' нашли букву R (82 ascii) Buf_count = 0 ' Reset Watchdog ' сбросить собаку Else Incr Buf_count : If Buf_count > 200 Then Buf_count = 10 End If
If B >= 48 And B <= 57 Then ' ASCII ,-44 0-48 9-57 (если цифры)
If Buf_count <> 5 Then S = Chr(b) If Buf_count = 5 Then Sh = S + Chr(b) ' сложение в строку
Varval = Val(sh) + _p ' для добавления часового пояса If Varval > 23 Then Varval = Varval - 24
' S = Chr(b) 'B - 048
If Buf_count = 4 Then I(1) = Varval / 10 If Buf_count = 5 Then I(2) = Varval Mod 10 If Buf_count = 6 Then I(3) = Val(s) If Buf_count = 7 Then I(4) = Val(s) If Buf_count = 8 Then I(5) = Val(s) If Buf_count = 9 Then I(6) = Val(s)
End If
If Buf_count = 10 And Pinb.6 = 0 Then ' увеличить часовой пояс Incr _p If _p > 24 Then _p = 0 Writeeeprom _p , 100 End If
If Buf_count = 10 And Pinb.7 = 0 Then ' уменьшить часовой пояс Decr _p Writeeeprom _p , 100 End If
Incr Count : If Count > 6 Then Count = 1 ' выбираем какой разряд сейчас включать
If I(count) >= 0 And I(count) <= 9 Then ' не зажигать, если мусор
Portd = Lookup(i(count) , Digits) ' закидываем в порт код цифры
Select Case Count ' включаем соответствующий разряд индикатора Case 1 : Set Dig1 Case 2 : Set Dig2 Case 3 : Set Dig3 Case 4 : Set Dig4 Case 5 : Set Dig5 Case 6 : Set Dig6 End Select End If
Return
Digits: ' это цифры для ИН-12 Data &B0110000 , &B0010000 , &B0001000 , &B0100000 , &B0000100 Data &B0101100 , &B0101000 , &B0001100 , &B0100100 , &B0000000
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения