ATMega16A Путаются данные в коде.

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

ATMega16A Путаются данные в коде.

Сообщение Petr57 »

Всем доброго времени суток!
Проблема начала возникать когда использование флеш перевалило за 40%. Программа в некоторых местах отправляет информацию на дисплей, но делает это некорректно. Дисплей тут непричём, тк пробовал разные, в том числе и на контроллере hd44780. Причём баги возникают случайно, то есть в некоторых местах программы отображение происходит корректно, а в некоторых нет(причём если в некотором месте баги проявились, то не перепрошивка, не ресет и ничего в этом духе не поможет, они будут одни и те же).

Проще показать на примере. Итак, кусочек кода:

Код: Выделить всё

                    LCDStr(0,0,int_to_string(0);
                    LCDStr(3,0,int_to_string(15));
                    LCDStr(5,0,":");
                    LCDStr(6,0,int_to_string(30));
                    LCDStr(9,0,"Ред");
                    LCDStr(3,1,"Выход");
                    LCDStr(8,1,"~");


Вроде бы всё понятно и отобразиться должно так:
_____
0 15:30 Ред
Выход~
_____
Но вместо этого отображается следущее:
_____
0 15~30 Ред
Выходд
_____

то есть вместо строки ":" печатается строка "~", а вместо "~" - "д", причём буква "д" является окончанием предыдущей строки. и это судя по всему важно, так как если просто поменять строчки в коде местами, то характер бага измениться. к примеру, сделаем вот так:

Код: Выделить всё

                    LCDStr(0,0,int_to_string(0);
                    LCDStr(3,0,int_to_string(15));
                    LCDStr(6,0,int_to_string(30));
                    LCDStr(8,1,"~");
                    LCDStr(9,0,"Ред");
                    LCDStr(3,1,"Выход");
                    LCDStr(5,0,":");

то отобразиться следущее:
_____
0 15д30 Ред
Выход~
_____

Пробовал определять строчки через #define - не помогло.
Ещё раз напомню, что в индикаторе ошибок нет, проблема в програмном коде. Кроме того иногда, если переписать функцию, в которой работает кусочек с выводом на экран(например, приведённый выше), при этом полностью переделав структуру ИФов и СВИТЧей, то баг чудесным образом может пропасть. а может и не пропасть. На такая работа в любом случае некорректна. Код пишу в CVAVR.
Это может быть браком микроконтроллера, или ошибкой при компиляции... это догадки, подскажите, в чём тут дело!

Зы. функция LCDStr(x,y,str) пишет строку str с x-того места на y-ковой строке.
функция int_to_string(x) возвращает строку с числом x.
Последний раз редактировалось Аlex Пн авг 20, 2012 00:28:46, всего редактировалось 2 раза.
Причина: Code
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

Скорее всего, баг в функции LCDStr(x,y,str). Или в функции вывода символа.
Покажите код, который управляет LCD, что бы не гадать на кофейной гуще.
И используйте кнопку Code :)
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

U235 писал(а):Скорее всего, баг в функции LCDStr(x,y,str). Или в функции вывода символа.
Покажите код, который управляет LCD, что бы не гадать на кофейной гуще.
И используйте кнопку Code :)


Это странно, на небольших програмках я эту библиотеку гонял и не было никаких багов. Вот код функций(я так понял все не надо, тут только вывод):

Код: Выделить всё

void LCDSend(unsigned char mess, unsigned char mode)
{
    R_S=mode;
    DATA_PORT=mess;
    delay_us(500);
    Strobe=1;
    delay_us(500);
    Strobe=0;
    R_S=0;
    DATA_PORT=0xff;
    delay_ms(1);
}


void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr)
{
    LCDSend((x+y*64)|0x80,0);
    while ((*dataPtr)&&(x<40))
    {
        LCDSend(Char_correct(*dataPtr),1);
        x++;
        dataPtr++;
    }
}


тут как раз для hd44780. R_S, Strobe и DATA_PORT просто обзывалка соответствующих выводов, а Char_correct() просто переделывает русские символы, поскольку в таблице контроллера дисплея они не по ASCII.

и ещё раз отмечу, что с другими дисплеями возникют ровно те же баги. ошибки абсолютно одинаковы.

спасибо за кнопочку Code! не знал :)
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

Petr57 писал(а):...и ещё раз отмечу, что с другими дисплеями возникют ровно те же баги. ошибки абсолютно одинаковы.

С другими дисплеями тоже используется функция Char_correct?

Для проверки работы функций LCD я использовал печать всех символов. Конечно, в один экран всё не помещалось, поэтому пришлось выводить частями со сменой по нажатию кнопки.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

U235 писал(а):С другими дисплеями тоже используется функция Char_correct?

Нет. Её мне пришлось написать специально для дисплея на hd44780. Если взглянуть на таблицу символов этого контроллера, сразу понятно почему для вывода рускоязычного текста нужна эта функция.

U235 писал(а):Для проверки работы функций LCD я использовал печать всех символов. Конечно, в один экран всё не помещалось, поэтому пришлось выводить частями со сменой по нажатию кнопки.


А я выводил символы по кругу с задержкой :)) всё корректно отображается.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

Попробуйте так:

Код: Выделить всё

void LCDSend(unsigned char mess, unsigned char mode)
{
    R_S=mode;
    DATA_PORT=mess;
    delay_us(500);
    Strobe=1;
    delay_us(500);
    Strobe=0;
    delay_us(500);
    Strobe=1;
    delay_us(500);
}
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

U235 писал(а):Попробуйте так:

Код: Выделить всё

void LCDSend(unsigned char mess, unsigned char mode)
{
    R_S=mode;
    DATA_PORT=mess;
    delay_us(500);
    Strobe=1;
    delay_us(500);
    Strobe=0;
    delay_us(500);
    Strobe=1;
    delay_us(500);
}


ЭЭээ?! :? лолщито? Strobe - это стробирующая линия, которая устанавливаясь в 1 даёт контроллеру команду читать шину данных. (в даташите E). оставлять её еденицей совершенно ни к чему. да и R_S и DATA_PORT по даташиту надо сбрасывать. в реале конечно не сильно важно, но тем не менее. Тем не менее так дисплей работает, вот только баги никуда не делись - в тех же местах те жде ошибки.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

Вы назвали контроллер дисплея hd44780. Так вот он запускает обработку данных по спаду на линии E (строб).
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

Оу. ну, возможно и так, просто в даташите правила на передачу такие:
1. Установить значение лини RS
2. Вывести значение байта данных на линии шины
3. Установить линию Е=1
4. Установить линию Е=0
5. Установить линии шины в 1
на это и опирался. Извините :roll:
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

CodeVision может генерировать файл с расширением cof. Скармливаете его AVR Studio 4 (для этого есть пункт меню Tools/Debugger) и запускаете симулятор. Это позволит довольно наглядно увидеть, что именно программа шлёт в регистры.

Как вариант, можно посмотреть ассемблерный листинг. Компилятор вписывает в него фрагмент на C и то, во что этот фрагмент превратился.

Можно ещё попробовать поставить задержки между обращениями к дисплею, но это вряд ли поможет.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

в ассемблерном коде в нужных местах те же строки. но проблема решилась после того, как все строки я объявил отдельно как

Код: Выделить всё

unsigned char EXIT[]= "Выход";

багов больше нет, по крайне мере пока, но всё равно это неправильно.
codenamehawk
Вымогатель припоя
Сообщения: 527
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: ATMega16A Путаются данные в коде.

Сообщение codenamehawk »

В функции используете указатель,

Код: Выделить всё

void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr)

а передаете строку

Код: Выделить всё

LCDStr(9,0,"Ред");


вот вам и ошибки.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

Не ошибка это. Строка - это массив, имя массива - это указатель на первый элемент.
Возможно, ошибка была из-за особенностей использования компилятором оперативной памяти.
И конечно, строки, которые не изменяются при работе программы, лучше размещать во флеше. Правда, тогда придётся писать вторую функцию вывода строки.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

U235 писал(а):Возможно, ошибка была из-за особенностей использования компилятором оперативной памяти.

Наверное так, особенно что включена максимальная оптимизация по размеру программы.
Аватара пользователя
signum
Встал на лапы
Сообщения: 84
Зарегистрирован: Ср июн 22, 2011 20:41:57
Откуда: Харьков

Re: ATMega16A Путаются данные в коде.

Сообщение signum »

А я прочитал: ATMega16A ПуГаются данные в коде. :))
Аватара пользователя
Petr57
Первый раз сказал Мяу!
Сообщения: 39
Зарегистрирован: Чт июл 05, 2012 22:39:11
Откуда: Санкт-Петербург

Re: ATMega16A Путаются данные в коде.

Сообщение Petr57 »

signum писал(а):ATMega16A ПуГаются данные в коде

:)) может когда-нибудь и такое будет)
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: ATMega16A Путаются данные в коде.

Сообщение vitalik_1984 »

codenamehawk писал(а):В функции используете указатель,

Код: Выделить всё

void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr)

а передаете строку

Код: Выделить всё

LCDStr(9,0,"Ред");


вот вам и ошибки.

Похоже реально из-за этого ошибки.
Меняем положение строковых констант картинка меняется.

Правильное решение как раз пихнуть все в один массив, и этот массив с кормить в функцию.Поэтому функция работает с массивом, а со строковыми не хочет.

И конечно, строки, которые не изменяются при работе программы, лучше размещать во флеше. Правда, тогда придётся писать вторую функцию вывода строки.

Насколько я понял вы пишете в программе Code vision AVR, эта программа позволяет использовать как память флеш так и память еепром как обычные переменные.Таким образом можно передать вашей функции указатель на флеш и она тоже должна работать.
В поисках истины человек развивается.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

vitalik_1984 писал(а):Насколько я понял вы пишете в программе Code vision AVR, эта программа позволяет использовать как память флеш так и память еепром как обычные переменные.Таким образом можно передать вашей функции указатель на флеш и она тоже должна работать.

Да, CodeVision позволяет работу со флешем гораздо проще, чем WinAVR. Но функции всё равно нужно писать разные.

Код: Выделить всё

//Для строк в RAM
void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr);
//для строк в FLASH
void LCDStrf(unsigned char x, unsigned char y, unsigned char  flash *dataPtr);

При этом тело у функций будет совершенно одинаковое.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: ATMega16A Путаются данные в коде.

Сообщение U235 »

В CodeVision оперативная память используется своеобразно.

С младших адресов начинается стек данных, за ним - глобальные переменные, дальше - аппаратный стек и остальное пространство отдано куче, если программа использует функции выделения памяти.

С глобальными переменными всё довольно просто - размер этой области вычисляется на этапе сборки программы и вероятность повреждения данных довольно мала - это может произойти если аппаратный стек мал.

А вот со стеком данных ситуация другая - он используется для динамического хранения локальных переменных, передачи параметров функций и регистров, сохраняемых при прерывании. Как и аппаратный стек, стек данных растёт вниз. То есть при записи чего-либо указатель уменьшается. Размер стека данных можно изменять в настройках проекта.

Код: Выделить всё

LCDStr(3,1,"Выход");

В этом случае строка копируется в стек данных перед вызовом функции. И тут возможна ситуация, что стека данных не хватит и данные затрутся.
А в следующем - строка находится в области глобальных переменных.

Код: Выделить всё

unsigned char EXIT[]= "Выход";


LCDStr(3,1,EXIT)

Вот скорее всего в этом и кроется причина внезапных глюков.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: ATMega16A Путаются данные в коде.

Сообщение vitalik_1984 »

U235 писал(а):void LCDStrf(unsigned char x, unsigned char y, unsigned char flash *dataPtr);
[/code]
При этом тело у функций будет совершенно одинаковое.

Смысл делать объявление двух одинаковых функций?
Вот буду дома проверю.
Вы уже объявили переменную как флеш, и адрес соответственно должен будет уже передаваться как флеш.

Нужно просто объявить указатель как флеш и все функция будет универсальной.

И тело кстати только на си будет одинаковым, для доступа к флеш и оперативной памяти используются разные команды, а КВ уже подтачивает код как нужно.
В поисках истины человек развивается.
Ответить

Вернуться в «AVR»