Файлы  •  Ссылки  •  Прошивки  •  Правила  •  Архив  •   FAQ  •  Участники  •  Поиск
Регистрация  •  Вход

Что курят программисты? (про си, контроллер, таблицу и ...)

Список форумов » Среда разработчика На страницу 1, 2  След.
АвторСообщение
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




03-02-2013 16:12

Короче предистория тут >> http://monitor.net.ru/forum/viewtopic.php?t=452996

Разобрался! Заработало, прикрутил знакогенератор, вывел на экран один символ - получилось. Решил создать какой нить интерфейс типа таблички на экране для будущих программок мониторчик состояний и прочего. Шрифт выбрал 8х12, причем тупо слямзил у немцев из проекта подобного экранчика. И тут началось...

Обьявил двумерный массив по размеру экрана в знакоместах, получилось 11х22. Для экономии (ну привычка такая еще от пиков осталась, все экономить надо) обьявил числа в таблице однобайтными без знака, т.е. самое малое, что может стать переменной ( unsigned char screen [11][22]подмигивание

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

Первым делом решил я таблицу очистить от мусора, т.е. в каждую ячейку вписать 0х00 и слепил по быстрому такой вот цикл

Код:


      unsigned char screen [11][22];
      unsigned char table_a = 0;
      unsigned char table_b = 0;
//     int screen [11][22];
//     int table_a = 0;
//     int table_b = 0;

тут ля-ля-ля ------


         while(table_a<=11)
              {
               while (table_b<=21)
                     {
                      screen [table_a][table_b]= 0;
                      table_b++;
                     }
              table_a++ ;
              table_b = 0 ;
              }



Запускаю - висит! шок

Никаких предупреждений от компилятора, все законно, но ВИСИТ!

Ставлю в программе затык и запускаю снова, дебагер тормозит на затыке и дальше пошагово наблюдаю процесс...

шок шок

после того как screen [table_a][table_b]= 0; перемнная table_b++; вместо ++ становится 0х00! Причем не всегда а когда она уже равна 14! Т.е. она никогда не становится 21! Цикл не работает!

шок шок

Смотрел я тупо и долго, но потом зачем то я вынес обьявление переменных

unsigned char table_a = 0;
unsigned char table_b = 0;

за int main(void), хотя в других войдах эти переменные и нафиг не сдались, но цикл заработал! шок шок

Дурдом! Рупор

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

Цикл упорно не работает. Причем компилятор его нормально пропускает, не выдавая никаких предупреждений, грузит в процессор и запускает, но с момента старта программы все висит жестоко...

new-1.jpg


new-2.jpg



slav0n
Забанен
Забанен
Сообщения: 2261




03-02-2013 22:29

записать нормально
Код:

#define u8 unsigned char

u8 screen[11][22];

for(u8 y=0;y<11;y++)
     for(u8 x=0;x<22;x++)
          screen[y][x]= 0;

Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




03-02-2013 23:43

slav0n писал:
записать нормально


Так бы и написал, что надо заменить цикл While на цикл For...

В целом конструкция полчилась компактнее. А еще она работает! Правда препроцессор меня послал с твоим U8 и пришлось везде расписать Unsigned Char, но это мелочь...

Все равно не понятно, почему вложенные циклы While не работают? шок Ведь правилами не запрещено и ваАще я не видел никаких рекомендаций по поводу использования или неиспользования циклов...
Rаmil
Гость 5.167.*.*





03-02-2013 23:55

Может стек переполняется?
Возможно ты
Цитата:
Для экономии

размер стека урезал ?
.
Под локальные переменные память выделяется в стеке. Под циклы(вообще для любых блоков ограниченных {} ) могут выделяться участки памяти в стеке для копий переменных. Насчёт массива не уверен - под него там указатели на память должны быть, по идее. Я бы посмотрел в дебаггере где выделяется память под массив.

Цитата:
но цикл заработал

Ты две переменные перевёл в глобальные - под них память выделяется в общей памяти - не в стеке - т.е. освободил тем самым стек. Посмотри что со стеком происходит в дебаггере. Или, для начала, увеличь размер стека и посмотри на реакцию. Мне кажется что ты командой
Цитата:
screen [table_a][table_b]= 0;

прописываешь ноль в том месте где находится переменная table_b.
Кстати говоря лучше массив сделал бы глобальным. Он же у тебя роль видеобуфера играет и при каждом выходе из функции по идее он у тебя должен исчезать.

Цитата:
записать нормально

А в чём разница с точки зрения языка ?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




04-02-2013 00:03

Дык вот стек... В общем я и сам об этом думаю, но пока плохо плаваю внутри Атолик Тру Студио. Не все понятно с его дебаггером. Короче тут для меня как бы задача с семью неизвестными. С одной стороны я среду разработки практически в первый раз вижу, с другой я процессор практически не знаю, и ваАще с таким навороченным чипом впервой борюсь. Вот раньше красота была на PIC16 программки на асме как стихотворение от зубов и процессор весь перед глазами как живой. Догадаться что куда улетело было просто, а у этого монстра всего внутри столько, пойди его пойми... рёв в три ручья гы-гы
slav0n
Забанен
Забанен
Сообщения: 2261




04-02-2013 10:06

Васисуалий, у тебя банальная опечатка. Память выделена для 11 строк, а цикл пытается сделать 12 оборотов.
Код:
  while(table_a<=11)

Я бы написал вообще одним циклом, используя указатель.
Код:
u8 screen[11][22];

u8 *pt = screen;
for(u8 i=0;i<11*22;i++) *pt++ =0;

Но это всё для 8 битных процев, а писать надо учитывая разрядность проца.
slav0n
Забанен
Забанен
Сообщения: 2261




04-02-2013 11:14

Васисуалий писал:
препроцессор меня послал с твоим U8 и пришлось везде расписать Unsigned Char

дефайн в шапке пропиши
Rаmil писал:

А в чём разница с точки зрения языка ?

практически ни в чём кроме внешнего вида
o_l_e_g
Участник
Сообщения: 2454




04-02-2013 12:21

Васисуалий, Как расположена майн функция? Пляска со стеком и вложенностью циклов идёт от неё.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




04-02-2013 12:59

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

Я совершенно запутался с двумерным массивом. Его надо создать глобально для всей программы что бы все функции имели возможность вносить в него изменения и затем вывести из него значения на экран с помощью такой же отдельной функции... В этом возник затык!

Я запутался с передачей двумерного массива в подпрограмму. Я, конечно, могу использовать и одномерный массив, это будет не сложно, но все же хочется что бы было круто гы-гы Крутой!

В этом форуме http://programmersforum.ru/showthread.php?t=38174 нашел вот такой вот пример:

Код:

void randmass(int ** mass, int rows, int cols)
{
   for (int i=0; i<rows; i++){
      for (int j=0; j<cols; j++){
         mass[i][j]=rand();
      }
   }
}

int main()
{
   int n=5;
   
        int **matrix=new int*[n];
   for (int i=0;i<n;i++)
      matrix[i]=new int[n];

   randmass(matrix, 5, 5); //объявил явно как указатель на указатель
}


Попытался скопипастить его в Тру Студио, матюкается и нифига не понимает строку int **matrix=new int*[n]; ну и все, что следом за ней, так же пошло в гугл...

Долго смотрел на эту строку и нифига не понял ее смысла...

Обьясните плз...

Добавлено 04-02-2013 13:06

o_l_e_g писал:
Васисуалий, Как расположена майн функция? Пляска со стеком и вложенностью циклов идёт от неё.


А как ее можно расположить? В майн.си, после инклюдов и обьявления массива сразу и начинается int main(void), в ней куча строк инициализации периферии, все светодиоды, кнопка и SPI, затем в том же майне тот самый цикл, где таблица обнуляется, потом несколько строк, которые прописывают в некоторые ячейки Helo World и некоторые символы вверху, все точно как на картинке. Это было надо, что бы ориентироваться в номерах символов, и потом вызов подфункйии с инициализацией дисплея (там своеобразный танец с бубном на SPI затем несколько байт инфы в регистры индикатора) после чего я хочу воткнуть подфункцию вывода инфы из таблицы на индикатор, но вот тут у мну и проблема вышла - не могу передать внутрь функции массив. Компилятор не ругается, но проц улетает в завис, а дебаггер пишет об обращении к неправильному адресу памяти и все...

Добавлено 04-02-2013 13:08

Да, к стати... Если всю канитель с индикатором вынести из подфункции в майн, то индикатор работает как часики. Собственно так я и сделал фотки...
slav0n
Забанен
Забанен
Сообщения: 2261




04-02-2013 13:32

Васисуалий писал:
Я совершенно запутался с двумерным массивом. Его надо создать глобально для всей программы что бы все функции имели возможность вносить в него изменения и затем вывести из него значения на экран с помощью такой же отдельной функции... В этом возник затык!

Какой тут затык?
Объявил его глобально и пользуй где хошь безо всякой передачи.
АМИГО_FAS
Участник
Сообщения: 206




04-02-2013 17:06

slav0n писал:
Васисуалий писал:
Я совершенно запутался с двумерным массивом. Его надо создать глобально для всей программы что бы все функции имели возможность вносить в него изменения и затем вывести из него значения на экран с помощью такой же отдельной функции... В этом возник затык!

Какой тут затык?
Объявил его глобально и пользуй где хошь безо всякой передачи.


Совершенно точно.

Зачем усложнятся. Обьявил глобально массив (буфер).
Размер установил.
Добавлю, не дай Бог, программа вылезет, за пределы размера массива.
Не предсказуемый висяк или поведение неадекватное обеспечено.
Нужно постоянно помнить размер буфера и в функциях где он используется прибегать к разным вариантам ограничения.

В компьютерных приложениях, такой перебор массива, моментом выдаст ошибку и приложение закроется. А вот в микроконтроллерах, компилятор ругатся на это не будет, но в практике контроллер повесится.

Добавлено 04-02-2013 17:44

Васисуалий,
Я с другим монитором работаю TFT_320QVT
Использую вариант 565;
без заморочек обьявляю глобально

unsigned int screenRGB [size];
при rgb=565;
Помним, что 5 бит старших красный, следующие 6 зеленый, 5 младших синий.


и по всей программе из всех функций пользуем его без заморочек

for( int i=0;i<size;i++){

screenRGB [i]=0xFFFF;

}

или


for( int i=0;i<size;i++){

PORT=screenRGB [i];

}
slav0n
Забанен
Забанен
Сообщения: 2261




04-02-2013 21:04

Васисуалий писал:
Долго смотрел на эту строку и нифига не понял ее смысла...

Обьясните плз...

вот тебе масла в огонь
динамический массив

Добавлено 04-02-2013 20:51

Васисуалий писал:
int **matrix=new int*[n];

Перевод на русский что-то типа:
создаем массив matrix из n указателей на элементы типа int
slav0n
Забанен
Забанен
Сообщения: 2261




04-02-2013 22:29

Цитата:
Я запутался с передачей двумерного массива в подпрограмму. Я, конечно, могу использовать и одномерный массив, это будет не сложно, но все же хочется что бы было круто гы-гы Крутой!

а может наш ТС просто не врубился в синтаксис Си?
Многомерность массивов была придумана для удобства Человеку а не Машине.
А оно вишь как наоборот получается.
кому она нужна эта многомерность в МК?
LH
Участник
Сообщения: 1370




05-02-2013 07:24

slav0n писал:
кому она нужна эта многомерность в МК?

Ну не скжи. Простой пример : двумерный массив определяет 10 спрайтов графики каждый состоит из 8 байт. Я так думаю удобнее создать один массив с названием к примеру "antenna" и в зависимости от уровня сигнала выводим один из 10 спрайтов. Пример мож не самый лучший , но суть ясна.

slav0n писал:
а может наш ТС просто не врубился в синтаксис Си?

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

Добавлено 05-02-2013 07:29

Кстати по существу вопроса:
Васисуалий писал:
Что курят программисты?


Я както из нашей конторы программера спросил, что он курил когда писал просмотрщик и декодировщик файлов?
Так он вполне конкретно ответил на этот вопрос - "оо-о ! это сильная трава"
Rаmil
Гость 85.233.*.*





05-02-2013 09:58

slav0n писал:
Цитата:
Васисуалий писал:
int **matrix=new int*[n];

Перевод на русский что-то типа:
создаем массив указателей matrix, состоящий из n указателей на элементы типа int

Поподробнее я тут попытался описать в своих поправках.

Я бы ещё добавил что указатели при объявлении указывают в никуда и их нужно инициализировать что и делается сначала для массива указателей на указатели(matrix[]) а потом в цикле каждый элемент из этого массива matrix[][], т.к. каждый элемент этого массива сам по себе является указателем уже на массив(в этом примере) с элементами типа int.
Если попытаться использовать неинициализированный указатель полёт в никуда обеспечен.


Код:
 int n=5;
   
        int **matrix=new int*[n];
   for (int i=0;i<n;i++)
      matrix[i]=new int[n];


Цитата:
матюкается и нифига не понимает строку int **matrix=new int*[n]

А что именно говорит ?
slav0n
Забанен
Забанен
Сообщения: 2261




05-02-2013 14:16

LH писал:
Ну не скжи. Простой пример : двумерный массив определяет 10 спрайтов графики каждый состоит из 8 байт. Я так думаю удобнее создать один массив с названием к примеру "antenna" и в зависимости от уровня сигнала выводим один из 10 спрайтов. Пример мож не самый лучший , но суть ясна.

Да какая разница? Всё равно в памяти массив займет 80 байт. Обращайся к ним любым удобным способом. Правда это справедливо для 8 битных МК. А тут надо еще разобраться как организуется память у АРМов, дабы эффективно её использовать.

Rаmil писал:
создаем массив указателей matrix, состоящий из n указателей на элементы типа int

"массив указателей, состоящий из указателей"
масло масляное
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




05-02-2013 14:17

Rаmil писал:
А что именно говорит ?


new-1.jpg


new-2.jpg


new-3.jpg



slav0n
Забанен
Забанен
Сообщения: 2261




05-02-2013 14:21

Васисуалий, оператора new в С нет.
он есть в С++
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




05-02-2013 15:50

Тем более весело потому, что Атолик Тру Студио компилирует с чего угодно (ну типа С или ++), короче ваАще не понятно.
slav0n
Забанен
Забанен
Сообщения: 2261




05-02-2013 19:35

Васисуалий писал:
короче ваАще не понятно.

да не связывайся ты с не пойми какими исходниками.
Объявляй буфер глобально в начале своего майн.си и не морочь голову.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5261




05-02-2013 20:09

slav0n, дык у мну задача не сделать что то на индикаторе и этом кирпиче, а просто изучить и индикатора и камень и Си одновременно... Т.е. цель у мну исключительно "академическая" гы-гы И вот согласно оной я не понимаю где тут обьявление именно двумерного массива?

slav0n писал:
Васисуалий писал:
int **matrix=new int*[n];

Перевод на русский что-то типа:
создаем массив matrix из n указателей на элементы типа int

slav0n
Забанен
Забанен
Сообщения: 2261




05-02-2013 20:45

Васисуалий писал:
И вот согласно оной я не понимаю где тут обьявление именно двумерного массива?

да нету тут такого. Здесь просто резервируется ОЗУ в количестве n ячеек для хранения указателей.
slav0n
Забанен
Забанен
Сообщения: 2261




21-09-2014 14:56

Прикол. Напишите сиЕ в удобоваримом виде:
Код:
if(a == (b ? y : x)) return (b ? x : y);

Rаmil
Гость 83.149.*.*





21-09-2014 16:12

slav0n писал:
Прикол. Напишите сиЕ в удобоваримом виде:
Код:
if(a == (b ? y : x)) return (b ? x : y);



Код:
 
 if(b)
   {
    if(a==y) return x;
   }
  else
   {
    if(a==x) return y;
   }


А в чём прикол.
slav0n
Забанен
Забанен
Сообщения: 2261




22-09-2014 01:30

прикол в говнокоде
Rаmil
Гость 178.207.*.*





22-09-2014 08:49

интересно в каком месте понадобились такие хитрые условия
slav0n
Забанен
Забанен
Сообщения: 2261




22-09-2014 12:49

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

/*Функция вывода прямой по алгоритму Брезенхома.*/
int LCD_LINE(int xt, int x0, int x1, int y0, int y1)
{   
   u8 steep =0;
   
   if (abs1(y1 - y0) > abs1(x1 - x0))// Проверяем рост отрезка по оси икс и по оси игрек
   {
      steep =-1;
   // Отражаем линию по диагонали, если угол наклона слишком большой   
      swap(&x0, &y0);
        swap(&x1, &y1);   
   }
    // Если линия растёт не слева направо, то меняем начало и конец отрезка местами
    if (x0 > x1)
    {
        swap(&x0, &x1);
        swap(&y0, &y1);
    }
   
    int dx = x1 - x0;
    int dy = abs1(y1 - y0);
    int error = dx; // Здесь используется оптимизация с умножением на dx, чтобы избавиться от лишних дробей
    int ystep = (y0 < y1) ? 1 : -1; // Выбираем направление роста координаты y
   int y = y0;
   
    for (int x = x0; x <= x1; x++)
    {
    //    PUT_PIXEL_to_video_bufer(steep ? y : x, steep ? x : y); // Не забываем вернуть координаты на место
       
      error -= dy;
        if (error < 0)
        {
            y += ystep;
            error += dx;
        }
      
      if(xt == (steep ? y : x)) return (steep ? x : y);
   /*      
      if(steep)
      {
         if(xt == y)return x;
      }
      else
      {
         if(xt == x)return y;
      }
      */
    }   
}

Rаmil
Гость 178.207.*.*





22-09-2014 15:54

Свапы я бы на месте делал, при большом количестве точек вызывать функции накладно по времени. Ну или инлайнить эти функции, или макросом реализовать. Или у тебя это и так макросы ? Эти swap-ы ?

пс. Я вот так и не дошёл до графики на таком низком уровне. Сглаживание линий реализовал ? Чтобы линия выглядела линией а не ступеньками шла. Растеризация сложная тема по нудности и длине её теории. Я сходу, наскоком не смог этого освоить.


ппс. Ну и конкретно по этому коду - то получается что к примеру при условиях
steep != 0 и при этом xt != y до return дело никогда не дойдёт, в лучшем случае функция возвратит мусор. В худшем код пойдёт выполняться дальше за телом этой функции. Гарантированное зависание. А по общему коду вникать, - возможна такая ситуация или нет, желания нет. Но код получается некорректным.
slav0n
Забанен
Забанен
Сообщения: 2261




23-09-2014 20:09

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

пс.Да... До каких только извращений не додумаешься под настроение.
Это ж надо - брезенхома впихнуть в нагревалку.
Вот медленный эквивалент вышеприведенной ереси:
Код:
int LCD_LINE(int xt, int x0, int x1, int y0, int y1)
{
   int res = xt * (y1-y0) * 10 / (x1-x0);
   //для прикола округляем до целого
   if(abs(res)%10 >= 5)return ((res>0) ? res/10 + 1 : res/10 - 1);
   else return res/10;
}

Rаmil
Гость 178.207.*.*





25-09-2014 16:37

Когда я пытался вникать в эти алгоритмы я запомнил что есть версии алгоритма без делений, суть там была в том что направление следующей точки зависело только от знака какого-то простого выражения. Типа меньше ноля рисуем точку выше, больше ноля рисуем, ниже или что то в этом духе. Или же от знака зависело что брать за функцию, а что за аргумент, т.е. то ли y(x) то ли x(y) - это так как у тебя это сделано.
Точно не помню.

пс. А чем нагревалка не подходит для брезенхема ?
slav0n
Забанен
Забанен
Сообщения: 2261




27-09-2014 09:35

Rаmil писал:
А чем нагревалка не подходит для брезенхема ?

подходит конечно. Но если нагревалка это какая нибудь одно-двухканальная печка, то чтобы держать пару температурных профилей зачем там супербыстрый алгоритм
SSergeB
Новичок
Сообщения: 5




07-10-2014 04:39

slav0n писал:
Это ж надо - брезенхома впихнуть в нагревалку.
Вот медленный эквивалент вышеприведенной ереси

Он не только медленный. Он еще и ошибку накопит, как любой другой с плавающей точкой в целочисленной среде. А вот по Брезенхэму ошибка всегда не больше 1/2 шага, независимо от того, насколько далеко ушагали.
В нагревалках брезенхэм, чтобы рулить периодами сети, а не фазой, дешево и без ошибок. Почему полагается именно периоды пропускать - сам знать должен...

Васисуалий - все-таки камушек, с которым балуешь, указывать надо. АРМы, они разные... А инициализация камня - это вообще отдельная песня. Которую компилятор не слышит.
Список форумов » Среда разработчика » Что курят программисты? (про си, контроллер, таблицу и ...) На страницу 1, 2  След.
Перейти:  
Текущий раздел » Среда разработчика ( Программы, базы данных, документация, симуляторы и т.д.)


Похожая информация:
  • Программисты C нужна помощь...







  • Электроника
    Прошивки и схемы на телевизоры, мониторы, dvd, телефоны. Schematic, Service Manual (mode), eeprom dumps Информация по ремонту для специалистов - справочники, инструкции, энциклопедия, советы и секреты ремонта,  настройка, сервисные режимы поиск и продажа электронных компонентов, магазины, datasheet, pdf, размещение в интернете рекламы на сайтах электронной тематики
    Powered by phpBB 2.0.18 © 2001, 2002 phpBB Group!