AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
03.07.2019, 22:04
|
|
Прохожий
Регистрация: 03.07.2019
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
ATtiny441 и UART. Не могу разобраться
Коллеги, помогите!
Появилось у меня хобби - начал с Ардуино UNO и теперь дорос до контроллера ATtiny441 + Atmel Studio 7. Играюсь с домашне-дачной автоматизацией ...
Задача очень простая: удаленно посылая телеграммы по RS-485 (протокол ModBus RTU) управлять с компьютера периферией и отвечать компьютеру о своем состоянии. Начал писать код:
Код:
PHP код:
|
#define F_CPU 1000000UL #include ‹avr/io.h› #include ‹avr/interrupt.h› #include ‹util/delay.h› #define BUFFER_SIZE 128 #define StartTransmit_SET_OUTPUT DDRA |= (1 ‹‹ 0) #define StartTransmit_LOW PORTA |= (1 ‹‹ 0) #define StartTransmit_HIGH PORTA &= ~(1 ‹‹ 0) #define LED_SET_OUTPUT DDRA |= (1 ‹‹ 4) #define LED_LOW PORTA |= (1 ‹‹ 4) #define LED_HIGH PORTA &= ~(1 ‹‹ 4) volatile unsigned char slaveID = 50; unsigned char frame[BUFFER_SIZE]; unsigned char funktion=1; bool broadcastFlag=0; void USART_Init() { UBRR0H = 0; UBRR0L = 6; UCSR0B = (1‹‹RXEN0)|(1‹‹TXEN0)|(1‹‹RXCIE0); UCSR0C = (1‹‹USBS0)|(3‹‹UCSZ00); } unsigned int calculateCRC(uint8_t bufferSize) { unsigned int temp, temp2, flag; temp = 0xFFFF; for (unsigned char i = 0; i ‹ bufferSize; i++) { temp = temp ^ frame[i]; for (unsigned char j = 1; j ‹= 8; j++) { flag = temp & 0x0001; temp ››= 1; if (flag) temp ^= 0xA001; } } temp2 = temp ›› 8; temp = (temp ‹‹ 8) | temp2; temp &= 0xFFFF; return temp; } void USART_Transmit( unsigned char data ) { StartTransmit_LOW; _delay_ms(5); while ( !( UCSR0A & (1‹‹UDRE0)) ); UDR0 = data; _delay_ms(5); StartTransmit_HIGH; _delay_ms(5); } void USART_Transmit_String() { int i=0; unsigned char c = frame[0]; while(c != '\0') { c = frame[i]; if(c!='\0') {USART_Transmit(c);} i++; } } void exceptionResponse(unsigned char exception) { if (!broadcastFlag) { frame[0] = slaveID; frame[1] = (funktion | 0x80); frame[2] = exception; unsigned int crc16 = calculateCRC(3); frame[3] = crc16 ›› 8; frame[4] = crc16 & 0xFF; USART_Transmit_String(); } } ISR (USART0_RX_vect) { while ( !(UCSR0A & (1‹‹RXC0)) ); slaveID = UDR0; } int main(void) { USART_Init(); StartTransmit_SET_OUTPUT; LED_SET_OUTPUT; LED_LOW; sei(); while(1) { exceptionResponse(2); _delay_ms(5000); } }
|
и столкнулся со следующей хренью: вбиваю в Terminal Window (встроенный терминал в Atmel Studio 7) число 33 - по указанному выше алгоритму если в буфере что то появилось, то переменная slaveID становится этим. Но она этим становится в хаотичном порядке: может так: 33 81 02 60 5e - и это правильно, она 33, а может так: b3 81 02 61 b6 - это когда первый бит у тройки заменен на 1. Причем непонятно с чем это связано. Вроде вбиваю в поле Send терминала 33, все честно, но результат на выходе ИЛИ-ИЛИ. Нет стабильности. Например та же хрень при вводе 54: 5 раз d4 81 02 d0 69, три раза 54 81 02 d1 81 Для приема в терминал использую китайский переходник с UART на RS-485 и переходник - RS-485 - USB. Если есть у кого какие мысли - помогите, пожалуйста, разобраться.
Спасибо!
Последний раз редактировалось Deniska407; 03.07.2019 в 22:12.
|
|
|
|
03.07.2019, 22:09
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,050
Сказал спасибо: 3,041
Сказали Спасибо 3,210 раз(а) в 2,180 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Для кода используй тэг php или прикладывай исходник файлом.
__________________
Экзорцист 40-го уровня.
|
|
|
Сказали "Спасибо" ForcePoint
|
|
|
03.07.2019, 23:47
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.01.2008
Сообщений: 1,143
Сказал спасибо: 379
Сказали Спасибо 430 раз(а) в 274 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
В программе ничего подозрительного не увидел.
На всякий случай проверьте напряжение на PA2 (вдруг там, когда нету передачи высокий уровень)
Попробуйте подключать МК к компу через переходник USB - UART (или RS232 - UART).
Очень вероятно что глюки в передаче по RS485.
Термальные резисторы стоят?
|
|
|
|
04.07.2019, 00:01
|
|
Прохожий
Регистрация: 03.07.2019
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Сообщение от E97
|
В программе ничего подозрительного не увидел.
На всякий случай проверьте напряжение на PA2 (вдруг там, когда нету передачи высокий уровень)
Попробуйте подключать МК к компу через переходник USB - UART (или RS232 - UART).
Очень вероятно что глюки в передаче по RS485.
Термальные резисторы стоят?
|
PA2 - завтра проверю обязательно!
RS-232 поищу, где то был. Отпишу.
Нет, терминальных резисторов нет. Линия связи не более 30 см.
|
|
|
|
04.07.2019, 01:15
|
|
Заблокирован
Регистрация: 17.07.2010
Адрес: мурмурляндия
Сообщений: 10,715
Сказал спасибо: 189
Сказали Спасибо 3,199 раз(а) в 2,074 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
помехи на лини связи.
для начала земли обоих плат соедини надежно.
небось питаешь от импульсных блоков питания - вот они эту срань на шину и наводят.
любая шина данных защищается конрольными сумами всякими чтоб гавно это отсечь.
но гавна больше 5-10% не должно быть иначе все рухнет.
вообще осцилографом надо смотреть - так все очень наглядно становится.
|
|
|
|
04.07.2019, 08:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.06.2006
Адрес: Украина, Запорожье
Сообщений: 8,003
Сказал спасибо: 0
Сказали Спасибо 4,946 раз(а) в 2,374 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
|
|
|
|
04.07.2019, 09:18
|
|
Прохожий
Регистрация: 09.05.2004
Адрес: Санкт-Петербург
Сообщений: 7
Сказал спасибо: 2
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Сообщение от Deniska407
|
вбиваю в Terminal Window (встроенный терминал в Atmel Studio 7) число 33 - по указанному выше алгоритму если в буфере что то появилось, то переменная slaveID становится этим. Но она этим становится в хаотичном порядке: может так: 33 81 02 60 5e - и это правильно, она 33, а может так: b3 81 02 61 b6 - это когда первый бит у тройки заменен на 1. Причем непонятно с чем это связано. Вроде вбиваю в поле Send терминала 33, все честно, но результат на выходе ИЛИ-ИЛИ. Нет стабильности. Например та же хрень при вводе 54: 5 раз d4 81 02 d0 69, три раза 54 81 02 d1 81 Для приема в терминал использую китайский переходник с UART на RS-485 и переходник - RS-485 - USB.
|
Возможная причина - несоответствие настроек портов. Нужно смотреть лог. анализатором вроде saleae logic или клоном, сразу станет все ясно. Переходники лучше использовать на ft232 чипе, с ch340 тоже могут быть проблемы на уровне драйверов...
|
|
|
|
04.07.2019, 10:43
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,105
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Искажается старший бит, который передаётся последним. Установки количества стоп-битов одинаковые?
Saleae анализатор (клон за $12 c али) сильно выручит.
|
|
|
|
04.07.2019, 12:04
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,050
Сказал спасибо: 3,041
Сказали Спасибо 3,210 раз(а) в 2,180 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Не вижу помещения символа завершения (0x00, который ожидается в "USART_Transmit_String") в буфер передачи:
Цитата:
|
PHP код:
|
frame[4] = crc16 & 0xFF; frame[5] = 0x00; // Примерно - вот так добавить. USART_Transmit_String();
|
|
Ну и по мелочи...
1. В "ISR (USART0_RX_vect)" как-бы излишняя проверка готовности:
Цитата:
|
PHP код:
|
while ( !(UCSR0A & (1‹‹RXC0)) );
|
|
2. Непонятные "& 0xFFFF" кругом.
__________________
Экзорцист 40-го уровня.
Последний раз редактировалось ForcePoint; 04.07.2019 в 12:08.
|
|
|
|
04.07.2019, 13:10
|
|
Почётный гражданин KAZUS.RU
Регистрация: 15.11.2010
Сообщений: 2,379
Сказал спасибо: 338
Сказали Спасибо 328 раз(а) в 253 сообщении(ях)
|
Re: ATtiny441 и UART. Не могу разобраться
Уже говорил на другом форуме - не стабильная тактовая частота из-за отсутствия кварца. Начинать надо с этого. Затем цеплять ЛА на интерфейс или ослика и смотреть, что происходит физически.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:51.
|
|