Помогите разобраться новичку - Страница 4 - Форум Picbasic.ru
Регистрация | Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 4 из 11«1234561011»
Модератор форума: demanik 
Форум Picbasic.ru » Программирование МК » Proton PicBasic » Помогите разобраться новичку (как правильно?)
Помогите разобраться новичку
G2212 Дата: Чт, 07.02.2013, 09:41  |                                                                                                                Сообщение # 46
Группа: Проверенные
Ранг:  Начал соображать
Сообщений: 37
Репутация: 0   ±
Замечания:   ±
На сайте с 06.11.2012

Статус: Offline

Большое спасибо dimitriy-bc !!
Код работает. Дальше буду проверять как будет лучше работать.
Теперь хоть есть отталкиваться.
ЯНДЕКС Дата: 07.02.2013
MiXaS Дата: Ср, 17.04.2013, 12:01  |                                                                                                                Сообщение # 47
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

Здрасте! Не хочу создавать новую тему, поэтому тут нагажу. Попробую на пальцах.
Пытаюсь написать MODbus slave, да я знаю, что есть такая тема, но тут немного не про него. Так вот, столкнулся с такой проблемой. При записи массива данных, которые прилетают по USART, делаю сразу же чтение массива, всё работает нормально, но стоит мне отправится в метку для расчета контрольной суммы, там уже какие-то другие данные (в массиве). В итоге CRC неправильная. Замечено, что при такой конструкции всё работает как хочется.

Код
MAIN_SOFT:

If NewFrame = 1 Then ' флаг о новом фрейме

For a = 0 To (Length-1)

HRSOut Buffer  

[a]Next

Length=0 ' сбросить длину фрейма
NewFrame = 0 ' сбросить флаг нового фрейма

EndIf
GoTo MAIN_SOFT


ТО есть что прилетело, то и улетело обратно.

Далее нам нужно отбросить CRC письма и посчитать свой CRC.

Код
MAIN_SOFT:

If NewFrame = 1 Then ' флаг о новом фрейме

Length = Length-2 ' последние 2 байта содержат CRC, которое находится в посылке (массиве)

GoSub MB_CRC_RTU ' отправляюсь в метку для расчета

HRSOUT CRC16 [1], CRC16 [2] ' отправить обратно значение посчитанного CRC

Length=0 ' сбросить длину фрейма
NewFrame = 0 ' сбросить флаг нового фрейма

EndIf
GoTo MAIN_SOFT


Получаю чушь!!! Но стоит мне добавить...

MAIN_SOFT:

If NewFrame = 1 Then ' флаг о новом фрейме

Length = Length-2 ' последние 2 байта содержат CRC, которое находится в посылке (массиве)

HRSOUT Buffer [1]
delayms 10


GoSub MB_CRC_RTU ' отправляюсь в метку для расчета

HRSOUT CRC16 [1], CRC16 [2] ' отправить обратно значение посчитанного CRC

Length=0 ' сбросить длину фрейма
NewFrame = 0 ' сбросить флаг нового фрейма

EndIf
GoTo MAIN_SOFT

Прилетает всё как положено. Такое впечатление. что при переходах на метки данные теряются.
Использовал COMPUMP.

Посылал 001.003.000.012.000.001.068.009, где 2 самых правых байта CRC, который должен быть расчитан и отправлен обратно. HEX 4409 - 068. 006

2 дня уже ушатал, думал метка CRC неправильная.
Да, при переходе на другие метки, всё что я написал, повторяется. Разници нет куда переходить. Смысл один.
Спасибо!

Добавлено (17.04.2013, 12:01)
---------------------------------------------

Цитата (MiXaS)
HEX 4409 - 068. 009

сорри
Прикрепления: CRC.zip(56Kb)

Сообщение отредактировал MiXaS - Ср, 17.04.2013, 11:58
anatol Дата: Ср, 17.04.2013, 14:04  |                                                                                                                Сообщение # 48
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

MiXaS, что это
Код
 Buffer[1] = 1
     Buffer[2] = 3          ' Функция
     Buffer[3] = 2          ' Количество байт данны
     Buffer[4] = %00000000
     Buffer[5] = %11111111

и это
Код
 Buffer [Length]= RCREG
Какое значение буфера правильное? Принятое или константа?

А это
Length будет равен минус 1?
Код
 For a = 0 To (Length-1)
Еслия не прав, что вполне возможно, то из-за прикидочного просмотра тела программы.
MiXaS Дата: Ср, 17.04.2013, 14:41  |                                                                                                                Сообщение # 49
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

anatol,  Это куски, я представил для того, чтобы показать, что происходт с программой.

Код
Buffer[1] = 1  
      Buffer[2] = 3          ' Функция  
      Buffer[3] = 2          ' Количество байт данны  
      Buffer[4] = %00000000  
      Buffer[5] = %11111111

Это ответ slave устройства, но на него пока не нужно обращать внимание, так как оно находится в метке, к которой мы не обращаемся, пока.

Код
Buffer [Length]= RCREG


это нужно более подробно описать, вот так чтоли:

Код
ReadModbus_Frame:  

  If RCSTA.1 = 1 Or RCSTA.2 = 1 Then    
        RCSTA.4 = 0
     EndIf  
   
If PIR1.5 = 1  Then
  While PIR1.5 = 1  

             Buffer[Length] = RCREG      
             Length = Length + 1    
            ' If i = 75 Then     
             '    i = 0         
            ' EndIf
             
         Wend   
    
   EndIf
   
NewFrame = 1

Context Restore'------------------------------------------------------------------------


это подпрограмма прерывания по USART. Если есть прерывание вызванное приёмником, то переходим в цикл, где читаем принятые данные и записываем их в массив.

Цитата (anatol)
Length будет равен минус 1?


Length - это переменная, в которой хранится количество байт, полученных от USART.
Не знаю почему, но когда принимаю 8 байт, то переменная на 1 больше, то есть 9.
Поэтому Вы и наблюдаете
Цитата (anatol)
For a = 0 To (Length-1)


Ща чуток поковырялся, поменял камень, прицепил LCD и обнаружил причину этого глюка.

Код
If NewFrame = 1 Then
    
    
      [b]DelayMS 10[/b]  
      
      x2=Length
      Length = Length - 2
      Print At 2,1, Dec3 x2," . ", Dec3 Length, "           "
      'DelayMS 10
  GoSub    MB_CRC_RTU  
  DelayMS 10
         Print At 1,1, Dec3 CRC16 [0]," . ", Dec3 CRC16 [1], "           "
      Length=0
      NewFrame = 0    
     EndIf  
GoTo MAIN_SOFT

Я выделил delayms 10, потому, что при этой записи x2 = 8 ; Length = 6.
Если убрать delayms 10, или сделать меньше, то x2 = 1; Length = 0.
Как будто не успевает произвести вычисления. wacko бред конечно говорю, но по-другому мозга не хватает. Могу снять видел и показать.

Добавлено (17.04.2013, 14:41)
---------------------------------------------
Отправляю по-прежнему 001.003.000.012.000.001.068.009, то есть должен x2 = 8, а Length = 6

anatol Дата: Ср, 17.04.2013, 15:13  |                                                                                                                Сообщение # 50
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

Все что хотите показать в качестве пояснения должно быть , как сказать?,  заапострофено,  т.е. помечено знаком "   '    ".
Это знак действует до конца строки, а не на группу строк.
Дальше 1) какое значение переменная Length имела перед этим выражением
Buffer [Length]= RCREG,     где  RCREG = "железный" приемный регистр контроллера
Length = Length + 1
2) Вы присвоили ячейке буфера  Length = Length + 1 значение № на единицу больше для приема следующего байта. Но присвоили вперед, а байты для приема уже закончились. Вот значение на 1 и больше.

Сообщение отредактировал anatol - Ср, 17.04.2013, 15:17
MiXaS Дата: Ср, 17.04.2013, 15:25  |                                                                                                                Сообщение # 51
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

Цитата (anatol)
Все что хотите показать в качестве пояснения должно быть , как сказать?,  заапострофено,  т.е. помечено знаком "   '    ".


Не понял! это к чему? Двойные ковычки - это вывод на дисплей пустого места. Если Вы имеете введу ' DelayMs 10 , то это я так замораживаю, то есть убираю из кода. Но только одну строку.

Цитата (anatol)
Это знак действует до конца строки, а не на группу строк.

Если быть откровенным я не знаю как в Protone группу строк заморозить.

Цитата (anatol)
Дальше 1) какое значение переменная Length имела перед этим выражением Buffer [Length]= RCREG Length = Length + 1


Length = 0 и каждый раз обнуляется, после того, как выполнены все необходимые действия.

Если послать 001.003.000.012.000.001.068.009, то она равна 8

Цитата (anatol)
2) Вы присвоили ячейке буфера  Length = Length + 1 значение № на единицу больше для приема следующего байта. Но присвоили вперед, а байты для приема уже закончились. Вот значение на 1 и больше.


согласен -болван!

Это немного не соль. так как незначительно изменит результат.
anatol Дата: Ср, 17.04.2013, 15:44  |                                                                                                                Сообщение # 52
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

Цитата (MiXaS)
ТО есть что прилетело, то и улетело обратно.Далее нам нужно отбросить CRC письма и посчитать свой CRC.

Код
MAIN_SOFT:
If NewFrame = 1 Then ' флаг о новом фрейме

[b][color=#ff0000]Length = Length-2[/color][/b] ' последние 2 байта содержат CRC, которое находится в посылке (массиве)
GoSub MB_CRC_RTU ' отправляюсь в метку для расчета

HRSOUT CRC16 [1], CRC16 [2] ' отправить обратно значение посчитанного     
CRCLength=0 ' сбросить длину фрейма

NewFrame = 0 ' сбросить флаг нового фрейма
EndIf

GoTo MAIN_SOFT

В выделенном мной Length начальное значение наверняка на единицу больше. см. выше

Сообщение отредактировал anatol - Ср, 17.04.2013, 15:47
MiXaS Дата: Ср, 17.04.2013, 15:52  |                                                                                                                Сообщение # 53
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

точно не знаю, ща проверю
anatol Дата: Ср, 17.04.2013, 15:52  |                                                                                                                Сообщение # 54
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

А задержки на передачу для асихронного порта грубо количество байт *9/скорость и удвоить (на всяк случай). 9*9/9600= 8,5 мСек. Удвоим = прим.20 мСек
MiXaS Дата: Ср, 17.04.2013, 16:38  |                                                                                                                Сообщение # 55
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

Это опять зависит от delayms. Если она есть, то Length = 8, а x2 = 6, если нету delayms, то может быть от 1 до 255, прям рандом какой-то.

Добавлено (17.04.2013, 16:02)
---------------------------------------------

Цитата (anatol)
*9/скорость и удвоить (на всяк случай). 9*9/9600= 8,5 мСек. Удвоим = прим.20 мСек


Я извиняюсь, конечно , а разве не 11 бит?? 1 старт, 8 данных, 1 стоп, и 1 четности.

Немного непонял, как изменить задержку? Точнее где?

Добавлено (17.04.2013, 16:02)
---------------------------------------------
Вы хотите сказать, что USART не успевает принять данные??

Добавлено (17.04.2013, 16:04)
---------------------------------------------
Снял видео быстро, сейчас надо переконвертировать, а то youtube ругается.

Добавлено (17.04.2013, 16:38)
---------------------------------------------


С чем это может быть связанно???
Спасибо!

anatol Дата: Ср, 17.04.2013, 16:38  |                                                                                                                Сообщение # 56
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

Цитата (MiXaS)
Я извиняюсь, конечно , а разве не 11 бит?? 1 старт, 8 данных, 1 стоп, и 1 четности.
Я тоже с 9 маху дал, держал в уме 9 байт данных. 8 данных может и 7 быть . и старт по длине отличается. И время для вхождения в  связь надобно. Поэтому и 2 коэфф. причем по минимуму.
Вот здесь 232 расписан на русском  http://www.microchip.ru/files/d-sheets-rus/pic16_18.pdf
MiXaS Дата: Ср, 17.04.2013, 16:42  |                                                                                                                Сообщение # 57
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

Прошу прощения за качество. Youtube ухудшил качество cry

Добавлено (17.04.2013, 16:42)
---------------------------------------------
anatol,  спасибо! Сейчас буду грызть

anatol Дата: Ср, 17.04.2013, 16:49  |                                                                                                                Сообщение # 58
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

Интересный вы мужик. Проц используете 877 или 887, программы рисуем для 628. И кварц в памяти. Вопрос вам. Если две частоты немного разные, например на полпроцента, стартуют с одинаковой фазой то через сколько они встретятся снова с той же фазой. Это к тому что вы отправив 1 байт вновь служебно синхронизируетесь (задержка) потом второй байт и т.д.
MiXaS Дата: Ср, 17.04.2013, 17:00  |                                                                                                                Сообщение # 59
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 613
Репутация: 26   ±
Замечания:   ±
На сайте с 02.10.2010

Статус: Offline

Я же написал в 49 посту, что меняю камень и ставлю lcd. Отсюда и код меняется немного.
Цитата (anatol)
Это к тому что вы отправив 1 байт вновь служебно синхронизируетесь (задержка) потом второй байт и т.д.
это понятно.
Но у меня кварц соответствует описанному в листинге.
Прикрепления: CRC16.bas(9Kb)
anatol Дата: Ср, 17.04.2013, 17:56  |                                                                                                                Сообщение # 60
Группа: Проверенные
Ранг:  Разобрался
Сообщений: 535
Репутация: 13   ±
Замечания:   ±
На сайте с 10.02.2010

Статус: Offline

Вы наверно Михаил.  Кварц штука серьезная. Как и скорости передачи-приема.
необходимо соблюсти условия 1. Настроить порт компьютера на скорость , разрядность паритет такой же как и контроллера.
С целью недопущения ошибок кварц выбирается из http://www.microchip.ru/files/d-sheets-rus/pic16_18.pdf  Часть 18.3 Генератор частоты обмена..таблица 18-1. Только задаешь скорость и получаешь частоту кварца с нулевыми ошибками. Кстати пределы изменения скорости имеют место быть  максимальные коэффициэнты деления кварца  16384 или 256 в зависимости от режима USART.
Далее в прерывании обычно фиксируется факт прерывания и запрет прерываний, а вычисления производятся в подпрограмме и, потом, разрешение прерываний
Возможны и варианты.

Сообщение отредактировал anatol - Ср, 17.04.2013, 17:59
Форум Picbasic.ru » Программирование МК » Proton PicBasic » Помогите разобраться новичку (как правильно?)
Страница 4 из 11«1234561011»
Поиск: