- Вложения
-
- Проект с библиотеками.rar
- (46.31 КБ) 129 скачиваний
UART постоянно шлет мусор в TXD
Вот все файлы. Я сейчас не дома, а практически в походных условиях. Под рукой есть Дискавери первая, сейчас попробую на ней сваять приемо/передатчик и посмотрю на эхо.
Я не волшебник, я только лечусь
- Реклама
- Сообщения: 547
- Зарегистрирован: Вт фев 09, 2010 17:52:26
Вроде должен работать.
добавьте перевод строки
Попробуйте настроить порт.
Попробуйте скорость выставить 9600
(я так понял при включении сим сам посылает в порт информацию, попробуйте ее считать, выставляя разные скорости. Напишите новую прогу, читайте, то что шлет сим и выводите на экран )
добавьте перевод строки
Код: Выделить всё
void USART_END(void)
{
USART_TXD('\r');
USART_TXD('\n');
}
Попробуйте настроить порт.
Код: Выделить всё
DDRD = 0x02;
PORTD = 0x03;
(я так понял при включении сим сам посылает в порт информацию, попробуйте ее считать, выставляя разные скорости. Напишите новую прогу, читайте, то что шлет сим и выводите на экран )
что мне в тексте понравилось, то это форматирование строк - ну хоть у одного есть...
Но анекдот про еврея в бане сразу вспомнился, конечно...Или трусы наденьте, или крестик снимите...
В смысле, если расширение файла cpp - как бы подразумевается с++ компилятор, у которого есть перегрузка функций.
Перегрузка подразумевает "перекручивание" имен функций, для того, чтобы не было 2 функций с одинаковыми именами( и разными параметрами внутри). У си этого нет - поэтому нужно указывать, что это сишный текст, обязательно, когда работаете с с++ компилятором
extern "C"
И обработка прерываний по приему байта удивила, конечно
ISR(USART_RX_vect) // По приходу данных в UDR
{
char temp = UDR;
if(!(temp == 0x0A || temp == 0x0D)) InBuffer(temp);
}
Но анекдот про еврея в бане сразу вспомнился, конечно...Или трусы наденьте, или крестик снимите...
В смысле, если расширение файла cpp - как бы подразумевается с++ компилятор, у которого есть перегрузка функций.
Перегрузка подразумевает "перекручивание" имен функций, для того, чтобы не было 2 функций с одинаковыми именами( и разными параметрами внутри). У си этого нет - поэтому нужно указывать, что это сишный текст, обязательно, когда работаете с с++ компилятором
extern "C"
И обработка прерываний по приему байта удивила, конечно
ISR(USART_RX_vect) // По приходу данных в UDR
{
char temp = UDR;
if(!(temp == 0x0A || temp == 0x0D)) InBuffer(temp);
}
А что удивительного в приёме байта? Выкидывают мусор и складываются в буфер. А переменная нужна для сохранения данных так как если сравнивать с UDR напрямую то в буфер запишется ноль. Уже напарывался. Или у Вас есть иное мнение? Готов принять Ваше предложение. Не откажусь.))) А вот на счёт extern C можно по подробнее. Меня в AS6 сильно удивило то что я не могу создать хедер с об'явленными функциями, а сами функции в С фйле. Или там есть какая настройка? А то очень не удобно.
Я не волшебник, я только лечусь
первая же ссылка в гуглях
1 - вы не обрабатываете исключения - пропуск стопового бита и переполнение внутреннего буфера
2 - символ перевода строки - команда фас для парсера строк - анализ, что там пришло. Отсутствует.
Что удивительного в приеме байта ?если до сих пор непонятно откуда растут корни, поясняю полностью.
издревле повелось, что компиляторы с "продвинутых" и общеупотребительных языков программирования (asm, c, c++ и др.) разделяют код между т.н. юнитами компиляции (модулями). Каждый модуль может быть скомпилирован отдельно от других, производя на свет файл *.obj формата (универсальный формат), которые потом с помощью линкера подшиваются в один конечный исполняемых файл *.exe.
Так уж повелось, что в целях унификации фирмы-производители компиляторов старались сохранить формат *.obj единым для всех языков (по возможности), что даёт хорошую возможность создавать программы на из юнитов на разных языках программирования. Например модуль на чистопородном ASM можно было сшить в программу на чистопородном C.
Обратная совместимость с этой концепцией ввела в язык C++ некие "странные" на первый взгляд вещи.
*.obj файл исторически устроен сравнительно просто: в нём есть изолированные блоки откомпилированного уже машинного кода и данных, которые сдобрены "метками" - мнемоническими обозначениями, указывающими куда-нибудь внутрь сего дела. Причем в *.obj файле принципиально неизместно чем именно является метка - адресом глобальной переменной, или ф-ии - даже для линкера это непринципиально.
Со старыми языками всё это работало без проблем - экспортные ф-ии и переменные получали совпадающую со своим программным именем метку в *.obj файле и дальше всё шло как по маслу.
А вот в C++ дядя Страуструп ввел такую фичу, как перегруженные ф-ии. Это такие звери, которые хотя и называются в программе одинаково, но имеют разный набор параметров, а следовательно разные тела, наполнение и содержание.
И вот чтобы эту концепцию протянуть через *.obj файлы без конфликта меток пришлось ввести т.н. name mangling. С помощью этого механизма имена переменных и ф-ий в *.obj файлах дополняются специальными длинными абреввиатурами, чтобы исключить конфликт имен конечных перегруженных ф-ий.
Проблема в том, что этот механизм срабатывает всегда и объявив void some(); ты в *.obj файле получить можешь имя для ф-ии вроде _some_v_f. Чтобы нормально спрягать код на C++ с C или ASM, где name mangling отсутствует, введено extern "C", которое отключает сей механизм у экспортируемых или импортируемых имен переменных/ф-ий. Логично, что extern "C" ф-ии не могут быть перегружены.
Так понятно? =)
1 - вы не обрабатываете исключения - пропуск стопового бита и переполнение внутреннего буфера
2 - символ перевода строки - команда фас для парсера строк - анализ, что там пришло. Отсутствует.
- Реклама
Ну с extern С я еще по колупаюсь. Самому интересно стало. Пропуск стопового бита? Если я не ошибаюсь, то МК сам этим занимается и если что не так то он выставит флаг и прерывание по окончанию приема данных не произойдет. Переполнение буфера маловероятно так как как только я передаю команду я знаю что сразу последует ответ. Длинна ответа всегда короче длинны буфера, а по приходу данных в буфер программа их оттуда извлекает и спокойно работает с ними. На счет обработки строк. Я четко знаю где лежит нужный мне байт или ряд из нескольких поэтому я не считаю нужным читать весь массив. Например при получении сообщения о приходе SMS меня интересует только последний байт который несет в себе номер SMS. А символов перевода строки модуль к сожалению присылает аж 3 штуки и поди разбери что где. Мне проще все повыкидывать и по OK все проверить. Ну как-то так. Если конечно я не прав то поправте, я не откажусь от дельных мыслей.))
Я не волшебник, я только лечусь
Ошибаешься.Если я не ошибаюсь, то МК сам этим занимается и если что не так то он выставит флаг и прерывание по окончанию приема данных не произойдет.
Пример обработки
https://github.com/jeremycole/avr/blob/ ... art/uart.c
Да столько кода всю память МК заб'ет
Короче это загруз мозга минимум на неделю. Лан буду вкуривать в это.
Все, разобрался. Сдох контроллер. Сегодня купил новый и все пошло как по маслу.
Все, разобрался. Сдох контроллер. Сегодня купил новый и все пошло как по маслу.
Я не волшебник, я только лечусь
- Сообщения: 47
- Зарегистрирован: Ср ноя 12, 2014 14:48:39
Кто нибудь объяснит, что это за конструкция такая?urry писал(а):Ошибаешься.Если я не ошибаюсь, то МК сам этим занимается и если что не так то он выставит флаг и прерывание по окончанию приема данных не произойдет.
Пример обработки
https://github.com/jeremycole/avr/blob/ ... art/uart.c
uart->tx.buffer = malloc(UART_TX_BUFFER_SIZE);
uart->rx.buffer = malloc(UART_RX_BUFFER_SIZE);
uart->tx.head = 0;
Еще там дан такой штук
uart_set_frame_format(uart,
uart->description->format_async
| uart->description->format_8n1);
Как такое вообще читать?
Разве то что в скобках так переносить можно?
И еще, можете мне помочь с моим постом. Там тоже затык с передачей и тоже срр
http://radiokot.ru/forum/viewtopic.php?f=57&t=109685
Мало данных. Какие параметры должна возвращать функция malloc(UART_TX_BUFFER_SIZE)? Явно как аргумент получает размер буфера передатчика. Возвращаемое значение судя по всему складируется в какой-то структуре. Это видно из обращения к члену структуры. Для понимания нужно хотя бы глянуть в тело функции malloc() и на структуру.
Я не волшебник, я только лечусь
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
malloc это стандартная функция динамического выделения нужного объема памяти, объявлена в alloc.h и stdlib.h, если не ошибаюсь. Принимает собственно объем, который нужно, возвращает адрес первого выделенного байта, либо NULL, если выделить не удалось (кстати, в этом куске ошибка не обрабатывается). Разумеется, эта функция работает дольше и занимает больше места, чем статической выделение памяти.
Обычно перенос строк делают для удобства чтения, когда аргументы не влезают в ширину экрана, чтобы не приходилось прокручивать влево-вправо. По аргументам можно предположить, что uart настраивается как асинхронный, 8n1. format_async и format_8n1 это случайно не константы?uart_set_frame_format(uart,
uart->description->format_async
| uart->description->format_8n1);
Как такое вообще читать?
Разве то что в скобках так переносить можно?
- Сообщения: 47
- Зарегистрирован: Ср ноя 12, 2014 14:48:39
спасибо. Теперь буду знать. Раньше не видел кода со стрелочками "->"
Возможно, я никогда с alloc.h и stdlib.h не работал. Если там описана функция то можно посмотреть как она работает.
Я не волшебник, я только лечусь


