Stolbov 0 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба 7 минут назад, aaarrr сказал: 1. Реализация кольцевого буфера корявая. Но гораздо менее корявая, чем остальной код. Буду работать дальше. 7 минут назад, aaarrr сказал: 2. К чему весь этот ужас с switch() вместо передачи в цикле из массива? Потому что в когда я передавал данные в цикле из массива, на выходе я получал один-единственный байт данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба 12 minutes ago, Stolbov said: Потому что в когда я передавал данные в цикле из массива, на выходе я получал один-единственный байт данных. Выше уже указали причину. Не может это не работать: const uint8_t databuffer[8] = {0x01,0x04,0x00,0x06,0x00,0x02,0x91,0xCA}; int i; for(i = 0; i < sizeof(databuffer); i++) uart_0_send(databuffer[i]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 23 октября, 2019 Опубликовано 23 октября, 2019 (изменено) · Жалоба 1 hour ago, Stolbov said: #define BUFFER_SIZE 18 //Максимальный размер кольцевого буфера (на две принятые посылки) #define BUFFER_MASK (BUFFER_SIZE - 1) //Маска обнуления В том месте, где вы брали кольцевой буфер, не было написано большими буквами, что его размер обязательно должен быть кратен степени двойки? В противном случае "магия" с маской работает совсем не так, как должна. И вот это безобразие: while (1) { if(get_data() == 0) //Если функция вернула 0, значит, в массиве нет новых данных { asm("nop"); //И тогда мы ничего не делаем } else if(get_data() == 1) //Если функция вернула 1, значит, какие-то данные всё же получены { read_byte_from_ring(local_buffer,index_number()); //Читаем полученные от вольтметра данные в local_buffer } else { break; } uart_1_send(local_buffer[0]); //Отсылаем данные из local_buffer на ПК } Должно быть как-то так: while (1) { if(get_data() == 1) //Если функция вернула 1, значит, какие-то данные всё же получены { char local; read_byte_from_ring(&local, 1); //Читаем полученные от вольтметра данные в local_buffer uart_1_send(local); //Отсылаем данные из local_buffer на ПК } } Изменено 23 октября, 2019 пользователем esaulenka чёртов редактор... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба Из void call_voltage() //Отправка сообщения на вольтметр уберите описание global_state - у вас получилась локальная переменная, которая закрыла глобальную. И ваш ужастный switch дальше перого case никогда не уходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба 2 часа назад, aaarrr сказал: Не может это не работать: Вы оказались правы, это не может не работать. Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5); в main() до двух 2000ms, и всё заработало. От ужасного и чудовищного switch'а избавился. 1 час назад, esaulenka сказал: В том месте, где вы брали кольцевой буфер, не было написано большими буквами, что его размер обязательно должен быть кратен степени двойки? Было написано, и в том месте на этом было заострено внимание. Почему я напортачил на ровном месте - ума не приложу. Сейчас разбираюсь, почему не происходит отсылка данных из условия if(get_data() == 1) (я имею ввиду приведённый Вами кусочек кода). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба 2 hours ago, Stolbov said: . . . . Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5); в main() до двух 2000ms, и всё заработало. . . . Это "симптоматическое" лечение. Тем более в таких "особо крупных" размерах (2 сек). Возможно Вам имеет смысл использовать трансивер RS485 с автоопределением прием/передача, на первом этапе. MAX13487EESA-T_C18347.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 23 октября, 2019 Опубликовано 23 октября, 2019 · Жалоба 3 hours ago, Stolbov said: Я всего лишь увеличил паузу после DDRE |= (1<<PORTE5); Какое-то странное лечение. По-хорошему, никаких пауз не надо. Если паузу убрать, переходник в компьютер отправленные байты видит? Вольтметр как запитан? Может, он просто запускается эти 1-2 секунды, а вы ему постоянно питание дёргаете? 3 hours ago, Stolbov said: Сейчас разбираюсь, почему не происходит отсылка данных из условия На первый взгляд, правильно всё написано... Предложения по отладке: - в прерывание на приём байта добавьте пересылку его в соседний порт. Скорость этого UART1 лучше поставить побольше (например, 115200), чтоб не мешал своими задержками. - также можно через некоторый промежуток (например, через секунду) после обмена с вольтметром отправить в этот UART1 всю интересующую информацию - в первую очередь, IndexStart / IndexEnd. - также ооочень рекомендую отладчик. Называется AVR JTAG ICE. Оригинал стоит каких-то неразумных, на мой взгляд, денег, но китайские клоны продаются за копейки (порядка 200 рублей). Правда, как работают клоны, я не знаю. "Пошагать" по программе у вас не получится (т.к. задействован вольтметр, а он ждать не будет), но посмотреть в любой момент значения переменных, да и за несколько секунд обновить программу - это очень упрощает работу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stolbov 0 7 ноября, 2019 Опубликовано 7 ноября, 2019 (изменено) · Жалоба Перед тем, как закрыть тему, я хотел бы подвести некоторые итоги. Нет, свою задачу я так и не решил. Пару раз я переписывал свой код, и в прошлую пятницу добился его работоспособности (AVR'ка опрашивала вольтметр раз в пару-секунд и стабильно получала ответ). Не было ни каких сомнительных задержек, и прочих "костылей". В начале этой недели всё внезапно прекратило работать. Ничего не менялось. Просто включил свою отладочную плату во вторник утром, а в мониторе, который я подключил параллельно вольтметру, либо ничего нет, либо передаётся максимум один байт сообщения. Почему это происходит, и как мне найти решение - я не знаю. На одном из форумов прочёл, что при построении таких систем микроконтроллер следует тактировать от внешнего кварца, но в своём случае я не заметил никаких улучшений. Попробую использовать другие микросхемы-аналоги MAX485 (SN75176AP, к примеру). Может быть поможет. В любом случае, всем спасибо за участие. Как только я доберусь до правильного решения, я обязательно его здесь опубликую. Изменено 7 ноября, 2019 пользователем Stolbov Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 10 ноября, 2019 Опубликовано 10 ноября, 2019 · Жалоба On 11/7/2019 at 11:11 AM, Stolbov said: Перед тем, как закрыть тему, ... AVR очень неудачный выбор (на данное время, за 10 лет назад разговора нет), по причине отсутствия нормальных (доступных и недорогих) средств аппаратной отладки. Возьмите надежный-удобный компилятор (для меня это IAR или Keil) и аппаратный отладчик-программатор. Получите нормальную среду для разработки-отладки и сэкономите массу времени изучив новый нормальный инструмент для работы и процессор (например ARM, к томуже ресурсы даже у "младших" ARM не сравнить с AVR). Тратьте время на изучение того, что перспективно и удобно, а не поиск/психоанализ "черного ящика" (это "аналитическая" отладка софта и программы без JTAG). Не в обиду фанатов AVR, IMHO. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться