Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

Приветствую всех. Вот решил на Си реализовать вывод анимации на lcd дисплей от Nokia6610, ну а поскольку программист я великий))- прошу помощи у знающих товарищей!
Немного предистории:
анимация разбита на 15 изображений (спрайтов), каждый спрайт оформлен в виде массива в котором кроме самого изображения, присутствуют данные о размере оного- по вертикали и горизонтали, а также бите цветности. Далее - все изображения анимации оформлены в один массив, из которого они в цикле вызываются.
Спойлерvoid nlcd_Bitmap_Animation(unsigned char start_x, unsigned char start_y)
{
unsigned char j; // счетчик цикла
unsigned char *bitmap_data; // указатель на bmp спрайт из массива спрайтов
unsigned char *Table_smile1[15] = {(unsigned char *)bmp1_smile1, (unsigned char *)bmp2_smile1,
(unsigned char *)bmp3_smile1, (unsigned char *)bmp4_smile1,
(unsigned char *)bmp5_smile1, (unsigned char *)bmp6_smile1,
(unsigned char *)bmp7_smile1, (unsigned char *)bmp8_smile1,
(unsigned char *)bmp9_smile1, (unsigned char *)bmp10_smile1,
(unsigned char *)bmp11_smile1,(unsigned char *)bmp12_smile1,
(unsigned char *)bmp13_smile1,(unsigned char *)bmp14_smile1,
(unsigned char *)bmp15_smile1};

for (j= 0; j<15; j++)
{ // Перебираем все спрайты анимации и крутим их в цикле
bitmap_data = (unsigned char *)Table_smile1[j];// Получаем указатель на массив с массивами спрайтов

unsigned char end_x; // Ширина картинки по x
unsigned char end_y; // Высота картинки по y
unsigned char bit_col; // Цветопередача картинки
unsigned char byte; // Количество байт
unsigned char frame; // Количество кадров- не используется
unsigned int i;
unsigned char *pBit;
unsigned char *pBitmap;

pBit = (unsigned char*)bitmap_data;

end_x = pgm_read_byte(pBit); // Получаем из массива ширину изображения
end_y = pgm_read_byte(pBit +1); // Получаем из массива высоту изображения
bit_col = pgm_read_byte(pBit +2); // Получаем из массива цветность (бит- цвета)
byte = pgm_read_byte(pBit +3); // Получаем из массива количество байт
frame = pgm_read_byte(pBit +4); // Получаем из массива количество кадров(для анимации)

nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_COLMOD); // Команда выбора режима отображения цвета
nlcd_SendByte(DATA_LCD_MODE,bit_col); // Пишем значение выбранного цвета из массива

// Указываем размеры рисунка в соответствии с этими пределами
nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_CASET); // Команда адреса страницы RAM
nlcd_SendByte(DATA_LCD_MODE,start_x); // Старт
nlcd_SendByte(DATA_LCD_MODE,start_x+end_x); // Конец

nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_PASET); // Команда адреса колонки RAM
nlcd_SendByte(DATA_LCD_MODE,start_y); // Старт
nlcd_SendByte(DATA_LCD_MODE,start_y+end_y); // Конец

nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_RAMWR); // Пишем в RAM

pBitmap = (unsigned char*)bitmap_data +5; // прибавляем 5, чтобы при чтении не учитывались первые
// 5 бит с служебной информацией

for (i= 0; i<((end_x+1)*(end_y+1))>>1; i++) // Цикл отрисовки спрайта анимации
{
CS_LCD_RESET; // Отключаем дисплей
switch(bit_col) // Устанавливаем отображение цветности изображения
{
case 0x04: // Если бит цвета изображения( спрайта) равен 0x04, то
{
unsigned char bitmap;
bitmap = pgm_read_byte(pBitmap++); // Выполняем- 12 бит
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
CS_LCD_SET; // включаем дисплей
}
break; // и выходим,

case 0x05: // если 0x05:
{
unsigned char bitmap;
bitmap = pgm_read_byte(pBitmap++); // Выполняем- 16 бит
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
CS_LCD_SET; // включаем дисплей
}
break; // и выходим,

default: case 0x02: // или 0x02-
{
unsigned char bitmap;
bitmap = pgm_read_byte(pBitmap++); // Выполняем- 8 бит
nlcd_SendByte(DATA_LCD_MODE,bitmap);
bitmap = pgm_read_byte(pBitmap++);
nlcd_SendByte(DATA_LCD_MODE,bitmap);
CS_LCD_SET; // включаем дисплей
}
break; // и выходим.
} // цветность определили
}// спрайт отрисовали
nlcd_SendByte(CMD_LCD_MODE,LCD_PHILLIPS_NOP);
lcd_delay_ms(Frame_delay); // Частота кадров анимации
}// цикл спрайтов
}// конец функции
Пишу в AVRStudio 4.19 + WinAVR-20100110, все компилится без ошибок. Но! Функция выводит все 15 спрайтов и происходит останов (естественно); если я перед циклом for(j=0; j<15; j++) ставлю бесконечный цикл while(1)- тогда анимация работает как надо, но (естественно) из функции я выйти не могу.
Вот тут сам вопрос- как организовать бесконечный цикл вывода спрайтов изображения с выходом из функции?
Реклама
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

Вообще, обычно while(1) пишут в main(), тактируют этот while с требуемой частотой и в него уже вставляют свои функции.
При этом внутренние функции должны быть "прозрачными" - т. е. не завешивать while(1). Соответственно, вместо for надо юзать if. И плюсавать счетчик цикла вне ИФа.

***

Короче, попробовал создал новый проект под 4313. Создалв нем все новые файлы и накопипастил свой код в каждый файл. Все то же самое((
Для прикола открыл HEX в программаторе - даже под 2313 в нем вконце идут FFFFF немножко.
Реклама
Аватара пользователя
Psych
Опытный кот
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Re: Вопросы по С/С++ (СИ)

Сообщение Psych »

-Valerius- писал(а):Вот тут сам вопрос- как организовать бесконечный цикл вывода спрайтов изображения с выходом из функции?
while (1)
{
func();
if (что-то)break;
}
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

Вы что, какой брейк? Он тогда с цикла вылетит совсем! Или может я не понял, речь не о системном цикле проца?
***
Короче, по ИАРу. Забахал Тини84 - глючит! :o :o :o Но позже, чем Тини44!
Я не понимаю, линкер определяет, что прога не влезает, по квадрату от объема байт кода? :))
Короче, вот что он орет:
Спойлер

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

Building configuration: LED_cnt - Debug 
Updating build tree... 
 
main.c  
iccavr.exe C:\firmware_84\firmware\main.c --cpu=tiny84 -mt -o C:\firmware_84\firmware\Debug\Obj\ -lCN C:\firmware_84\ 
firmware\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 512 --clib -Ohz 
    
   IAR C/C++ Compiler V6.10.1.50424 for Atmel AVR 
   Copyright 1996-2011 IAR Systems AB.  
  
 1 821 bytes of CODE  memory (+ 16 bytes shared) 
   132 bytes of DATA  memory (+ 21 bytes shared) 
    48 bytes of XDATA memory 
 
Errors: none 
Warnings: none 
 
Linking 
xlink.exe C:\firmware_84\firmware\Debug\Obj\main.r90 -o C:\firmware_84\firmware\Debug\Exe\LED_cnt.d90 -Fubrof8 -l  
C:\firmware_84\firmware\Debug\List\LED_cnt.map -xmsn -IC:\Program Files\IAR Systems\Embedded Workbench 6.0\ 
avr\LIB\ -f C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\src\template\cfgtiny84.xcl  
-D_..X_HEAP_SIZE=10 -D_..X_TINY_HEAP_SIZE=0 -D_..X_NEAR_HEAP_SIZE=0 -D_..X_FAR_HEAP_SIZE=0  
-D_..X_HUGE_HEAP_SIZE=0 -D_..X_CSTACK_SIZE=20 -D_..X_RSTACK_SIZE=20  
-D_..X_FLASH_CODE_END=_..X_FLASH_END -f C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\src\ 
template\cfg1toim.xcl -D_..X_FLASH_BASE=_..X_INTVEC_SIZE -H1895 -h(CODE)0-(_..X_INTVEC_SIZE-1)  
-D_..X_RSTACK_BASE=_..X_SRAM_BASE -D_..X_RSTACK_END=_..X_SRAM_END -s __program_start C:\Program  
Files\IAR Systems\Embedded Workbench 6.0\avr\LIB\CLIB\cl1t-ec_nomul.r90 -e_large_write=_formatted_write  
-e_large_read=_formatted_read 
 
     IAR Universal Linker V5.2.3.14 
     Copyright 1987-2011 IAR Systems AB. 
Error[e16]: Segment CSTACK (size: 0x20 align: 0) is too long for segment definition. At least 0x2 more bytes needed.  
The problem occurred while processing the segment placement command  
"-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE", where at the moment of  
placement the available memory ranges were "DATA:e2-ff" 
   Reserved ranges relevant to this placement: 
   DATA:60-df           TINY_I 
   DATA:e0-e1           TINY_Z 
   DATA:e2-ff           CSTACK 
Error while running Linker 
 
Total number of errors: 1 
Total number of warnings: 0 
Ну извините, Тини84 - это 8 Кбайт!!!

А вот результат компиляции всего того же, только после закомментирования одной из сточек типа а+=b:
Спойлер

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

Building configuration: LED_cnt - Debug 
Updating build tree... 
 
main.c  
iccavr.exe C:\firmware_84\firmware\main.c --cpu=tiny84 -mt -o C:\firmware_84\firmware\Debug\Obj\ -lCN C:\firmware_84\ 
firmware\Debug\List\ --initializers_in_flash --debug -DENABLE_BIT_DEFINITIONS -e --eeprom_size 512 --clib -Ohz 
    
   IAR C/C++ Compiler V6.10.1.50424 for Atmel AVR 
   Copyright 1996-2011 IAR Systems AB.  
Warning[Pe177]: variable "grad" was declared but never referenced C:\firmware_84\firmware\main.c 377 
  
 1 801 bytes of CODE  memory (+ 16 bytes shared) 
   130 bytes of DATA  memory (+ 21 bytes shared) 
    48 bytes of XDATA memory 
 
Errors: none 
Warnings: 1 
 
Linking 
xlink.exe C:\firmware_84\firmware\Debug\Obj\main.r90 -o C:\firmware_84\firmware\Debug\Exe\LED_cnt.d90 -Fubrof8 -l  
C:\firmware_84\firmware\Debug\List\LED_cnt.map -xmsn -IC:\Program Files\IAR Systems\Embedded Workbench 6.0\ 
avr\LIB\ -f C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\src\template\cfgtiny84.xcl  
-D_..X_HEAP_SIZE=10 -D_..X_TINY_HEAP_SIZE=0 -D_..X_NEAR_HEAP_SIZE=0 -D_..X_FAR_HEAP_SIZE=0  
-D_..X_HUGE_HEAP_SIZE=0 -D_..X_CSTACK_SIZE=20 -D_..X_RSTACK_SIZE=20  
-D_..X_FLASH_CODE_END=_..X_FLASH_END -f C:\Program Files\IAR Systems\Embedded Workbench 6.0\avr\src\ 
template\cfg1toim.xcl -D_..X_FLASH_BASE=_..X_INTVEC_SIZE -H1895 -h(CODE)0-(_..X_INTVEC_SIZE-1)  
-D_..X_RSTACK_BASE=_..X_SRAM_BASE -D_..X_RSTACK_END=_..X_SRAM_END -s __program_start C:\Program  
Files\IAR Systems\Embedded Workbench 6.0\avr\LIB\CLIB\cl1t-ec_nomul.r90 -e_large_write=_formatted_write  
-e_large_read=_formatted_read 
 
     IAR Universal Linker V5.2.3.14 
     Copyright 1987-2011 IAR Systems AB. 
 
 1 899 bytes of CODE  memory (+             20 range fill ) 
   190 bytes of DATA  memory (+ 21 absolute ) 
    38 bytes of XDATA memory 
 
Errors: none 
Warnings: none 
 
 
Total number of errors: 0 
Total number of warnings: 1 
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

Ну если говорить о последнем посте - то тут речь идет о том, что не хватает стека, я не флэша.
Реклама
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

А где стек рассчитывается?
Там ведь написано:

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

132 bytes of DATA  memory (+ 21 bytes shared) 
Т. е. всего 153 байта. У 84-й тини 512 байт оперативы. Т. е. 2/3 может идти под стек.
Хотя, спасибо за наводку - я про оперативу как-то и забыл... :facepalm: :oops:
Реклама
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

To aam:
Сорри за задержку с ответами) А можно кусочек кода- как вы думаете использовать if и инкрементировать его вне цикла if? Опробовать в железе смогу только числа 20-го.(

To Psych:
При использовании break- как только счетчик досчитает до 15 произойдет останов анимации и выход из функции..
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

Возникла идея! :idea:

Может нужно в цикле for после передачи последнего (15-го) спрайта, передавать указатель на массив с первым спрайтом? Только как все это реализовать- пока не понимаю))
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

В том, что вы присылали, написано что размер CSTACK, которого и не хватает, равен 20 байтам. Увеличьте, посмотрите что будет. А вообще ерунда какая-то. Выложите ваш проект, или в почту киньте.
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

А где стек увеличивать?
-Valerius- писал(а):А можно кусочек кода- как вы думаете использовать if и инкрементировать его вне цикла if?

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

void main()
{
 //инициализация переферии
..
и т. д.

while(1)
{
 if(TimerFlag) //затактировались от таймера, в котором вздергивается флаг
 {
   //сюда пишем свой код
  
  //прозрачный аналог If - выполнится всего 4 раза. Если надо перезапустить - обнуляем где-то i
  if(i<4)
    {
      сделать то-то и то-то[i]
      i++;
    }

...
  TimerFlag=0;
 }
}

}
Аватара пользователя
-Valerius-
Встал на лапы
Сообщения: 99
Зарегистрирован: Сб янв 12, 2013 22:43:10
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение -Valerius- »

To aam:
Спасибо за код, будем пробовать!))
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение BCluster »

В настройках проекта, там хип и стек
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

Короче, стало прокатывать, когда я соответствующие "одноразовые" функции объявил как инлайн. (Раньше тоже пытался, но увидев по асму, что компилятор на это кладет, не стал).
А теперь еще вопрос: сегодня я узнал, что оказывается я глубокий олень, когда цепляю другие сишники проекта через include :shock:
Оказывается надо цеплять только h-файл с объявлениями и прототипами, а нужный сишник типа нигде не указывается и его находит линкер сам. Но насколько помню, даже в институте сишники вроде цепляли.
Кто дурак в итоге? :dont_know: И как все-таки делается многофайловая программа "по фен-шую"?
Аватара пользователя
Psych
Опытный кот
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Re: Вопросы по С/С++ (СИ)

Сообщение Psych »

aam писал(а):Кто дурак в итоге? И как все-таки делается многофайловая программа "по фен-шую"?
Подключают только .h, а в нем подключается сишник.
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

aam писал(а):И как все-таки делается многофайловая программа "по фен-шую"?
projectname.h

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

//projectname.h
#ifndef PROJECTNAME_H
#define PROJECTNAME_H
#include"module1.h"
#include"module2.h"
...
#endif
projectname.c

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

//projectname.c
#include"projectname.h"
...
module1.h

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

//module1.h
#ifndef MODULE1_H
#define MODULE1_H
#include"submodule.h"
...
#endif
module1.c

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

//module1.c
#include"module1.h"
...
submodule.h

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

//submodule.h
#ifndef SUBMODULE_H
#define SUBMODULE_H
...
#endif
submodule.c

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

//submodule.c
#include"submodule.h"
...
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

В итоге, из этого у меня так и остался вопрос - сами сишники выходит, нигде не указываются? Как тогда компилятор находит где искать конкретную функцию из описания h-файла? Типа сишники должны быть в одной папке и добавлены в проект?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение WiseLord »

.c файлы указывать не надо - грубо говоря, при компиляции все они скопом компилируются вместе, для каждого файла создаётся объектный .o, а уже линкер их объединяет вместе в один исполняемый.
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

А вообще, как компилятор определяет из каких сишников состоит именно этот проект? Я могу ведь в папку кучу всего напихать и что надо и что не надо. Или о том, какие сишники компилировать IAR узнает из настроек проекта, т. е. обрабатывает только те, что добавлены в проект?
Т. е. указывается ли где в тексте программы из каких фалов кроме h она состоит?

Короче дальше - интересней. Оказывается не все МК поддерживают модель памяти SMALL. 2Кб-процы поддерживают только модель ТИНИ. В итоге Ни Тини24 Линкер вылетает с ошибкой по теме TINY_I.
Что такое кстати TINY_I, TINY_Z и т. п.?
Аватара пользователя
Psych
Опытный кот
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Re: Вопросы по С/С++ (СИ)

Сообщение Psych »

aam писал(а):Что такое кстати TINY_I, TINY_Z и т. п.?
Сегменты памяти в ОЗУ. _I - инциализируемый начальными значениями, _Z - нулями. Вот только зачем они если вы пишете на Си??
Аватара пользователя
aam
Собутыльник Кота
Сообщения: 2994
Зарегистрирован: Сб фев 20, 2010 14:00:12
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение aam »

Ну этот мат произносит линкер в сообщении об ошибке. А я пытаюсь разобраться почему, например, в Тини 24 нелезет, а в 44 - лезет. По объему все норм кстати)
Ответить

Вернуться в «Разные вопросы по МК»