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

  • Автор темы Васисуалий
В

Васисуалий

Команда форума
  • 3 Фев 2013
Короче предистория тут >> https://monitor.net.ru/forum/threads/452996/

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

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

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

Первым делом решил я таблицу очистить от мусора, т.е. в каждую ячейку вписать 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 ;
              }

Запускаю - висит! :shocked:

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

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

:shocked: :shocked:

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

:shocked: :shocked:

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

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

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

Дурдом! :ma: :rupor: :crazy: :crazy:

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

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



 
S

slav0n

  • 3 Фев 2013
записать нормально
Код:
#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;
 

Информация Неисправность Прошивки Схемы Справочники Маркировка Корпуса Сокращения и аббревиатуры Частые вопросы Полезные ссылки

  • Справочная информация

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

    • Диагностика
    • Определение неисправности
    • Выбор метода ремонта
    • Поиск запчастей
    • Устранение дефекта
    • Настройка

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

  • Неисправности

    Все неисправности по их проявлению можно разделить на два вида - стабильные и периодические. Наиболее часто рассматриваются следующие:

    • не включается
    • не корректно работает какой-то узел (блок)
    • периодически (иногда) что-то происходит

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

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

    На сайте существуют разделы с прошивками (дампами памяти) для микросхем, либо для обновления ПО через интерфейсы типа USB.


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

    Начинающие ремонтники часто ищут принципиальные схемы, схемы соединений, пользовательские и сервисные инструкции. Это могут быть как отдельные платы (блоки питания, основные платы, панели), так и полные Service Manual-ы. На сайте они размещены в специально отведенных разделах и доступны к скачиванию гостям, либо после создания аккаунта:


    Внимательно читайте описание. Перед запросом схемы или прошивки произведите поиск по форуму, возможно она уже есть в архивах. Поиск доступен после создания аккаунта.
  • Справочники

    На сайте Вы можете скачать справочную литературу по электронным компонентам (справочники, таблицу аналогов, SMD-кодировку элементов, и тд.).


    Информация размещена в каталогах, файловых архивах, и отдельных темах, в зависимости от типов элементов.

  • Marking (маркировка) - обозначение на электронных компонентах

    Современная элементная база стремится к миниатюрным размерам. Места на корпусе для нанесения маркировки не хватает. Поэтому, производители их маркируют СМД-кодами.


  • Package (корпус) - вид корпуса электронного компонента

    При создании запросов в определении точного названия (партномера) компонента, необходимо указывать не только его маркировку, но и тип корпуса. Наиболее распостранены:

    • DIP (Dual In Package) – корпус с двухрядным расположением контактов для монтажа в отверстия
    • SOT-89 - пластковый корпус для поверхностного монтажа
    • SOT-23 - миниатюрный пластиковый корпус для поверхностного монтажа
    • TO-220 - тип корпуса для монтажа (пайки) в отверстия
    • SOP (SOIC, SO) - миниатюрные корпуса для поверхностного монтажа (SMD)
    • TSOP (Thin Small Outline Package) – тонкий корпус с уменьшенным расстоянием между выводами
    • BGA (Ball Grid Array) - корпус для монтажа выводов на шарики из припоя

  • Краткие сокращения

    При подаче информации, на форуме принято использование сокращений и аббревиатур, например:

      Сокращение   Краткое описание
    LEDLight Emitting Diode - Светодиод (Светоизлучающий диод)
    MOSFETMetal Oxide Semiconductor Field Effect Transistor - Полевой транзистор с МОП структурой затвора
    EEPROMElectrically Erasable Programmable Read-Only Memory - Электрически стираемая память
    eMMCembedded Multimedia Memory Card - Встроенная мультимедийная карта памяти
    LCDLiquid Crystal Display - Жидкокристаллический дисплей (экран)
    SCLSerial Clock - Шина интерфейса I2C для передачи тактового сигнала
    SDASerial Data - Шина интерфейса I2C для обмена данными
    ICSPIn-Circuit Serial Programming – Протокол для внутрисхемного последовательного программирования
    IIC, I2CInter-Integrated Circuit - Двухпроводный интерфейс обмена данными между микросхемами
    PCBPrinted Circuit Board - Печатная плата
    PWMPulse Width Modulation - Широтно-импульсная модуляция
    SPISerial Peripheral Interface Protocol - Протокол последовательного периферийного интерфейса
    USBUniversal Serial Bus - Универсальная последовательная шина
    DMADirect Memory Access - Модуль для считывания и записи RAM без задействования процессора
    ACAlternating Current - Переменный ток
    DCDirect Current - Постоянный ток
    FMFrequency Modulation - Частотная модуляция (ЧМ)
    AFCAutomatic Frequency Control - Автоматическое управление частотой

  • Частые вопросы

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

    После регистрации аккаунта на сайте Вы сможете опубликовать свой вопрос или отвечать в существующих темах. Участие абсолютно бесплатное.

    Кто отвечает в форуме на вопросы ?

    Ответ в тему Что курят программисты? (про си, контроллер, таблицу и ...) как и все другие советы публикуются всем сообществом. Большинство участников это профессиональные мастера по ремонту и специалисты в области электроники.

    Как найти нужную информацию по форуму ?

    Возможность поиска по всему сайту и файловому архиву появится после регистрации. В верхнем правом углу будет отображаться форма поиска по сайту.

    По каким еще маркам можно спросить ?

    По любым. Наиболее частые ответы по популярным брэндам - LG, Samsung, Philips, Toshiba, Sony, Panasonic, Xiaomi, Sharp, JVC, DEXP, TCL, Hisense, и многие другие в том числе китайские модели.

    Какие еще файлы я смогу здесь скачать ?

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


  • Здесь просто полезные ссылки для мастеров. Ссылки периодически обновляемые, в зависимости от востребованности тем.



В

Васисуалий

Команда форума
  • 4 Фев 2013
slav0n сказал(а):
записать нормально

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

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

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

Rаmil

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

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

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

Васисуалий

Команда форума
  • 4 Фев 2013
Дык вот стек... В общем я и сам об этом думаю, но пока плохо плаваю внутри Атолик Тру Студио. Не все понятно с его дебаггером. Короче тут для меня как бы задача с семью неизвестными. С одной стороны я среду разработки практически в первый раз вижу, с другой я процессор практически не знаю, и ваАще с таким навороченным чипом впервой борюсь. Вот раньше красота была на PIC16 программки на асме как стихотворение от зубов и процессор весь перед глазами как живой. Догадаться что куда улетело было просто, а у этого монстра всего внутри столько, пойди его пойми... :cry: :gigi:
 
S

slav0n

  • 4 Фев 2013
Васисуалий, у тебя банальная опечатка. Память выделена для 11 строк, а цикл пытается сделать 12 оборотов.
Код:
  while(table_a<=11)
Я бы написал вообще одним циклом, используя указатель.
Код:
u8 screen[11][22]; 

u8 *pt = screen;
for(u8 i=0;i<11*22;i++) *pt++ =0;
Но это всё для 8 битных процев, а писать надо учитывая разрядность проца.
 
S

slav0n

  • 4 Фев 2013
Васисуалий сказал(а):
препроцессор меня послал с твоим U8 и пришлось везде расписать Unsigned Char
дефайн в шапке пропиши
Rаmil сказал(а):
А в чём разница с точки зрения языка ?
практически ни в чём кроме внешнего вида
 
O

o_l_e_g

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

Васисуалий

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

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

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

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

Код:
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

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

slav0n

  • 4 Фев 2013
Васисуалий сказал(а):
Я совершенно запутался с двумерным массивом. Его надо создать глобально для всей программы что бы все функции имели возможность вносить в него изменения и затем вывести из него значения на экран с помощью такой же отдельной функции... В этом возник затык!
Какой тут затык?
Объявил его глобально и пользуй где хошь безо всякой передачи.
 
А

АМИГО_FAS

  • 4 Фев 2013
slav0n сказал(а):
Я совершенно запутался с двумерным массивом. Его надо создать глобально для всей программы что бы все функции имели возможность вносить в него изменения и затем вывести из него значения на экран с помощью такой же отдельной функции... В этом возник затык!
Какой тут затык?
Объявил его глобально и пользуй где хошь безо всякой передачи.

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

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

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

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

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

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


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

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

screenRGB =0xFFFF;

}

или


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

PORT=screenRGB ;

}
 
S

slav0n

  • 4 Фев 2013
Васисуалий сказал(а):
Долго смотрел на эту строку и нифига не понял ее смысла...

Обьясните плз...
вот тебе масла в огонь
 ссылка скрыта от гостей 

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

Васисуалий сказал(а):
int **matrix=new int*[n];
Перевод на русский что-то типа:
создаем массив matrix из n указателей на элементы типа int
 
S

slav0n

  • 4 Фев 2013
Я запутался с передачей двумерного массива в подпрограмму. Я, конечно, могу использовать и одномерный массив, это будет не сложно, но все же хочется что бы было круто гы-гы Крутой!
а может наш ТС просто не врубился в синтаксис Си?
Многомерность массивов была придумана для удобства Человеку а не Машине.
А оно вишь как наоборот получается.
кому она нужна эта многомерность в МК?
 
L

LH

  • 5 Фев 2013
slav0n сказал(а):
кому она нужна эта многомерность в МК?
Ну не скжи. Простой пример : двумерный массив определяет 10 спрайтов графики каждый состоит из 8 байт. Я так думаю удобнее создать один массив с названием к примеру "antenna" и в зависимости от уровня сигнала выводим один из 10 спрайтов. Пример мож не самый лучший , но суть ясна.

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

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

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

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

Rаmil

  • 5 Фев 2013
slav0n писал:
new сказал(а):
Васисуалий писал:
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];

new сказал(а):
матюкается и нифига не понимает строку int **matrix=new int*[n]
А что именно говорит ?
 
S

slav0n

  • 5 Фев 2013
LH сказал(а):
Ну не скжи. Простой пример : двумерный массив определяет 10 спрайтов графики каждый состоит из 8 байт. Я так думаю удобнее создать один массив с названием к примеру "antenna" и в зависимости от уровня сигнала выводим один из 10 спрайтов. Пример мож не самый лучший , но суть ясна.
Да какая разница? Всё равно в памяти массив займет 80 байт. Обращайся к ним любым удобным способом. Правда это справедливо для 8 битных МК. А тут надо еще разобраться как организуется память у АРМов, дабы эффективно её использовать.

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

Васисуалий

Команда форума
  • 5 Фев 2013
Rаmil сказал(а):
А что именно говорит ?





 
S

slav0n

  • 5 Фев 2013
Васисуалий, оператора new в С нет.
он есть в С++
 
В

Васисуалий

Команда форума
  • 5 Фев 2013
Тем более весело потому, что Атолик Тру Студио компилирует с чего угодно (ну типа С или ++), короче ваАще не понятно.
 
S

slav0n

  • 5 Фев 2013
Васисуалий сказал(а):
короче ваАще не понятно.
да не связывайся ты с не пойми какими исходниками.
Объявляй буфер глобально в начале своего майн.си и не морочь голову.
 
В

Васисуалий

Команда форума
  • 5 Фев 2013
slav0n, дык у мну задача не сделать что то на индикаторе и этом кирпиче, а просто изучить и индикатора и камень и Си одновременно... Т.е. цель у мну исключительно "академическая" :gigi: И вот согласно оной я не понимаю где тут обьявление именно двумерного массива?

slav0n сказал(а):
int **matrix=new int*[n];
Перевод на русский что-то типа:
создаем массив matrix из n указателей на элементы типа int
 
S

slav0n

  • 5 Фев 2013
Васисуалий сказал(а):
И вот согласно оной я не понимаю где тут обьявление именно двумерного массива?
да нету тут такого. Здесь просто резервируется ОЗУ в количестве n ячеек для хранения указателей.
 
S

slav0n

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

Rаmil

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


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

А в чём прикол.
 
S

slav0n

  • 22 Сен 2014
вот оно, алго брезенхома в действии
код был содран где-то на просторах сети, я чуть модифицировал.
Код:
/*Функция вывода прямой по алгоритму Брезенхома.*/
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;
		}
		*/
    }	
}
 

Верх Низ