Страница 1 из 2
Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 01:14:16
engee
Собственно занимаюсь микроконтроллерной техникой уже около года, начинал с нуля, но за год пускай не всему но многому уже научился и многое освоил, вот написал курсовую работу на тему сабжа+ собрал устройство. Идея родилась спонтанно, в этом семестре по учебе пришлось самому осваивать LabView и читая учебник, наткнулся на информацию, что программа может работать с внешними устройствами через rs232, ну а потом уже начал копать в интернете, наткнулся на идею соединить мк+датчик температуры+ПК, но решений готовых никто естественно не предоставлял, хотя бы как образец. Поэтому решил сам все сделать с нуля. Курсовую, кстати, защитил на отлично. Но проблема в том что преподаватели практически не задавали вопросы по микроконтроллерной технике, а я знаю что в курсовой может быть много недостатков. Хотя писал сам от начала до конца и каждое слово могу пояснить, рассказать и показать на практике, но все же что-то мог понять не правильно из руководств, даташитов и тд.
Хотелось бы чтобы знающие люди пролистали, посмотрели, и высказали свои замечания, предложения и тп. По коду(в LabView в основном, там у меня много трудностей возникло изза непонятного типа выходных данных с терминала Visa Read), ну и если увидите в курсовой откровенный маразм - высказывайте мне все как есть, не стесняйтесь. Я не претендую на звание гуру, пока еще всего лишь новичек, и хочется чтоб меня не только похвалили, но и поругали, потыкали носом в мои ошибки, спасибо!
Кстате другие новички, опираясь на мою курсовую, могут с легкостью разработать такое же устройство, я постарался все изложить подробнейшим способом(есть все схемы и исходники)
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 11:13:41
orinoko
Расписано всё, конечно, замечательно, но практическая реализация как то не очень. В защиту этого только то , что это курсовая, которую нужно просто сдать. А теперь по существу. Я не силён в Си, поэтому все замечания будут, исходя из программы на LV, которая была написана не совсем красиво.
1. вы передаёте по одному байту за раз, но при этом преобразовываете в Double. Зачем? Т.е. вы работаете только с целым значением температуры. Как то несолидно при том , что датчик выдаёт значение с дискретностью 1/16 градуса. Но если это делать, то нужно пересмотреть протокол обмена.
2. Вы формируете массив чисел Double, постоянно увеличивающийся, и, теоретически, ваша программа будет постоянно увеличивать занимаемую память, при этом вы не используете этот массив. ( А, нет, используете в конце...)
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 11:34:44
Леонид Иванович
Вообще, сопряжение микроконтроллера и ПК - это прежде всего протокол обмена. Я эту задачу решал так:
http://digit-el.com/files/open/wake/wake.html
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 11:42:49
orinoko
Далее...
3. При каждом проходе цикла весь массив данных (который у вас увеличивается каждый раз на один элемент), вы преобразовываете в таблицу но пользутесь результатом только при выходе из программы. Может всё таки вынести это преобразование за цикл, чтобы оно выполнялось 1 раз.
4. И нет обработки ошибок
5. Служебный терминал, который у вас типа показывает количество полученных байт, на самом деле показывает количество байт в буфере приёма, а получаетет вы всегда по 1 байту. А если в буфере больше 1 байта? И тогда будут приняты данные, которы были отосланы раньше, чем вы их приняли (т.е. принятые данные будут неактуальны на данный момент времени)
5а. А если в буфере ничего не будет?
6. Я думаю, что вам не нужен весь массив данных, а может, некоторая часть типа за последний час и тогда надо ограничивать размер массива
Кстати, для информации. Ваш курсовой (и даже его перспектива развития) практически является частью измерительного стенда, который я делал на работе. При этом к МК у меня могут подключаться до 30 датчиков DS18B20 (обращение происходит по серийному номеру), таких контроллеров 3 шт., всё это собирается программой на LV и записывается в БД Access. Правда, программа для МК написана на ассемблере.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 11:49:00
orinoko
протокол обмена - это в общем то дело лично каждого. У меня он таков, чтобы на одной линии уживались мои контроллеры и промышленные с ModBus
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 12:33:52
orinoko
Ну вот я немного скорректировал вашу программу. Правда, проверить не на чем.
Как то так...
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 13:28:32
YS
Вот я как раз не силен в LabView.

Более того, ненавижу его и стремлюсь уничтожить.
А вот по сишным исходникам есть пара комментариев.
Во-первых, CVAVR - не тру, ибо слишком лоялен к ошибкам и поставляется с визардами, которые отучают думать. Но это субъективно (хотя большинство народа скажет Вам то же самое). Тру - IAR либо AVR-GCC + AVR Studio.
Во-вторых, использование функций из stdio в проекте для МК чаще всего сильно раздувает код. Вам-то здесь это без разницы, ибо сама программа проще некуда, но в чем-то более серьезном может не хватить памяти.
В-третьих, какое-то стремное форматирование кода.
А теперь по коду.
Код: Выделить всё
void ifconnected()
{
datchik=w1_init();
while(datchik==0)
{
#pragma rl+
sprintf(lcd_buffer," ДАТЧИК НЕ ПОДКЛЮЧЕН");
lcd_clear();
lcd_puts(lcd_buffer);
#pragma rl-
delay_ms(500);
datchik=w1_init();
}; // ";" - не нужна.
}
Во-первых, обратите внимание на форматирование. Во-вторых, что за прагмы?
В третьих, неоптимально. Вот оптимизированный вариант:
Код: Выделить всё
void ifconnected()
{
#pragma rl+ //зачем?
sprintf(lcd_buffer," ДАТЧИК НЕ ПОДКЛЮЧЕН"); //Лучше написать свой sprintf
lcd_clear();
lcd_puts(lcd_buffer);
#pragma rl-
while(!(w1_init()));
lcd_clear();
}
Называть переменные транслитом - дикий моветон.
Код: Выделить всё
while(datchik>0)
{
temp=ds18b20_temperature(0);
sprintf(lcd_buffer," B KOMHATE: t=%i\xdfC",temp);
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer);
ifconnected();
}; // ";" не нужна
Если датчик отключат, программа выйдет за пределы цикла. Это грубейшая ошибка.
Исправляем:
Код: Выделить всё
while (1)
{
sprintf(lcd_buffer," B KOMHATE: t=%i\xdfC",ds18b20_temperature(0));
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(lcd_buffer);
ifconnected();
}
Дорабатываем ifconnected():
Код: Выделить всё
void ifconnected()
{
if (!(w1_init()))
{
sprintf(lcd_buffer," ДАТЧИК НЕ ПОДКЛЮЧЕН"); //Лучше написать свой sprintf
lcd_clear();
lcd_puts(lcd_buffer);
while(!(w1_init()));
}
lcd_clear();
}
Теперь она ждет подключения датчика.
Ффух. Это все, что видно с первого взгляда. Впитывайте.

Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 13:36:02
YS
По UART'у.
Код: Выделить всё
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;
Код генерировали визардом, признавайтесь? "Волшебные" числа - очень плохо, ибо нечитаемо.
Правильно:
Код: Выделить всё
UCSRC=(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
И так далее.
То же самое.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 13:40:11
YS
Вот, как-то так. Глядел бегло, потому мог и что-то еще пропустить. Вообще, С, несмотря на кажущуюся легкость, требует особого внимания и не прощает быдлокода (это я не к тому, что Вы написали, не подумайте, я понимаю, что Вы только учитесь, я вообще, на будущее).
Правда, компиляторы пытаются подстилать соломку. Например, у Вас программа вылетает за пределы цикла. Наверняка CVAVR неявно сгенерировал код, который ее ловит, и либо отправляет в ребут, либо просто завешивает контроллер.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 18:36:57
engee
orinoko писал(а):1. вы передаёте по одному байту за раз, но при этом преобразовываете в Double. Зачем? Т.е. вы работаете только с целым значением температуры. Как то несолидно при том , что датчик выдаёт значение с дискретностью 1/16 градуса. Но если это делать, то нужно пересмотреть протокол обмена.
2. Вы формируете массив чисел Double, постоянно увеличивающийся, и, теоретически, ваша программа будет постоянно увеличивать занимаемую память, при этом вы не используете этот массив. ( А, нет, используете в конце...)
1. Это да, просто не углублялся в эту сторону, важен был на тот момент хоть какой-то рабочий результат, но об этом упущении я упомянул в конце курсовой, наверное вскоре переделаю
2. А как можно избежать постоянно растущего массива? Даже не задумывался над этим, честно говоря.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 18:43:28
engee
orinoko писал(а):5. Служебный терминал, который у вас типа показывает количество полученных байт, на самом деле показывает количество байт в буфере приёма, а получаетет вы всегда по 1 байту. А если в буфере больше 1 байта? И тогда будут приняты данные, которы были отосланы раньше, чем вы их приняли (т.е. принятые данные будут неактуальны на данный момент времени)
5а. А если в буфере ничего не будет?
У меня на стадии проверки связи была такая проблема, что в буфере может быть то много байт, то 1, то 0, хотя по идее контроллер должен отправлять по 1 байту в ~750мс, разобраться с этим я так и не смог, поэтому к терминалу Visa Read к входу byte count я подцепил единичку, я так понял она позволяет считывать только последний байт в пакете, заработало и ладно, и даже когда ноль байтов в буфере все вроде работает, но все равно не понимаю почему так((
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 18:48:21
orinoko
2. Вариант 1 - Инициализировать сразу массив нужной длины и сделать его типа буфера FIFO
Вариант 2 - Контролировать длину, и если длина превышает некоторое значение, удалять нулевой элемент
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 18:57:52
engee
orinoko писал(а):Ну вот я немного скорректировал вашу программу. Правда, проверить не на чем.
Как то так...
Я попробовал ваш вп, работает, значения на графике меняются мгновенно(сравнивал с показаниями на lcd). Но ваши подходы более изящны, спасибо!
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 19:02:07
orinoko
engee писал(а):У меня на стадии проверки связи была такая проблема, что в буфере может быть то много байт, то 1, то 0, хотя по идее контроллер должен отправлять по 1 байту в ~750мс, разобраться с этим я так и не смог, поэтому к терминалу Visa Read к входу byte count я подцепил единичку, я так понял она позволяет считывать только последний байт в пакете, заработало и ладно, и даже когда ноль байтов в буфере все вроде работает, но все равно не понимаю почему так((
Вы считываете не последний, а самый первый (т.е. самый старый) пришедший с порта, но не считанный "Visa Read". Когда у вас показывает ноль байтов в буфере, то программа всё равно будет ждать одного байта - visa read будет ждать время, определяемое параметром Timeout при инициализации.
Просто в вашем случае программа останавливается на некоторое время, что не совсем корректно.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 19:09:39
orinoko
engee писал(а):Я попробовал ваш вп, работает, значения на графике меняются мгновенно(сравнивал с показаниями на lcd). Но ваши подходы более изящны, спасибо!
Они как бы более правильны для построения программ на LV. К этому надо привыкнуть.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 19:12:16
engee
YS писал(а):Во-первых, CVAVR - не тру, ибо слишком лоялен к ошибкам и поставляется с визардами, которые отучают думать. Но это субъективно (хотя большинство народа скажет Вам то же самое). Тру - IAR либо AVR-GCC + AVR Studio.
Во-вторых, использование функций из stdio в проекте для МК чаще всего сильно раздувает код. Вам-то здесь это без разницы, ибо сама программа проще некуда, но в чем-то более серьезном может не хватить памяти.
Полностью с вами согласен, тоже читал про что что cvavr генерирует громоздкий код, просто был учебник под рукой, и сама программа + этот визард понравился, понимаю что подход дилетантский, но выбирать не приходилось, в будущем буду пользоваться чемто другим)
YS писал(а):В-третьих, какое-то стремное форматирование кода.
Блин все время как не стараюсь, пробельчики-табуляции вставлять, все говорят что надо не так(( может есть какая-нибудь статейка в интернете как надо оформлять код по стандарту, чтоб было удобно и правильно читать? Буду очень благодарен)
Про прагмы я прочитал в статье по LCD дисплею где-то, типо нужны чтоб русский текст выводить на него, даже не пробовал без них...
Большое спасибо за код! Буду разбираться, но не уверен что до конца правильно понял фразу
YS писал(а):Если датчик отключат, программа выйдет за пределы цикла.
Пробовал отключать датчик, а потом включать, прибор возвращается в работу сам, наверное я не о том говорю да?(
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 19:24:11
engee
YS писал(а):По UART'у.
Код: Выделить всё
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;
Код генерировали визардом, признавайтесь? "Волшебные" числа - очень плохо, ибо нечитаемо.
Правильно:
Код: Выделить всё
UCSRC=(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
Да, код сгенерирован мастером начального кода, но честное слово, я разбирал все значения перед защитой курсовой) переводил из шестнадцатиричной в двоичную и смотрел как сконфигурирован каждый бит конфигурационных регистров уарта) даже скорость сам считал по формуле, все так же как мне посчитал визард(для 4800бод при такте 8Мгц(ровно) получается 103 в десятичной, т.е 67 в hex). По поводу формы записи (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); полностью с вами согласен, меня научрук тоже так учил, когда я пробывал писать на ассемблере в AvrStudio. В принципе это очень удобно и правильно, когда у каждого бита есть свое имя, и это удобно читать, гораздо удобнее чем UCSRC=0x86; Да и когда я смотрел проекты на WinAVR в интеренете, там везде пишется так, удобно читать))) И я честное слово пытался реализовать такие записи в codevision, но у меня ничего не получилось, ошибки, указывающие на неизвестные имена в коде, пытался найти похожие имена в библиотеках компилятора, но тщетно, может у меня библиотеки старые\кривые, или кодвижн в принципе не содержит в своих библиотеках имен разных битов?
ну или руки чутка кривые)
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 20:23:23
YS
Они как бы более правильны для построения программ на LV. К этому надо привыкнуть.
"Мыши плакали, кололись, но продолжали есть кактус". Зачем привыкать? Просто взять и написать нормальную программу на С/С++.
может есть какая-нибудь статейка в интернете как надо оформлять код по стандарту, чтоб было удобно и правильно читать?
Я Вас огорчу, стандарта нет.

В принципе, каждый оформляет код по-своему, и оттого регулярно случаются холивары.

Но есть общие принципы:
1. Переменные и функции должны по-возможности называться осмысленно и по-английски. Английский поймут все, транслит - только носители языка. Т.е., переменная должна бы называться не datchik, а, например, sensor_present (датчик присутствует), тем более, что по смыслу она логическая, 0/1. Но к слову, как видно, там эта переменная вообще не нужна.
2. То же касается комментариев. Предпочтителен английский язык. Во-первых, в любой точке земли поймут, а, во-вторых, комментарии на других языках порождают проблемы с кодировкой. Латиница же - везде латиница.
3. Каждый новый блок (if, while, объявление функции) должен начинаться с отступа/табуляции. Продвинутые редакторы вроде Code::Blocks это вообще сами делают. Например:
Код: Выделить всё
if (<условие>)
{
[два пробела/табуляция]<оператор>;
[два пробела/табуляция]<оператор>;
[два пробела/табуляция]if (<условие>)
[два пробела/табуляция][два пробела/табуляция]<оператор>;
}
т.е.
if (foo())
{
bar();
if (foo()*bar())
{
boo();
}
}
Еще пример:
Код: Выделить всё
void foo(int x)
{
if (x)
{
x=0;
return;
}
else
while (1);
}
И так далее.
Пробовал отключать датчик, а потом включать, прибор возвращается в работу сам
Значит Ваш косяк прикрыл компилятор, и в случае вылета за пределы программы отправляет МК в ребут.
Приведу цитату из пособия, которое я писал для кружка электроники, который веду:
Еще один момент, специфичный для встроенных систем. Чаще всего обычная программа
для «большого» компьютера выполняется под управлением операционной системы, и
потому функция main() завершается командой возврата т.н. кода завершения – знакомый
всем return 0 в ее конце. Кроме того, main() может принимать аргументы – параметры
командной строки. Однако ясно, что в микроконтроллере нет операционной системы – с
самого начала управление всеми ресурсами отдается единственной управляющей
программе. Поэтому стандартное завершение не имеет смысла – возвращать код некуда.
И, естесственно, main() в программе для МК не может принимать никаких аргументов –
им просто неоткуда взяться. Кстати, поскольку микроконтроллером исполняется всего
одна программа, оная должна иметь вид бесконечного цикла или кончаться им, потому
что поведение устройства за пределами управляющей программы не определено, и пока
устройство включено, постоянно должен исполняться пользовательский код.
Исходя из всего вышесказанного, можно представить себе базовую структуру программы
для микроконтроллера:
#include <avr/io.h>
void main(void)
{
/*Здесь обычно производится настройка периферии*/
while (1);
}
Иногда в бесконечном цикле делается что-то осмысленное, но довольно часто он пустой,
как в примере, и служит только для того, чтобы не пустить контроллер дальше
пользовательской программы, а вся работа выполняется в прерываниях.
Мораль - main() должна содержать бесконечный цикл. У вас цикл имеет условие. Как только датчик отключают, программа вылетакет из main() в неведомые дали. Посмотрите дизассемблированный листинг, наверняка CVAVR после main() воткнул перезагрузку.
ну или руки чутка кривые)
Скорее CVAVR убогий.
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Сб янв 07, 2012 23:41:51
orinoko
Уважаемый YS. Прошу извинить, но ваше выражение ""Мыши плакали, кололись, но продолжали есть кактус". Зачем привыкать? Просто взять и написать нормальную программу на С/С++." несколько оскорбительно. Есть разные причины выбирать ту или иную среду программирования, у каждой есть область применения, достоинства, недостатки, необходимость.
И если ТС выбрал LV, значит были причины, надо помочь, тем более что разобрался и написал сам, хреново, но сам. И это важно. Ведь какая разница на чём писать, главное уметь создать алгоритм и отладить. Попросил указать на ошибки.
И если предыдущее ваше мнение "Вот я как раз не силен в LabView. Более того, ненавижу его и стремлюсь уничтожить. " было типа как шутка (со смайликами), хотя и обидная для меня например, я её пропустил, но это уже занадто.
Прошу прощения за оффтопик. Наболело.
И в догонку. Если вы так болеете С/С++, то почему управляющая программа для Большого адронного коллайдера была написана на ненавистном Вам LabVIEW ?
Re: Курсовая работа: сопряжение МК AVR с ПК
Добавлено: Вс янв 08, 2012 00:17:28
РадиоЛоматель
Ого! Насколько я приятно удивлен! Ожидал увидеть тут очередную тему "Помогите сделать курсовик, времени мало, не знаю как." И даже открывать не хотел. А тут такое похвальное стремление.
По поводу проекта-ничего сказать не могу, так как не вникал еще. И ЛабВиев тоже не мое. На досуге посмотрю ваши сишные программы. Может еще чего-то подскажу, чего не заметил YS.