Обсуждаем контроллеры компании Atmel.
Ответить

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

Сб авг 04, 2012 12:46:10

Всем доброго времени суток!
Проблема начала возникать когда использование флеш перевалило за 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

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

Сб авг 04, 2012 13:25:43

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

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

Сб авг 04, 2012 16:05:18

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! не знал :)

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

Сб авг 04, 2012 17:54:33

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

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

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

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

Сб авг 04, 2012 18:03:20

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

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

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


А я выводил символы по кругу с задержкой :)) всё корректно отображается.

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

Сб авг 04, 2012 18:23:38

Попробуйте так:
Код:
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);
}

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

Сб авг 04, 2012 19:07:17

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 по даташиту надо сбрасывать. в реале конечно не сильно важно, но тем не менее. Тем не менее так дисплей работает, вот только баги никуда не делись - в тех же местах те жде ошибки.

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

Сб авг 04, 2012 19:29:34

Вы назвали контроллер дисплея hd44780. Так вот он запускает обработку данных по спаду на линии E (строб).

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

Сб авг 04, 2012 20:35:41

Оу. ну, возможно и так, просто в даташите правила на передачу такие:
1. Установить значение лини RS
2. Вывести значение байта данных на линии шины
3. Установить линию Е=1
4. Установить линию Е=0
5. Установить линии шины в 1
на это и опирался. Извините :roll:

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

Сб авг 04, 2012 22:57:00

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

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

Можно ещё попробовать поставить задержки между обращениями к дисплею, но это вряд ли поможет.

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

Вс авг 05, 2012 21:02:10

в ассемблерном коде в нужных местах те же строки. но проблема решилась после того, как все строки я объявил отдельно как
Код:
unsigned char EXIT[]= "Выход";

багов больше нет, по крайне мере пока, но всё равно это неправильно.

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

Вс авг 05, 2012 21:39:16

В функции используете указатель,
Код:
void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr)

а передаете строку
Код:
LCDStr(9,0,"Ред");


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

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

Вс авг 05, 2012 22:35:26

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

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

Пн авг 06, 2012 00:36:31

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

Наверное так, особенно что включена максимальная оптимизация по размеру программы.

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

Чт авг 16, 2012 16:29:11

А я прочитал: ATMega16A ПуГаются данные в коде. :))

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

Чт авг 16, 2012 19:59:45

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

:)) может когда-нибудь и такое будет)

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

Вс авг 19, 2012 22:13:58

codenamehawk писал(а):В функции используете указатель,
Код:
void LCDStr(unsigned char x, unsigned char y, unsigned char *dataPtr)

а передаете строку
Код:
LCDStr(9,0,"Ред");


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

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

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

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

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

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

Вс авг 19, 2012 23:44:38

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);

При этом тело у функций будет совершенно одинаковое.

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

Пн авг 20, 2012 00:33:47

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

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

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

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

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

В этом случае строка копируется в стек данных перед вызовом функции. И тут возможна ситуация, что стека данных не хватит и данные затрутся.
А в следующем - строка находится в области глобальных переменных.
Код:
unsigned char EXIT[]= "Выход";


LCDStr(3,1,EXIT)

Вот скорее всего в этом и кроется причина внезапных глюков.

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

Пн авг 20, 2012 10:49:32

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

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

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

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