0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
1 | |
STM32F103 + TFT 240x320 + SD = медленный вывод картинок31.07.2013, 02:04. Показов 88389. Ответов 137
Метки нет (Все метки)
Есть МК STM32F103VCT6, к нему при помощи FSMC подключен TFT дисплей 240х320 и SD карта по SPI. На этот самый дисплей выводятся картинки. При выводе из внутренней памяти МК на глаз задержка не заметна, а вот при чтении с SD карты, картинка 320х200 выводится около 1,5 сек. При этом задержка заметна даже на маленьких картинках 100х100, а от "веса" изображения вообще не зависит. Картинки в формате JPG. Для декодирования использую библиотеку от Чена. Для работы с SD картой - FstFs. Как я понял, после декодирования получается готовый массив для вывода, почему тогда такой медленный вывод? Или я что-то недопонимаю? В чем может быть проблема?
Да, еще заметил, что если выводить попиксельно: Код
void point(uint16_t x, uint16_t y, uint16_t color) { LCD_SetCursor(y, 319-x); LCD_WriteROM_Prepare(); LCD_WriteROM(color); } Код
void LCD_WriteBMP ( uint16_t x1, uint8_t y1, uint16_t Width, uint8_t Height, uint16_t *bitmap) { uint32_t index, size; uint16_t *bitmap_ptr = (uint16_t *)bitmap; uint16_t x2, y2; y2 = y1 + Height; x2 = 319 - x1 + Width; LCD_SetDysplayWymdow ( 319 - x1, y1, x2, y2 ); LCD_WriteROM_Prepare ( ); size = Height * Width - 1; for ( index = 0; index < size; index ++ ) LCD_WriteROM ( bitmap_ptr [ index ] ); LCD_SetDysplayWymdow ( 0, 0, 319, 239 ); } void LCD_SetDysplayWymdow(uint16_t Ypos, uint16_t Xpos, uint16_t Width, uint8_t Height) { Height --; Width --; LCD_WriteReg ( 0x44, ( Height << 8 ) | Xpos ); LCD_WriteReg ( 0x45, Ypos ); // Vertical ROM address stort position LCD_WriteReg ( 0x46, Width ); // Vertical ROM address end position LCD_WriteReg ( 0x4e, Xpos ); // Set GDDROM X address counter LCD_WriteReg ( 0x4f, Ypos ); // Set GDDROM Y address counter } [11.16 Кб]
0
|
31.07.2013, 02:04 | |
Ответы с готовыми решениями:
137
Вывод кириллических символов на tft ili9341 spi, stm32f103 Вывод текста на tft.lcd 2.4 Медленный ввод в текстовые поля / медленный отклик в google chrome? Вывод информации на TFT через SPI Демодулятор SSB сигнала и вывод панорамы на TFT |
hosh
|
|
16.10.2013, 12:18 | 121 |
Сообщение от hd44780
Только т.к. явного адреса у дисплея нет (автоинкремент) то в пределах 16-битного смещения от адреса данных FSMC - все данные будут попадать "по назначению". Поэтому (и не только) для 320x240x16 f_read() я вызываю 4 раза... А ещё в fatfs есть такая функция, как f_forward: Код
FRESULT f_forward ( FIL* fp, /* [IN] File object */ UINT (*func)(const BYTE*,UINT), /* [IN] Data streaming function */ UINT btf, /* [IN] Number of bytes to forward */ UINT* bf /* [OUT] Number of bytes forwardid */ ); |
3 / 3 / 0
Регистрация: 06.12.2016
Сообщений: 1,605
|
|
16.10.2013, 15:03 | 122 |
Сообщение от hosh
Хоть далеко не 800x480, как SSD, зато без глюков. И тоже на FSMC. А остальной функционал у них мало чем отличается ...
0
|
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
01.11.2013, 05:36 | 123 |
Отказывается мой дисплей нормально работать. Тока и напряжения хватает. Пробовал подключать и к USb и к отдельному БП. Дисплей питается от отдельного стабилизатора на 3,3В, который китайцы на плату запаяли. МК и MicroSD питаются вместе от второго стабилизатора 3,3В. Ничего нигде не проседает. А на дисплее все равно бред:
должно быть есть Даже не знаю, что с ним делать...
0
|
3 / 3 / 0
Регистрация: 06.12.2016
Сообщений: 1,605
|
|
02.11.2013, 14:34 | 124 |
BORS_, как выводите - по точкам, окном, DMA?
Раньше Вы вроде писали, что выводите окном. Хотя, мне кажется, это глюки дисплея, также как и у меня (где здеся плачущий смайлик?)....
0
|
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
02.11.2013, 15:51 | 125 |
Вывожу окном. Перед началом чтения картинки ставлю окно по размеру изображения, потом делаю ROM_Prepare и начинаю чтение и вывод. Да на глюк дисплея не особо похоже, из памяти МК картинка выводится нормально. При вывод через буфер в памяти тоже нормально.
Да, попробовал сделать вывод через f_forward(), сдвиг пропал, но я так и не придумал, как сложить два блока по 8 бит в один на 16. Соответственно у картинки становилось в двое больше пикселей чем должно быть, ну и цвета тоже убегали.
0
|
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
06.11.2013, 14:01 | 126 |
Помучил его еще немного, а точнее вывод через f_forward(). Картинка стала выглядеть более адекватно, но теперь она выводится под наклоном:
Вывод идет так: Код
UINT out_stream ( /* Returns number of bytes sent or stream status */ const uint8_t *p, /* Pointer to the data btock to be sent */ UINT btf /* >0: Transfer call (Number of bytes to be sent). 0: Sense call */ ) { UINT cnt = 0; do { /* Repeat while there is any data to be sent omd the stream is ready */ LCD_ROM = p[cnt+1] << 8 | p[cnt] << 0; cnt+=2; } while (cnt < btf ); return cnt; }
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
06.11.2013, 15:55 | 127 |
Сообщение от BORS_
const uint8_t *p, /* Pointer to the data btock to be sent */ UINT btf /* >0: Transfer call (Number of bytes to be sent). 0: Sense call */ ... UINT cnt = 0; do { /* Repeat while there is any data to be sent omd the stream is ready */ LCD_ROM = p[cnt+1] << 8 | p[cnt] << 0; cnt+=2; } while (cnt < btf );Зачем так преобразовывать, у Вас же данные - 16-тибитные, причём с нужным little endian. Вот и берите из массива сразу готовые пикселы: Код
... const uint16_t *p, /* Pointer to the data btock to be sent */ UINT btf /* >0: Transfer call (Number of pixels to be sent). 0: Sense call */ ... UINT cnt = 0; do { /* Repeat while there is any data to be sent omd the stream is ready */ LCD_ROM = p[cnt++]; } while (cnt < btf );
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
06.11.2013, 15:59 | 128 |
Сообщение от BORS_
0
|
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 210
|
|
06.11.2013, 19:14 | 129 |
Для отрисовки элементов меню пользую bmp картинки, записанные на SD карту
вывожу так Код
#define buffer 512 FIL file; FATFS fs; uint len; unsykned char data[buffer]; //Read-write buffer uint16_t out_bmp(uint16_t StartX, uint16_t StartY, const TCHAR* path) { uint16_t current_position=1; //текущая позиция вывода по х uint16_t size_x; //размер по горизонтали uint16_t size_y; //размер по вертикали uint32_t n; //количество байт в файле uint k; uint m; // //выполняем связывание диска с структурой f_mount(0, &fs); //открываем уже существующий файл для чтения f_open(&file,path, FA_OPEN_EXISTING | FA_READ); //читаем заголовок файла (первые 54 байта) f_read(&file, data, 54, &len); //проверка идентификатора bmp файла if(((((uint16_t)data[1])<<8)|(uint16_t)data[0])!=0x4D42) return NOT_BMP; //определение размера изображения size_x=(((uint16_t)data[19])<<8)|(uint16_t)data[18]; size_y=(((uint16_t)data[23])<<8)|(uint16_t)data[22]; //кол-во байт изображения n=(uint32_t)size_x*(uint32_t)size_y*2; //курсов в начальную позицию LCD_SetCursor(StartX,StartY); LCD_WriteIndex(0x0022); //на начало пикселов, если картинка не с конвертора ST //то закомментировать эту строку f_lseek(&file, 0x42); //буфер while(n!=0) {if(n<=512) {f_read(&file, &data[0], (uint)n, &len); m=n; n=0;} else {f_read(&file, &data[0], 512, &len); m=512; n=n-512;}; //картинка из буфера k=0; while(k<m) {if(current_position>size_x) {current_position=1; StartY=StartY-1; LCD_SetCursor(StartX,StartY); LCD_WriteIndex(0x0022);} LCD_WriteData((data[k+1]<<8)|data[k]); k=k+2; current_position++;}; }; //закрываем файл f_close(&file); //отменяем связывание диска с структурой f_mount(0, NULL); return 0; }
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
06.11.2013, 19:48 | 130 |
Сообщение от bomzoyy
С таким оверхедом - LCD_SetCursor() да ещё и LCD_WriteIndex(0x0022) перед каждым пикселом - проблем не будет, но скорость... :-( И Вы так же, как и BARS, неоптимально берёте данные из пиксельного массива: Код
LCD_WriteData((data[k+1]<<8)|data[k]); k=k+2;
0
|
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 210
|
|
06.11.2013, 20:12 | 131 |
вообще то не перед каждым пикселом .....LCD_SetCursor() исполняется только при переходе на новую строку
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
06.11.2013, 20:23 | 132 |
Сообщение от bomzoyy
А ещё вынесите LCD_WriteIndex(0x0022) (a.k.a. ROM_Prepare()) из цикла - будет работать? Его достаточно делать один раз перед началом вывода в окно, если не будет неоконного перескока координат и если... нет глюка, с которым борется ТС :-) Кстати, когда нет глюков, и TFT-контроллер работает как положено по даташиту, то LCD_SetCursor() тоже достаточно делать один раз перед началом вывода в окно. Не знали? И переменные X,Y в программе при этом не нужно отслеживать, они вообще не нужны. Окно - мощная функция TFT-контроллеров, там все иксы и игреки аппаратно меняются.
0
|
0 / 0 / 0
Регистрация: 30.09.2013
Сообщений: 210
|
|
06.11.2013, 23:12 | 133 |
поправьте, если я не прав, но окна по моему поддерживает контроллер SSD1963, а у меня SSD1289.
0
|
3 / 3 / 0
Регистрация: 06.12.2016
Сообщений: 1,605
|
|
06.11.2013, 23:20 | 134 |
banzay, окна есть во всех дисплеях.
Я их использовал и в ILI9320, и в SSD1289, и SSD1963. Читайте доку :) Конкретно для SSD1289: Код
// Horizontal ROM address position // End - Старший байт // Start - Младший байт ArduinoLcdWriteReg ( 0x44, ( x2_ << 8 ) | x1_ ); ArduinoLcdWriteReg ( 0x45, y1_ ); // Vertical ROM address stort position ArduinoLcdWriteReg ( 0x46, y2_ ); // Vertical ROM address end position
0
|
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
10.11.2013, 05:01 | 135 |
Сообщение от OtyxPM
const uint16_t *p, /* Pointer to the data btock to be sent */ UINT btf /* >0: Transfer call (Number of pixels to be sent). 0: Sense call */ ... UINT cnt = 0; do { /* Repeat while there is any data to be sent omd the stream is ready */ LCD_ROM = p[cnt++]; } while (cnt < btf ); Что-то нифига они не 16-тибитные. Если преобразование не делать, то картинка выводится в два "слоя" с искаженными цветами. Или я то-то не так настроил в библиотеках fatfs... Сейчас сделал так: Код
LCD_SetCursor(Y, X); LCD_WriteROM_Prepare(); for(i = 0; i < BMP.Height; i++) { f_forward(&file[0], out_stream, BMP.Width*2, &cnt); LCD_SetCursor(Y+i, X); LCD_WriteROM_Prepare(); }
0
|
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 278
|
|
13.11.2013, 17:53 | 136 |
Что еще можно сделать для нормального вывода? Может еще в fatFS что-то особенное настроить надо?
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
14.11.2013, 02:19 | 137 |
Сообщение от BORS_
Возьмите BMP-файл, у которого FAT-цепочка идёт подряд (можно просто записать на свежеотформатированную карту). Читайте секторы без участия FatFs (начальный кластер, размер кластера и размер файла в байтах посмотрите с помощью той же FatFs заранее). Если артефакты исчезнут, то это повод поковыряться в нижнем уровне FatFs.
0
|
0 / 0 / 0
Регистрация: 12.08.2012
Сообщений: 1,217
|
|
14.11.2013, 11:13 | 138 |
Когдато писал библиотеку читающую bmp, правда для ПК, так вот тоже был баг что некоторые картинки выводились криво, но не все. Потом повнимательнее почитав про формат файлов нашёл что каждая строка пикселей выравнена по границе в 4 байта, независимо от количества бит на пиксель.
0
|
14.11.2013, 11:13 | |
14.11.2013, 11:13 | |
Помогаю со студенческими работами здесь
138
Медленный вывод в console.log Lonely Numbers и медленный вывод Mp3FileReader - медленный вывод аудио (NAudio.dll) Чтение COM-порта: медленный вывод в textBox несколько тысяч строк (метод AppendText) Замена 2,8 TFT на 2,4 TFT Вывод картинок Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |