Купил я на Али дешевый чип, который принимает сигналы GPS и выдает по UART.
Захотел сделать просто часы. Ну чтобы сигнал времени принимался по UART, обрабатывался на Attiny2313 (Потому что есть у меня) и выводился на динамическую газоразрядную индикацию на ИН-12. До этого я делал такие часы на 2313 и 155ИД1+ИН-12, думал, справлюсь. Но вот тут знания по AVRу закончились.
В-общем, сигнал-то они принимают, но дело в том, что сигналы с чипа идет группами по нескольку строк. с периодичностью раз в секунду. И получается, что цифры на часах моргают. Между правильным временем выскакивают ненужные значения и прочий мусор.
Видимо, какой-то временный буфер нужен для хранения времени?
' Часы, которые тупо принимают данные с GPS модуля по UART
$regfile = "attiny2313.dat"
$crystal = 3686400
' Fuse Uniprog - галки на - CKSEL2 - CKSEL3 - SUT1 - CKOUT - CDKID8
$baud = 9600
$hwstack = 2 ' default
$swstack = 8 ' default
$framesize = 2
'Ucsra.6 = 0
Ucsrb.3 = 0
Ddrb = &B11111111 ' конфиг порта B - 1=Output
Ddrd = &B1111110 ' конфиг порта D - 0=Input
'Portd.1 = 0
'Config Portb = Output ' порт сегментов
' без этой строчки UART вообще гадости пишет даже на аппаратном порту
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Dim I(6) As Byte
Dim Count As Byte
Dim S As String * 80 'строка со спутника
Dim B As Byte
Dim R As Byte
Dim Z As String * 4
Dim _day As String * 2 ' день
Dim _month As String * 2 ' месяц
Dim _year As String * 2 ' год
Dim _hour As String * 2 'часы
Dim _min As String * 2 'минуты
Dim _sec As String * 2 'секунды
Dim Varval As Integer
Dim Poyas As Byte
Dig1 Alias Portb.0 : Dig2 Alias Portb.1 : Dig3 Alias Portb.2 : Dig4 Alias Portb.3 : Dig5 Alias Portb.4 : Dig6 Alias Portb.5
$eeprom 'обращение к блоку данных
Data &H34
$data
'***********************[Инициализация прерываний]*****************************************
Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0 ' конфигурируем таймер индикации (~500 Гц)
On Ovf0 Refresh ' обзываем прерывание индикации
On Oc0a Dimmer ' вектор прерывания по совпадению (длительность импульса)
'***********************[Начало основной программы]****************************************
Enable Interrupts ' разрешаем все прерывания
Enable Ovf0 ' и для индикации в частности
Enable Oc0a
' загрузка значения яркости катодов в регистр сравнения
Ocr0a = 64
' **********************[Основной цикл] **************************
'раскладываем строку содержащую идентификатор $GPRMC
'пример строки
'$GNRMC,045103.000,A,3014.1984,N,09749.2872,W,0.67,161.46,030913,,,A*7c
'$GNRMC,180215.00,A,5136.80492,N,03914.19482,E,1.575,,050118,,,A*65
Readeeprom Poyas , 0 ' получить часовой пояс
If Poyas = 0 Then ' если пусто
Poyas = 3
Writeeeprom Poyas , 0 ' записать один раз
End If
Do ' основной цикл
S = ""
Do
B = Inkey() 'берем символ из буфера в формате ASCII
Select Case B
Case 10 : If S <> "" Then Exit Do 'конец строки, значит выходит из подпрограммы
Case Else : If B > 31 Then S = S + Chr(b) 'печатаемые символы начинаются с кода 32 по таблице АСКИ, из них составляем строку
End Select
Loop
Z = Left(s , 4) 'вытаскиваем левые 4 символа
If Z = "$GPR" Then ' Только для строки "$GPRMC"
_hour = Mid(s , 8 , 2) ' выдираем часы (цифры 8-10-12) Date 54-56-58
_min = Mid(s , 10 , 2) ' -- минуты
_sec = Mid(s , 12 , 2) ' -- секунды
_year = Mid(s , 58 , 2)
_month = Mid(s , 60 , 2)
_day = Mid(s , 62 , 2)
' тут надо поправку на часовой пояс
Varval = Val(_hour) + 3 ' Val Превращает строку в число
If Varval > 23 Then
Varval = Varval - 24
End If
I(1) = Varval / 10 ' формат отображения времени: hh.mm.ss
I(2) = Varval Mod 10
Varval = Val(_min)
I(3) = Varval / 10
I(4) = Varval Mod 10
Varval = Val(_sec)
I(5) = Varval / 10
I(6) = Varval Mod 10
Waitms 10
End If
B = 0 'забираем все из буфера
Loop
'***********************[Процедуры обработки подпрограмм и прерываний]*******************************
Refresh: ' прерывание таймера Т0 (индикация)
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
Return
Dimmer: ' прерывание таймера Т0 (регулировка яркости)
Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4 : Reset Dig5 : Reset Dig6 ' гасим индикатор
Return
'***********************[DATA]****************************************************
Digits: ' это цифры для ИН-12
Data &B0110000 , &B0010000 , &B0001000 , &B0100000 , &B0000100 , &B0101100 , &B0101000 , &B0001100 , &B0100100 , &B0000000 , &B0111100Отредактировано goldskif (2018-04-18 00:50:43)

