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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Часы с GPS по UART


Часы с GPS по UART

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

1

Купил я на Али дешевый чип, который принимает сигналы 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)

0

2

Похвастайтесь схемой высоковольтного ?

0

3

Для начала увеличьте

Код:
$hwstack = 2                                                ' default
$swstack = 8                                                ' default
$framesize = 2

хотя бы так:

Код:
$hwstack = 32
$swstack = 16
$framesize = 32

0

4

goldskif
Я бы принимал в буфер,в справке к Баскому CONFIG SERIALIN.

0

5

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

Похвастайтесь схемой высоковольтного ?

я не делал повышатель. Схема питания на LNK304PN бестрансформаторная снижает до 5В и оттуда же от сети после мости через резистор 33К на аноды.

0

6

подскажите, если строка, принимаемая по UART имеет длину 66 знаков, то какого размера должен быть буфер?
Или данные оттуда можно выгребать по мере получения?

0

7

Всё зависит какой прием организован, аппаратный или софтовый.
В софтовом режиме буфер организовывать придется, т.к. между пакетами обычно есть пауза (несколько Гц), вот за неё надо распарсивать пришедшие данные. В реалтайме принимать не получится, точнее: велика вероятность пропустить нужные данные (вначале приняли, потом обрабатываем).
Если аппаратный уарт, то как угодно можно, там данные потерять очень сложно (если понимать, что происходит).

0

8

Аппаратный на Attiny2313. Строка со спутника 66 знаков. Идет группами с периодом в 1Гц. Но какой-то глюк в железе вылез, часы моргают, а через какое-то время останавливается МК. Что-то с буфером.
И вообще не компилилось (Out of Space), пока не урезал
$hwstack = 8                                                ' default 40
$swstack = 8                                                ' default 16
$framesize = 8                                              ' default 32

0

9

goldskif
Не пробовал сделать размер буфера 255?

0

10

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

Аппаратный на Attiny2313. Строка со спутника 66 знаков. Идет группами с периодом в 1Гц. Но какой-то глюк в железе вылез, часы моргают, а через какое-то время останавливается МК. Что-то с буфером.

Вот отсюда Исследование USART (пост 5) пользую на-ура (спасибо Александру).
Устанавливаете свои нужную размерность буфера и, если есть, код символа окончания передачи.
Если такого кода нет, то контролируете наполнение буфера.
Работает железно.

Отредактировано Nord (2018-04-26 18:44:35)

0

11

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

Вот отсюда Исследование USART (пост 5) пользую на-ура (спасибо Александру).
Устанавливаете свои нужную размерность буфера и, если есть, код символа окончания передачи.
Если такого кода нет, то контролируете наполнение буфера.
Работает железно.
Отредактировано Nord (Сегодня 18:44:35)

Ссылка битая?

0

12

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

goldskif
Не пробовал сделать размер буфера 255?

Пробовал. Все что больше 16 - ругается на Out of Space

0

13

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

Ссылка битая?

Ссылка не битая, это вы заходите на ....3bb... ;)
Попробуйте по этому пути: "» Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование USART."

0

14

Это снова я. После рабства в период летне-дачной жизни вдали от цивилизации решил все-таки добить этот проект. Он по прежнему глючит.
То есть динамическая индикация работает какое-то время нормально, но когда подключаешь GPS и начинается прием данных, срываются из генерации порты B, подающие питание на аноды. Останавливаются на какой-то одной цифре и она ярко светит.
Пытался после приема данных выключать порт аппаратного UARTA командой UCSRB.4 = 0. Прием прекращается, но динамическая индикация все равно через какое-то время останавливается на одной цифре. В Протеусе работает. В железе -глючит. Есть у кого какие мысли?

Код:
' Часы, которые принимают данные с GPS модуля по UART

$regfile = "attiny2313.dat"
$crystal = 3686400
' Fuse Uniprog - галки на - CKSEL2 - CKSEL3 - SUT1 - CKOUT - CDKID8

$baud = 9600

'***********************[Инициализация прерываний]*****************************************

Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0     ' конфигурируем таймер индикации (~500 Гц)
On Ovf0 Refresh                                             ' обзываем прерывание индикации
On Oc0a Dimmer                                              ' вектор прерывания по совпадению (длительность импульса)

Ddrb = &B00111111                                           ' конфиг порта B - 1=Output выход
Ddrd = &B0111110                                            ' конфиг порта D - 0=Input вход

Pinb.6 = 1
Pinb.7 = 1

' без этой строчки UART вообще гадости пишет на аппаратном порту
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Dim _datatime As String * 6
Dim _time As String * 2                                     'часы

Dim Varval As Byte

Dim I(6) As Byte
Dim Count As Byte

Dim S As String * 14                                        'строка со спутника
Dim B As Byte
Dim Z As String * 1

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 = 64

' **********************[Основной цикл] **************************
'раскладываем строку содержащую идентификатор $GNRMC
'пример строки
'$GNRMC,180159.00,A,5136.81278,N,03914.19037,E,2.468,71.94,050118,,,A*4C
'$GNVTG,71.94,T,,M,2.468,N,4.570,K,A*16
'$GNGGA,180159.00,5136.81278,N,03914.19037,E,1,05,2.40,143.2,M,12.1,M,,*45

Do

      S = ""
      Do
      B = Inkey()                                           ' берем символ из буфера в формате ASCII
      Select Case B
         Case 10 : If S <> "" Then Exit Do                  'конец строки - выходит из подпрограммы  *=42 .=46
        Case Else : If B > 31 Then S = S + Chr(b)           'печатаемые символы начинаются с кода 32 по таблице АСКИ, из них составляем строку
      End Select
      Loop

      Z = Mid(s , 4 , 1)                                    'вытаскиваем строку с буквой R

      If Z = "R" Then                                       ' Только для строки "$GNRMC"
      _datatime = Mid(s , 8 , 6)
'      Ucsrb.4 = 0                                           ' запрет приема UART 0-выкл 1 вкл
      End If

    Do
    B = Inkey()                                             'забираем все из буфера
    Loop Until B = 0

       _time = Mid(_datatime , 1 , 2)                       ' выдираем часы (цифры 8-10-12) Date 54-56-58
       Varval = Val(_time) + 3                              ' Val Превращает строку в число

      If Varval > 23 Then Varval = Varval - 24

I(1) = Varval / 10                                          ' формат отображения времени: hh.mm.ss
I(2) = Varval Mod 10

       _time = Mid(_datatime , 3 , 2)                       ' --  минуты
Varval = Val(_time)
I(3) = Varval / 10
I(4) = Varval Mod 10

       _time = Mid(_datatime , 5 , 2)                       ' -- секунды
Varval = Val(_time)
I(5) = Varval / 10
I(6) = Varval Mod 10


Loop


'***********************[DATA]****************************************************

Digits:                                                     ' это цифры для ИН-12
Data &B0110000 , &B0010000 , &B0001000 , &B0100000 , &B0000100 , &B0101100 , &B0101000 , &B0001100 , &B0100100 , &B0000000 , &B0111100

'***********************[Процедуры обработки подпрограмм и прерываний]*******************************

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

Отредактировано goldskif (2018-10-27 13:11:31)

0

15

Размер стеков какой? Возможно дело в этом. Сбой из-за переполнения.

0

16

Как же я сильно ругался неприличными словами.... Это дешифратор! Тварь... К155ИД1 Ну казалось бы, дубовая ТТЛ логика...палка и веревка.. Так хрен.. Именно она сбрасывалась. Причем весьма непредсказуемо..

0

17

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

Это дешифратор! Тварь... К155ИД1 Ну казалось бы, дубовая ТТЛ логика...палка и веревка.. Так хрен.. Именно она сбрасывалась. Причем весьма непредсказуемо..

Какая скорость обмена через этот дешифратор ?
Не стоит забывать, что 155-я логика весьма медлительна и, если (например) хххЛА3 легко переварит 1 МГц, то хххИЕ5 еле потянет 100 кГц... ;)
Я говорю про скорость входных данных, при которой гарантировано безошибочное состояние на выходе.

0

18

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

Какая скорость обмена через этот дешифратор ?
Не стоит забывать, что 155-я логика весьма медлительна и, если (например) хххЛА3 легко переварит 1 МГц, то хххИЕ5 еле потянет 100 кГц...
Я говорю про скорость входных данных, при которой гарантировано безошибочное состояние на выходе.

Кристалл 3686400
Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0     ' конфигурируем таймер индикации
Хз. Это какая частота будет в итоге? 57,6 Кгц?
Вообще подглючивает все равно. Срывается. Помогает вручную reset Attiny на первую ногу замкнуть..

Отредактировано goldskif (2018-10-27 22:43:21)

0

19

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

Это какая частота будет в итоге? 57,6 Кгц?Вообще подглючивает все равно. Срывается.

Ноги данных для индикаторов с таймером связаны походу...
Задействовано событие 0С0А - это порт В.

А в чем проблема использовать Мега 8 ?
Все сраслось бы гораздо проще...

Отредактировано Nord (2018-10-27 23:35:37)

0

20

Ну как бы использовал уже проверенную схему. DS1307+Attiny2313+К155ИД1+ИЕ12 работает до сих пор нормально который год. ВОт и решил на базе проверенной схемы сделать часы от GPS.
PORTB это аноды. На опротроны выходы
http://s7.uploads.ru/t/6PtmC.jpg

Отредактировано goldskif (2018-10-28 00:00:05)

0

21

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

PORTB это аноды. На опротроны выходы(Сегодня 00:00:05)

Событие 0С0А пишется в регистр порта.
В изначальной ("проверенной") схеме Timer0 задействован был ?
Если да, то надо искать проблему в другом, если нет, то надо отключать событие 0С0А от ноги порта.
Каким-то регистром это делается. Листайте даташит...

Отредактировано Nord (2018-10-28 00:19:46)

0

22

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

Событие 0С0А пишется в регистр порта.
В изначальной ("проверенной") схеме Timer0 задействован был ?
Если да, то надо искать проблему в другом, если нет, то надо отключать событие 0С0А от ноги порта.
Каким-то регистром это делается. Листайте даташит...
Отредактировано Nord (Сегодня 00:19:46)

Да, это регулировка длительности анодных импульсов. Оптроны тормозные, пока выключаться, уже следующая цифра включится успевает. Это приводит к паразитной засветке индикаторов. Это в изначальной схеме было.
Так что добавилось только получение данных по UART.
Может, Watchdog куда вставить?

Отредактировано goldskif (2018-10-28 00:36:31)

0

23

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

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

Тогда надо копать в другом направлении:

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

Так что добавилось только получение данных по UART.

Где-то они с таймером перехлестываются...
Не углублялся в листинг, да и неполный он какой-то... ;)
При работе с UART надо отключать прерывание таймера и наоборот.

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

Может, Watchdog куда вставить?

Думаю, это будет только лишней заморочкой... ;)

Отредактировано Nord (2018-10-28 00:55:03)

0

24

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

При работе с UART надо отключать прерывание таймера и наоборот.

Вот думаю, тут собака и зарыта.. А как? Есть примеры?

0

25

В тиньке есть аппаратный UART и отключать прерывания не нужно.

0

26

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

Вот думаю, тут собака и зарыта.. А как? Есть примеры?

Для начала, думаю, определиться со способом приема. ;)
Судя по фрагменту вашего листинга, UART читается силами INKEY, а это мало связано с включением или отключением UART через регистр UCSRB.
UART отключили, а INKEY ждет...
Переходите на прием UART по прерыванию, тогда будет возможность отключения...

Пётр написал(а):

В тиньке есть аппаратный UART и отключать прерывания не нужно.

Так он так и делает, через UCSRB, только результата нет... ;)

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Часы с GPS по UART