Возникла такая проблема. Необходимо организовать асинхронную передачу (а в дальнейшем и прием) с параметрами 9600-8-N-2 на 16-м ПИКе. Т.к. "железно" поддерживается только 1 стоп-бит, вычитал в сети, что для передачи 2-го стоп-бита достаточно сделать задержку длительностью в 1 бит (около 104 мкс для 9600) перед отправкой следующего байта. Но как бы я с этим ни извращался, куда бы ее не вставлял, в виртуальном терминале Протеуса выводится мусор в виде одного единственного байта F8. Когда переключаю терминал на 1 стоп-бит, последовательность из необходимых 13 байтов выводится нормально.
Кусок кода с отправкой таков (прерывание не используется): Спойлерsend bsf RCSTA,SPEN ; Включаю порт bsf STATUS,RP0 bsf TXSTA,TXEN ; Разрешаю передачу bcf STATUS,RP0 movlw 1-й байт ; Отправка байтов call tx movlw 2-й байт call tx movlw 3-й байт call tx ...... movlw 13-й байт call tx bsf STATUS,RP0 bcf TXSTA,TXEN ; Отключаю передатчик bcf STATUS,RP0 clrf command return
tx btfss PIR1,TXIF ; Ожидаем опустошения goto $-1 ; буфера перед movwf TXREG ; отправкой в его регистр байта. return
Пытался играть с длительностью задержки, даже делал ее 2 раза для верности - всё бестолку. Вставлял ее перед movwf TXREG, делал отдельную проверку по биту TRMT (1=TSR empty, 0=TSR full), но он почему-то никогда не выходит в 1. Как-то раз даже извратился: отключил USART, настроил порт ТХ на выход (для USART`a он и RX должны быть настроены на вход) и выставил на нем 1 на нужный период, но и это не помогло.
Что посоветуете сделать для передачи 2-го стоп-бита?
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Хочу добавить свежие наблюдения, которые могут помочь.
Решил пока обойтись передачей одного байта и контролировать его правильное отображение в окне терминала. Вывожу байт 0х33 (00110011), т.к. он должен на анализаторе показать отчетливую картину из-за своей последовательности 0 и 1, и кроме того это ASCII символ числа "3". В результате на терминал выводится одиночный символ кавычек ", его ASCII код 0х22. При это анализатор показывает на порту такую картинку:
На ней отчетливо виден стартовый бит 103 мкс и передача байта, начиная с 0 бита. Но тогда почему терминал воспринимает 0х33 как 0х22?
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Последний раз редактировалось AlekseyEnergo Вт мар 04, 2014 12:29:15, всего редактировалось 1 раз.
Какой именно МК используеш. Если МК с модулем на борту (о чём говорит код), то зачем заморачиваешся с задержками битов и прочей лабудой. Настрой модуль на передачу загрузи в него что надо и передай . Всё. ДШ в помощь.
Открыта удобная площадка с выгодными ценами, поставляющая весь ассортимент продукции, производимой компанией MEAN WELL – от завоевавших популярность и известных на рынке изделий до новинок. MEAN WELL.Market предоставляет гарантийную и сервисную поддержку, удобный подбор продукции, оперативную доставку по России.
На сайте интернет-магазина посетители смогут найти обзоры, интересные статьи о применении, максимальный объем технических сведений.
Продукция MOSO предназначена в основном для индустриальных приложений, использует инновационные решения на основе более 200 собственных патентов для силовой электроники и соответствует международным стандартам. LED-драйверы MOSO применяются в системах наружного освещения разных отраслей, включая промышленность, сельское хозяйство, транспорт и железную дорогу. В ряде серий реализована возможность дистанционного контроля и программирования работы по заданному сценарию. Разберем решения MOSO
подробнее>>
Аlex
Заголовок сообщения: Re: USART на PIC16
Добавлено: Сб мар 01, 2014 23:04:30
Модератор
Карма: 90
Рейтинг сообщений: 1337
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4558 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Настройте модуль на 9-ти битный режим и передавайте девятым битом единичку. И будет Вам ещё один дополнительный бит, с точным временем, без всяких задержек.
Настройте модуль на 9-ти битный режим и передавайте девятым битом единичку. И будет Вам ещё один дополнительный бит, с точным временем, без всяких задержек.
Ок, спасибо! Сейчас попробую.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Сделал посредством 9-битной передачи. Судя по анализатору в Протеусе, два стопа теперь передаются, но его терминал по-прежнему выдает ерунду. Буду проверять на железе, т.к. Протеус явно халтурит. Но при этом в режиме 8-1 он все отображает правильно.
Спасибо за помощь!
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Последний раз редактировалось AlekseyEnergo Вт мар 04, 2014 12:29:44, всего редактировалось 1 раз.
Требуется получить по USART один за другим 8 байт, разместив их соответственно по регистрам с dd0 по dd7. Я это сделал кривым методом, он работает, но хочется утонченности компактности кода. Не подскажете алгоритм на АСМе?
Сейчас это делается запуском счетчика с приходом 1-го байта, наращивания его с приходом каждого нового байта, сравнивания его значения с 0-7 и размещением в соответствующие регистры. Чувствую, что должен быть иной, универсальный и компактный метод, основанный на косвенной адресации, но как это сделать - не знаю. Подсобите, пожалуйста Почти подобрался к финалу, забил память так, что осталось всего 15 слов свободных, хочется немного освободить места, оптимизировав программу. Тут, кстати, у меня тоже вопрос есть, но это потом.
ПИК тот же, 628-й.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Спасибо! Дома попробую после некоторой модификации. А я никак не мог понять логику, как эти 2 регистра связаны между собой и как их привязать к конкретному регистру ))
Добавлено 19.03.2014:
Все получилось! Код сократился аж на 60 слов. Еще раз большое спасибо!
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Косвенная адресация - великая сила! Освоить её надо обязательно. Только учтите, что, если вы ею пользуетесь и в программе, и в обработчике прерываний, то, при входе в обработчик, регистр-указатель необходимо сохранять, а при выходе, восстанавливать (аналогично регистрам статуса и аккумулятора).
Да, об этом я знаю. Прерывания используются, но если я, вернее программа, туда попаду, значит произошел таймаут и дальнейшая судьба этого указателя уже неважна. Поэтому не стал его сохранять.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
LIST P=PIC16F1825 INCLUDE <P16F1825.INC> errorlevel -305 errorlevel -302
;ПОДПРОГРАММЫ: ;EEPROM_WR - ЗАПИСЬ В EEPROM ПО АДРЕСУ В W И ДАННЫМИ В TEMP ;EEPROM_RD - ЧТЕНИЕ ИЗ EEPROM ПО АДРЕСУ В W ;DIR_TX - ПЕРЕВОД ПРИЕМОПЕРЕДАТЧИКА В РЕЖИМ "ПЕРЕДАЧА" ;DIR_RX - ПЕРЕВОД ПРИЕМОПЕРЕДАТЧИКА В РЕЖИМ "ПРИЕМ" ;CRC8_TX - ВЫЧИСЛЕНИЕ CRC8 ПЕРЕДАВАЕМОГО СООБЩЕНИЯ. ДОБАВЛЕНИЕ CRC8 В КОНЕЦ СООБЩЕНИЯ ;CRC8_RX - ВЫЧИСЛЕНИЕ CRC8 ПРИНЯТОГО СООБЩЕНИЯ. ЕСЛИ ОШИБКА, ТО УСТАНАВЛИВЕТСЯ FLAGS,0, ИНАЧЕ НИЧЕГО НЕ ПРОИСХОДИТ.
;ОПИСАНИЕ: ;TRM6 НАСТРОЕН НА ПЕРИОД В 0.77 МС, ДЛЯ ДЕТЕКТИРОВАНИЯ КОНЦА СООБЩЕНИЯ И ОЖИДАНИЯ ПРИЕМА СЛЕДУЮЩЕГО ;TMR3 НАСТРОЕН НА ПЕРИОД В 2 МС, ДЛЯ ПАУЗЫ ОТВЕТА
ADRES1 EQU 0X70 ;АДРЕС ПРИБОРА 1. ЧТЕНИЕ ИЗ EEPROM I2C_TEMP1 EQU 0X71 ;TEMP РЕГИСТР I2C KEY EQU 0X72 ;КЛЮЧ ПРИ ПЕРЕХОДЕ НА ШИФРАЦИЮ ПРИБОРА 1 RAND EQU 0X73 ;ЧИСЛО ШИФРАЦИИ ПРИБОРА 1 INC_N EQU 0X74 ;ИНКРЕМЕНТИРУЮЩЕЕСЯ ЧИСЛО КОМАНДЫ C_02
Рабочая программа (кусок) работы по RS485. Все действа (прием и передача) происходят в прерываниях. Можно отправить или получить сообщение до 80 байт. В основной программе я проверяю только регистры-флаги. Передача работает так: когда надо ответить (передать), готовиться ответ (пишется в буфер) и запускается таймер паузы ответа, по прерыванию которого запускается передача. При приеме, детектируется конец сообщения путем прерывания от таймера. То есть если в период таймера был принят байт, таймер сбрасывается. Если не был принят, то таймер генерирует по переполнению прерывание, которое и указывает на конец посылки. Ещё у меня проверка CRC8 табличным методом, и проверка на нули. Там у меня ещё интерфейс I2C тоже по прерываниям, может чего лишнего и оставил. По поводу сохранения контекста, в PIC16F1825 расширенное ядро, и процессорные регистры сами сохраняются и восстанавливаются.
При переходе на вектор прерываний 7-й бит INTCON (GIE) автоматически опускается, а по команде RETFIE поднимается. Так что вручную поднимать и опускать его не нужно.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Последний раз редактировалось Zhuk72 Пн мар 24, 2014 14:51:27, всего редактировалось 1 раз.
Полином X7+X3+1 или 0x44. Делаем табличку в экселе от "0" до "n", прописываем формулу для каждого значения (одна и та же) и получаем табличные данные. Это устройство эмулирует прибор в охранной сигнализации, по этому, в моем случае, это не совсем CRC8. Она очень похожа на Dallas-овскую, но отличается 5 значениями (видимо специально изменили). Если лень в экселе, можно посчитать тут: http://ghsi.de/CRC/ Вписываем свой полином "1000100" и последовательно заполняем таблицу. Удобнее работать с байтом, по этому значения от 0 до 255 (0x00 ... 0xFF). То есть на выходе таблица с 255 значениями. У меня это выглядит так:
Код:
CRC8_RX CLRF TEMP ;ПОДПРОГРАММА ВЫЧИСЛЕНИЯ CRC8 ПРИНЯТОГО СООБЩЕНИЯ MOVLW 0X20 ;курсов FSR на буфер принятого сообщения MOVWF FSR0H MOVLW 0X00 MOVWF FSR0L ;ВСТАЛИ НА ПЕРВЫЙ БАЙТ BANKSEL 0X21 MOVFW 0X21 ;в посылке указывается число байтов MOVWF TEMP1 ;СКОЛЬКО НАДО БАЙТОВ ВЫЧИСЛИТЬ INCF TEMP1 CRC2 MOVFW INDF0 ;ПРОЧИТАЛИ ЗНАЧЕНИЕ XORWF TEMP,1 ;ПРОКСОРИЛИ С ПРЕДЪИДЩИМ MOVFW TEMP CALL CRC8_TABLE ;ВЗЯЛИ ИЗ ТАБЛИЦЫ MOVWF TEMP ;ЗАПИСАЛИ ВО ВРЕМЕННЫЙ INCF FSR0L ;СЛЕДУЮЩИЙ АДРЕС DECFSZ TEMP1 ;УМЕНЬШИЛИ ЧИСЛО БАЙТОВ GOTO CRC2 MOVLW 0X00 ADDWF TEMP BTFSC STATUS,2 ;РЕЗУЛЬТАТ РАВЕН НУЛЮ? GOTO CRC3 ;ДА, ВСЁ ВЕРНО BCF FLAG485,1 ;НЕТ, ОШИКА ПРИЕМА. RETURN CRC3 BSF FLAG485,1 RETURN
, где CRC8_table - это таблица с заранее вычисленными значениями CRC, в моем случае из дизасма ПО, так как по далассовской были сбои. Если надо получить значение CRC, то последнее XOR делать не надо, то есть в моем случае на 1 байт меньше. То есть у меня вычисленное значение XORиться с принятым, и если ноль, то корректно. Можно вообще в ручную вычислять, со сдвигами n-битного числа (у меня сообщения до 80 байт и займет ~700 проходов по 50-100 слов) и проверкой старшего на 1 или 0 в соответствии с полиномом , и всё это в цикле на N-бит. Учитывая что в контроллере уживаются I2C и RS485 это не приемлемо по времени. По этому табличный, 300 слов в памяти не такая уж и дорогая плата.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения