Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Медленный вывод на STM32 8 битной шины (дисплей)

Ср мар 16, 2022 23:12:23

Здравствуйте!

Я переписал код, который был написан AVR по управлению в "ручную" 8 битной шиной для управления дисплеем IVI9488 при помощи платы nucleo с ST32F103RB. У меня дисплей 420*380, в уроке был 320*240. Да я понимаю, что у меня значительно большее идет данных по шине, но на AVR из цвета в цвет переходил ну практически моментально, а у меня закрашивается наверное около секунды. В чем может быть проблема?

Из-за того что я использую Nucleo64 с дисплейным шилдом, то все выводы раскиданы аж по 3 портам, поэтому написано всечерез функции с применением библиотеки HAL. Может ли это значительно уменьшать скорость ?

Изменение скорости тактирования порта с LOW на HIGH существенно ничего не меняет.
Прикладываю только файл *.cpp , думаю *.h с заголовками тут не поможет. в main.c тоже только TFT9488_ini(); да TFT9488_FillScreen(); с другими необходимыми для запуска nucleo командами

Знаю что у меня есть DMA и это может дать прирост в скорости, но я не пока не умею им пользоваться и как мне кажется, STM32 должна опережать по скорости Atmega8 , даже без использования DMA...

Так же проверял этот код на гораздо более скоростной плате f469i-disco скорость отображения 1в1 такая же как и на f103RB


Код:
/*
 * ili9488.c
 *
 *  Created on: Mar 14, 2022
 *      Author: AVerzin
 */
#include "ili9488.h"

unsigned int X_SIZE = 320;

unsigned int Y_SIZE = 480;

unsigned long dtt = 0;
// что нужно доделать

// чтобы было незаметно глазу обновление экрана он это должен делать быстрее чем за
// 1с / 25 кадров в секунду = 0,04 секунды = 40 миллисекунд = 40 000 микросекунд

// сделать функцию перевода портов линии данных из состояния чтения в состояние вывода
// убрать упоминание портов во всех функицях, сделать все на метках DATA,CS и тп (+)
// отладить функцию чтения портов линии данных (+)
// сделать функцию чтения из регистров LCD (+)
// прочитать ID LCD (!!!!) (+)

// Функция установки нужных уровней на линии выбора дисплея PORTC4
void TFT9488_CS_Active(void) {
   HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);
}
void TFT9488_CS_Idle(void) {
   HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);
}

// Функции установки состояния ножки RESET PORTC5
void TFT9488_RESET_Active(void) {
   HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);
}
void TFT9488_RESET_Idle(void) {
   HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);
}

// Функции установки состояния ножки отвечающей за строб, о том что данные готовы к считыванию
// PORTC2
void TFT9488_WR_Active(void) {
   HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, RESET);
}
void TFT9488_WR_Idle(void) {
   HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, SET);
}

// Функции установки состояния ножки если уровень низкий то мы читаем данные из LCD
// PORTB2
void TFT9488_RD_Active(void) {
   HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, RESET);
}
void TFT9488_RD_Idle(void) {
   HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, SET);
}

// Функции установки состояния ножки отвечающий за то что будет передаваться данные или команда
// PORTС3
void TFT9488_RS_Command(void) {
   HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, RESET);
}
void TFT9488_RS_Data(void) {
   HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, SET);
}

// Функция чтения данных из портов на линии данных
char TFT9488_Port_Read(void) {
   char dt;                           // переменнная для чтения данных
   TFT9488_Set_Port_Read();      // Установка портов линии даннных на чтение

   // чтение данных с портов линии данных начиная со старшего бита
   dt = HAL_GPIO_ReadPin(DATA7_GPIO_Port, DATA7_Pin);   // прочитали бит с пина
   dt <<= 1;                           // сдвинули влево на 1 разряд
   dt |= HAL_GPIO_ReadPin(DATA6_GPIO_Port, DATA6_Pin);   // прочитали следующий пин и присоединили его к dt
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA5_GPIO_Port, DATA5_Pin);
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA4_GPIO_Port, DATA4_Pin);
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA3_GPIO_Port, DATA3_Pin);
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA2_GPIO_Port, DATA2_Pin);
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA1_GPIO_Port, DATA1_Pin);
   dt <<= 1;
   dt |= HAL_GPIO_ReadPin(DATA0_GPIO_Port, DATA0_Pin);

   TFT9488_Set_Port_Write();// Возврат портов линии данных на запись, так как этот режим применяется чаще соответственно он должен быть по умолчанию

   return (dt);
}

// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
   // смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
   // мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
   // если в старшем бите 0, соотвественно выводим 0.
   HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
   HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
   HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}

// Функция которая дает строб, который говорит что данные готовы
void TFT9488_WR_Strobe(void) {
   TFT9488_WR_Active();
   TFT9488_WR_Idle();
}

//—————————————————————

void TFT9488_SendCommand(unsigned char cmd) {
   TFT9488_RS_Command();       //лапка в состоянии посылки команды
   TFT9488_RD_Idle();         //отключим чтение
   TFT9488_CS_Active();         //подали команду LCD чтобы он начал слушать
   TFT9488_Port_Write(cmd);      //выставили на нужных ножках данные
   TFT9488_WR_Strobe();         //подаем строб, чтобы LCD забрал данные
   TFT9488_CS_Idle();         //подаем команду на прекращение слушания LCD
}

//—————————————————————

void TFT9488_SendData(unsigned char dt) {
   TFT9488_RS_Data();         //лапка в состоянии посылки данных
   TFT9488_RD_Idle();         //отключим чтение
   TFT9488_CS_Active();          //выбор дисплея
   TFT9488_Port_Write(dt);
   TFT9488_WR_Strobe();
   TFT9488_CS_Idle();
}

//—————————————————————

void TFT9488_reset(void) {

   TFT9488_CS_Idle();
   TFT9488_WR_Idle();
   TFT9488_RD_Idle();
   TFT9488_RESET_Active();
   HAL_Delay(2);
   TFT9488_RESET_Idle();
   TFT9488_CS_Active();
   TFT9488_SendCommand(0x01); //Software Reset
   for (uint8_t i = 0; i < 3; i++)
      TFT9488_WR_Strobe();
   TFT9488_CS_Idle();
}
//—————————————————————

void TFT9488_Write8(unsigned char dt) {
   TFT9488_Port_Write(dt);
   TFT9488_WR_Strobe();
}

//—————————————————————

unsigned long TFT9488_ReadReg(unsigned char r) {
   unsigned long id;
   unsigned char x;
   TFT9488_CS_Active(); //выбор дисплея
   TFT9488_RS_Command(); //лапка в состоянии посылки команды
   TFT9488_Write8(r);
   TFT9488_Set_Port_Read();
   TFT9488_RS_Data();
//   _delay_us(50);

   HAL_Delay(1);
   TFT9488_RD_Active();
//   _delay_us(5);
   HAL_Delay(1);
   x = TFT9488_Port_Read();

   TFT9488_RD_Idle();
   id = x;
   id <<= 8;
   TFT9488_RD_Active();

//   _delay_us(5);
   HAL_Delay(1);
   x = TFT9488_Port_Read();
   TFT9488_RD_Idle();
   id |= x;
   id <<= 8;
   TFT9488_RD_Active();

//   _delay_us(5);
   HAL_Delay(1);
   x = TFT9488_Port_Read();
   TFT9488_RD_Idle();
   id |= x;
   id <<= 8;
   TFT9488_RD_Active();

//   _delay_us(5);
   HAL_Delay(1);
   x = TFT9488_Port_Read();
   TFT9488_RD_Idle();
   id |= x;
   if (r == 0xEF) {
      id <<= 8;
      TFT9488_RD_Active();
//      _delay_us(5);
      HAL_Delay(1);
      x = TFT9488_Port_Read();
      TFT9488_RD_Idle();
      id |= x;
   }
   TFT9488_CS_Idle();
   TFT9488_Set_Port_Write();
//   _delay_us(150);//stabilization time
   HAL_Delay(2);

   return (id);
}

//—————————————————————
// Функции настройки портов к котормы подключены линии данных на чтение или запись
// линии данных подключены к портам G и A
void TFT9488_Set_Port_Read(void) {
   GPIO_InitTypeDef GPIO_InitStruct = { 0 };
   // Каждый пин расписан индивидуально, без обьединенений для того чтобы при перенеосе этой библиотеки
   // нужно было менять пины и порты только в файле .h

   /*Configure GPIO pins : DATA7_Pin*/
   GPIO_InitStruct.Pin = DATA7_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA6_Pin*/
   GPIO_InitStruct.Pin = DATA6_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA5_Pin*/
   GPIO_InitStruct.Pin = DATA5_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA4_Pin*/
   GPIO_InitStruct.Pin = DATA4_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA3_Pin*/
   GPIO_InitStruct.Pin = DATA3_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA2_Pin*/
   GPIO_InitStruct.Pin = DATA2_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA1_Pin*/
   GPIO_InitStruct.Pin = DATA1_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA0_Pin*/
   GPIO_InitStruct.Pin = DATA0_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);
}

void TFT9488_Set_Port_Write(void) {
   GPIO_InitTypeDef GPIO_InitStruct = { 0 };

   HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, GPIO_PIN_SET);

   /*Configure GPIO pins : DATA7_Pin*/
   GPIO_InitStruct.Pin = DATA7_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA6_Pin*/
   GPIO_InitStruct.Pin = DATA6_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA5_Pin*/
   GPIO_InitStruct.Pin = DATA5_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA4_Pin*/
   GPIO_InitStruct.Pin = DATA4_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA3_Pin*/
   GPIO_InitStruct.Pin = DATA3_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA2_Pin*/
   GPIO_InitStruct.Pin = DATA2_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA1_Pin*/
   GPIO_InitStruct.Pin = DATA1_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : DATA0_Pin*/
   GPIO_InitStruct.Pin = DATA0_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);

}

// конфигурирование портов данных и управления
void TFT9488_Port_ini(void) {
   GPIO_InitTypeDef GPIO_InitStruct = { 0 };

   /* GPIO Ports Clock Enable */
   __HAL_RCC_GPIOC_CLK_ENABLE();
   __HAL_RCC_GPIOA_CLK_ENABLE();
   __HAL_RCC_GPIOB_CLK_ENABLE();

   // Конфигурирование начальных уровней, в высокое положение
   HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);
   HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, GPIO_PIN_SET);

   /*Configure GPIO pins : RS_Pin*/
   GPIO_InitStruct.Pin = RS_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(RS_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : WR_Pin*/
   GPIO_InitStruct.Pin = WR_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(WR_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : CS_Pin */
   GPIO_InitStruct.Pin = CS_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : RST_Pin */
   GPIO_InitStruct.Pin = RST_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);

   /*Configure GPIO pins : RD_pin */
   GPIO_InitStruct.Pin = RD_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(RD_GPIO_Port, &GPIO_InitStruct);

   TFT9488_Set_Port_Write();
}

// Функция установки ориентации дисплея
/*
 * 0 — вертикальная обычная ориентация
 1 — горизонтальная обычная ориентация
 2 — вертикальная перевёрнутная ориентация
 3 — горизонтальная перевёрнутная ориентация.
 *
 */
void TFT9488_SetRotation(unsigned char r) {
   TFT9488_SendCommand(0x36);
   switch (r) {
   case 0:
      TFT9488_SendData(0x48);
      X_SIZE = 320;
      Y_SIZE = 480;
      break;
   case 1:
      TFT9488_SendData(0x28);
      X_SIZE = 480;
      Y_SIZE = 320;
      break;
   case 2:
      TFT9488_SendData(0x88);
      X_SIZE = 320;
      Y_SIZE = 480;
      break;
   case 3:
      TFT9488_SendData(0xE8);
      X_SIZE = 480;
      Y_SIZE = 320;
      break;
   }
}

// Функция заливки области
void TFT9488_Flood(unsigned short color, unsigned long len)
{
   unsigned short blocks;
   unsigned char i, hi = color>>8, lo=color;
   TFT9488_CS_Active();
   TFT9488_RS_Command();
   TFT9488_Write8(0x2C);
   TFT9488_RS_Data();
   TFT9488_Write8(hi);
   TFT9488_Write8(lo);
   len--;
   blocks=(unsigned short)(len/64);//64 pixels/block
   if (hi==lo)
   {
      while(blocks--)
      {
         i=16;
         do
         {
            TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//2bytes/pixel
            TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//x4 pixel
         } while (--i);
      }
      //Fill any remaining pixels(1 to 64)
      for (i=(unsigned char)len&63;i--;)
      {
         TFT9488_WR_Strobe();
         TFT9488_WR_Strobe();
      }
   }
   else
   {
      while(blocks--)
      {
         i=16;
         do
         {
            TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
            TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
         } while (--i);
      }
      //Fill any remaining pixels(1 to 64)
      for (i=(unsigned char)len&63;i--;)
      {
         TFT9488_Write8(hi);
         TFT9488_Write8(lo);
      }
   }
   TFT9488_CS_Idle();
}

// Функция записи в регистр 32 числа
void TFT9488_WriteRegister32(unsigned char r, unsigned long d)
{
   TFT9488_CS_Active();
   TFT9488_RS_Command();
   TFT9488_Write8(r);
   TFT9488_SendData;
   HAL_Delay(1);
   TFT9488_Write8(d>>24);
   HAL_Delay(1);
   TFT9488_Write8(d>>16);
   HAL_Delay(1);
   TFT9488_Write8(d>>8);
   HAL_Delay(1);
   TFT9488_Write8(d);
   TFT9488_CS_Idle();
}
/*
 * прежде чем отправлять в память байты, нам нужно объявить область памяти, в которую будет вся наша цепочка одинаковых пикселей отправляться. Для этого мы напишем специальную функцию
 */
void TFT9488_SetAddrWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
   unsigned long t;
   TFT9488_CS_Active();
   TFT9488_SendCommand(0x2A);

   TFT9488_SendData(x1 >> 8);
   TFT9488_SendData(x1 & 0xFF);     // XSTART
   TFT9488_SendData(x2 >> 8);
   TFT9488_SendData(x2 & 0xFF);     // XEND

   TFT9488_SendCommand(0x2C);
   TFT9488_SendData(y1>>8);
   TFT9488_SendData(y1 &0xff);     // YSTART
   TFT9488_SendData(y2>>8);
   TFT9488_SendData(y2 &0xff);     // YEND

   TFT9488_SendCommand(0x2C); // write to RAM

   //t = x1;
   //t<<=16;
   //t |= x2;
   //TFT9488_WriteRegister32(0x2A,t);//Column Addres Set
   //t = y1;
   //t<<=16;
   //t |= y2;
   //TFT9488_WriteRegister32(0x2B,t);//Page Addres Set

   TFT9488_CS_Idle();
}

void TFT9488_FillScreen(unsigned int color)
{
   TFT9488_SetAddrWindow(0,0,X_SIZE-1,Y_SIZE-1);
   TFT9488_Flood(color,(long)X_SIZE*(long)Y_SIZE);
}

// Заливка прямоугольника
void TFT9488_FillRectangle(unsigned int color,unsigned int x1, unsigned int y1,
                      unsigned int x2, unsigned int y2)
{
   TFT9488_SetAddrWindow(x1, y1, x2, y2);
   TFT9488_Flood(color, (long)(x2-x1+1) * (long)(y2-y1+1));
}

void TFT9488_ini(void) {
   TFT9488_Port_ini();
   TFT9488_reset();
   HAL_Delay(1000);
   dtt = TFT9488_ReadReg(0xD3);
   TFT9488_CS_Active();


   //Software Reset
   TFT9488_SendCommand(0x01);


   // Display OFF
   TFT9488_SendCommand(0x28);

   // Positive Gamma Correction
    TFT9488_SendCommand(0xE0);
   TFT9488_SendData(0x00);
   TFT9488_SendData(0x03);
   TFT9488_SendData(0x09);
   TFT9488_SendData(0x08);
   TFT9488_SendData(0x16);
   TFT9488_SendData(0x0A);
   TFT9488_SendData(0x3F);
   TFT9488_SendData(0x78);
   TFT9488_SendData(0x4C);
   TFT9488_SendData(0x09);
   TFT9488_SendData(0x0A);
   TFT9488_SendData(0x08);
   TFT9488_SendData(0x16);
   TFT9488_SendData(0x1A);
   TFT9488_SendData(0x0F);

   //Negative Gamma  Correction
   TFT9488_SendCommand(0XE1);
   TFT9488_SendData(0x00);
   TFT9488_SendData(0x16);
   TFT9488_SendData(0x19);
   TFT9488_SendData(0x03);
   TFT9488_SendData(0x0F);
   TFT9488_SendData(0x05);
   TFT9488_SendData(0x32);
   TFT9488_SendData(0x45);
   TFT9488_SendData(0x46);
   TFT9488_SendData(0x04);
   TFT9488_SendData(0x0E);
   TFT9488_SendData(0x0D);
   TFT9488_SendData(0x35);
   TFT9488_SendData(0x37);
   TFT9488_SendData(0x0F);


   //Power Control 1
   TFT9488_SendCommand(0XC0);
   TFT9488_SendData(0x17);    //Vreg1out
   TFT9488_SendData(0x15);    //Verg2out

   //Power Control 2
   TFT9488_SendCommand(0xC1);
   TFT9488_SendData(0x41);    //VGH,VGL

   //Power Control 3
   TFT9488_SendCommand(0xC5);
   TFT9488_SendData(0x00);
   TFT9488_SendData(0x12);    //Vcom
   TFT9488_SendData(0x80);

   //Memory Access или это определение ориентации
   TFT9488_SendCommand(0x36);
   TFT9488_SendData(0x48); //01001000

   TFT9488_SendCommand(0x3A);      // Interface Pixel Format
   TFT9488_SendData(0x55);   //16 bit

   TFT9488_SendCommand(0XB0);      // Interface Mode Control
   TFT9488_SendData(0x00);      //SDO NOT USE

   TFT9488_SendCommand(0xB1);      //Frame rate
   TFT9488_SendData(0xA0);    //60Hz

   TFT9488_SendCommand(0xB4);      //Display Inversion Control
   TFT9488_SendData(0x02);    //2-dot

   TFT9488_SendCommand(0XB6);      //Display Function Control  RGB/MCU Interface Control
   TFT9488_SendData(0x02);    //MCU
   TFT9488_SendData(0x02);    //Source,Gate scan dieection
   TFT9488_SendData(0x3B);    //480 линий

   TFT9488_SendCommand(0XE9);      // Set Image Functio
   TFT9488_SendData(0x00);    // Disable 24 bit data

   TFT9488_SendCommand(0xF7);      // Adjust Control
   TFT9488_SendData(0xA9);
   TFT9488_SendData(0x51);
   TFT9488_SendData(0x2C);
   TFT9488_SendData(0x82);    // D7 stream, loose

   //Выйдем из спящего режим
   TFT9488_SendCommand(0x11);
   HAL_Delay(2);

   //Включение дисплея
   TFT9488_SendCommand(0x29);

   TFT9488_SendData(0x2C);
   HAL_Delay(2);
}
/*
 * ili9488.c
 *
 *  Created on: Mar 16, 2022
 *      Author: AVerzin
 */

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Ср мар 16, 2022 23:40:35

Код:
// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
   // смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
   // мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
   // если в старшем бите 0, соотвественно выводим 0.
   HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
   HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
   HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}

Вывод 8 бит в порт, вместе с RS и RW, если порт тот же - это одна запись в BSRR, а не вот это... Неужели на AVR было так же и заливка происходила практически моментально?

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Чт мар 17, 2022 06:32:52

Хоспаде, вы бы ещё на Ява-скрипте написали.
HAL он на то и "Уровень абстракции от железа". Он позволяет писать код одинаково для всех контроллеров производителя, но взамен выполняет МНОГО дополнительных операций внутри своих слоёв. Ну и плюс... Почему нельзя было просто вывести байт в порт? Зачем эта дикая конструкция по проверке битов?

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Чт мар 17, 2022 06:38:37

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

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Чт мар 17, 2022 07:23:18

Из-за того что я использую Nucleo64 с дисплейным шилдом, то все выводы раскиданы аж по 3 портам,
А код написан так, словно у вас каждый пин на своём порту.

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

Изменение скорости тактирования порта с LOW на HIGH существенно ничего не меняет.
Оно вообще ничего не меняет, так как влияет только на крутизну фронтов. Скорость вывода остаётся прежней.

Знаю что у меня есть DMA и это может дать прирост в скорости, но я не пока не умею им пользоваться
Нет, DMA в данном случае вам совсем не помощник. Думается, только хуже сделаете.

и как мне кажется, STM32 должна опережать по скорости Atmega8 , даже без использования DMA...
Когда вот так в лоб сравнивают скорость AVR с ARM сразу приходит в голову мультик "Ишь ты, Масленица" - "Пока твой конь четырьмя ногами - раз два три четыре... Мальчишка на двух - раз, два, раз, два".

Может ли это значительно уменьшать скорость ?
Скажу так, ваш код, навскидку, можно в десятки (а может даже сотню, смотря как ноги по портам распихать) раз ускорить.

Добавлено after 16 minutes 28 seconds:
План действий такой:
1. Отказаться от HAL_GPIO_WritePin.
2. Сгруппировать записи по портам. У вас их три, вот и должно быть три записи.
3. Объединить запись линий data с сигналами RS и RW.
4. Посмотреть на код и перегруппировать ноги так, чтобы было как можно меньше логических операций при группировке данных для записи в порты.

На каждом шаге можно получить значительный прирост в скорости. Atmega8 так уж точно обойдём :)

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Чт мар 17, 2022 20:55:35

Вывод 8 бит в порт, вместе с RS и RW, если порт тот же - это одна запись в BSRR, а не вот это... Неужели на AVR было так же и заливка происходила практически моментально?

Нет, в уроке было более оптимально просто перенос переменной в регистры. так как там все было подключено к 1 порту, я просто думал что STM32 настолько быстро дрыгает своими ножками, что и так сойдет...
AlanDrakes писал(а):замут чтобы линии на экран назначать любой порт, любой пин.

Да, именно в этом и была цель. Так как у меня разные платы и, казалось, что 8 битная шина ну никак не может быть медленной. Но видимо ошибся
VladislavS писал(а):План действий такой:
1. Отказаться от HAL_GPIO_WritePin.
2. Сгруппировать записи по портам. У вас их три, вот и должно быть три записи.
3. Объединить запись линий data с сигналами RS и RW.
4. Посмотреть на код и перегруппировать ноги так, чтобы было как можно меньше логических операций при группировке данных для записи в порты.
На каждом шаге можно получить значительный прирост в скорости. Atmega8 так уж точно обойдём

Огромное спасибо! На днях отпишусь по результатам, может даже попробую все переписать на работу с 1 портом :)
Портов на линии данных на самом деле 2, часть управления на 3ем =)

Добавлено after 2 hours 5 minutes 32 seconds:
Чтото у меня ещё более монструозное получается.... Чую я не в том направление иду, уже вижу ошибки как минимум в GPIOx->ODR = mask. Затирает весь порт и оставляет только биты данных

Код:
uint16_t mask = 0x0000;
   if (dt & 0b00000010) {
      mask = 0x0080;
   }
   GPIOC->ODR = mask;

   mask = 0x0000;
   //7 бит данных на 8 порт
   if(dt & 0b10000000) {
      mask = 0x0100;
   }
   // 0бит данных на 9 порт
   if(dt & 0b00000001){
      mask |= 0x0200;
   }
   //2бит данных на 10 порт
   if(dt & 0b00000100){
      mask |= 0x0400;
   }
   GPIOA->ODR = mask;

   mask = 0x0000;
   //3бит данных на 3 порт
   if(dt & 0b00001000){
      mask |= 0x0008;
   }
   //4 бит данных на 5 порт
   if(dt & 0b00010000){
      mask |=0x0020 ;
   }
   //6 бит данных на 10 порту
   if(dt & 0b01000000){
      mask |= 0x0400;
   }
   GPIOB->ODR = mask;

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Чт мар 17, 2022 21:37:11

Не, не, не. Ни каких ODR. Читаем про регистр BSRR.

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:15:46

2 VladislavS
Подскажите пожалуйста, переписал на BSRR, но увы не работает. Перепроверял соответствие бита и пинов все верно, однако не работает (

Код:
   if (dt & 0b10000000) maskA |= GPIO_PIN_8; // 7 бит данных на 8 пин порт А
   if (dt & 0b01000000) maskB |= GPIO_PIN_10; // 6 бит данных на 10 пин порта В
   if (dt & 0b00100000) maskB |= GPIO_PIN_4;// 5 бит данных на 4 пин порта В
   if (dt & 0b00010000) maskB |= GPIO_PIN_5; // 4 бит данных на 5 пин порта В
   if (dt & 0b00001000) maskB |= GPIO_PIN_3; // 3 бит данных на 3 пин порт В
   if (dt & 0b00000100) maskA |= GPIO_PIN_10; // 2 бит данных на 10 пин порт А
   if (dt & 0b00000010) maskC |= GPIO_PIN_7; // 1 бит данных на 7 пин порта С
   if (dt & 0b00000001) maskA |= GPIO_PIN_9; // 0  бит данных на 9 пин порт А

   GPIOA->BSRR = maskA;
   GPIOB->BSRR = maskB;
   GPIOC->BSRR = maskC;

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:21:22

BSRR состоит из двух половинок, в одной сбрасываешь все биты пинов, в другой устанавливаешь нужные(установка имеет приоритет).

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:27:36

Reflector писал(а):BSRR состоит из двух половинок, в одной сбрасываешь все биты пинов, в другой устанавливаешь нужные(установка имеет приоритет).

Честно говоря не понял (

То что я вычитал, это есть BSRR и BRR и вот BSRR ставит, BRR снимает.

написал в main вот такое и блинк работает
Код:
 uint16_t masa = 0;
 masa |= GPIO_PIN_5;

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

   //  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);


     // зажигаем 5 пин
     GPIOA -> BSRR = masa;
     HAL_Delay(150);
     GPIOA -> BRR = masa;
     HAL_Delay(150);
}

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:30:23

Нет, BSRR ставит и снимает одновременно. Ты только ставишь, через время на портах будет 10 единичек. Конечно можно снимать при помощи BRR, но тогда будет две записи в порт...

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:41:25

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

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

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 00:51:19

Похоже ты ничего не понял. Допустим нужно в PA2/PA1/PA0 записать 5 не трогая другие пины, тогда сначала очищаем все три пина записывая единички в старшую половину BSRR, а потом устанавливаем нужные два:
Код:
GPIOA->BSRR = (0x07 << 16) | 5;

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 01:25:35

Reflector,
Спасибо, действительно пока сложно понять, как работать с этим регистром в моем случае. Пример был очень наглядный и понятный, пойду возьму паузу на осмысление и понятия того как это использовать мне.
А так было просто с WritePin)

Добавлено after 8 minutes 39 seconds:
Родилось вот такое
Код:
   if (dt & 0b10000000) maskA |= GPIO_PIN_8;    // 7 бит данных на 8 пин порт А
   if (dt & 0b01000000) maskB |= GPIO_PIN_10;    // 6 бит данных на 10 пин порта В
   if (dt & 0b00100000) maskB |= GPIO_PIN_4;   // 5 бит данных на 4 пин порта В
   if (dt & 0b00010000) maskB |= GPIO_PIN_5;    // 4 бит данных на 5 пин порта В
   if (dt & 0b00001000) maskB |= GPIO_PIN_3;    // 3 бит данных на 3 пин порт В
   if (dt & 0b00000100) maskA |= GPIO_PIN_10;    // 2 бит данных на 10 пин порт А
   if (dt & 0b00000010) maskC |= GPIO_PIN_7;    // 1 бит данных на 7 пин порта С
   if (dt & 0b00000001) maskA |= GPIO_PIN_9;    // 0 бит данных на 9 пин порт А

   GPIOA->BSRR = (GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16 | maskA;
   GPIOB->BSRR = (GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16 | maskB;
   GPIOC->BSRR = GPIO_PIN_7 << 16 | maskC;


Скорость немного подросла
было 2.7 секунд
стало 1.4 секунды....

Надо ещё както ускорить в 10 раз....

Добавлено after 14 minutes 44 seconds:
Ещё вижу способ для ускорения это убрать HAL_Delay(1). В примере от AVR были микросекундные задержки, а у меня в 1000 раз больше.

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 06:34:21

На какой скорости работает процессор и какой уровень оптимизации?

Для начала вот так
Код:
GPIOA->BSRR = ((GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16)
            | ((dt & 0b10000000) << 1)   // 7 бит данных на 8 пин порт А
            | ((dt & 0b00000100) << 8)   // 2 бит данных на 10 пин порт А
            | ((dt & 0b00000001) << 9);  // 0 бит данных на 9 пин порт А

GPIOB->BSRR = ((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)
            | ((dt & 0b01000000) << 4)    // 6 бит данных на 10 пин порта В
            | ((dt & 0b00100000) >> 1)    // 5 бит данных на 4 пин порта В
            | ((dt & 0b00010000) << 1)    // 4 бит данных на 5 пин порта В
            | (dt & 0b00001000);          // 3 бит данных на 3 пин порт В

GPIOC->BSRR = (GPIO_PIN_7 << 16 )
            | ((dt & 0b00000010) << 6);   // 1 бит данных на 7 пин порта С

Затем, сюда же вводите сигналы RS и RW, их можно/нужно устанавливать вместе с данными.

На маску B напрашивается таблица перекодировки на 16 элементов, из которой выбирается значение по индексу ((dt & 0b01111000)>>3).
Последний раз редактировалось VladislavS Пт мар 18, 2022 08:34:23, всего редактировалось 2 раз(а).

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 07:03:51

Скорость немного подросла
было 2.7 секунд
стало 1.4 секунды....

Надо ещё както ускорить в 10 раз....

А вы можете использовать пины более... компактно? Или так разведено на плате?
Кстати, если контроллер изначально должен работать с экраном через параллельный порт и через FMC / FSMC шину, то ускорить вывод в него можно легко. Где-то, раз в 80.

Если же вы сами так раскидали пины... то всё очень грустно. Рекомендую скомпоновать их в восемь бит одного порта. Тогда писать можно будет всего за несколько тактов:
Код:
// Сброс пинов 0..7 порта B (шина напрямую сопоставлена D0 -> PB0, D1 -> PB1, ... D7 -> PB7
 GPIOB->BSRR = GPIO_BSRR_BR0 | GPIO_BSRR_BR1 | GPIO_BSRR_BR2 <...> GPIO_BSRR_BR7;
// Выводим байт в порт. "Нижние" биты [0..15] вызвают установку соответствующих пинов порта.
 GPIOB->BSRR = (uint8_t)NEXT_DATA_BYTE;
// Опускаем /CS, затем /WR
 GPIOx->BSRR = GPIO_BSRR_BR_cs_pin_n;
 GPIOx->BSRR = GPIO_BSRR_BR_wr_pin_n;
// Поднимаем /WR, затем /CS
 GPIOx->BSRR = GPIO_BSRR_BS_cs_pin_n;
 GPIOx->BSRR = GPIO_BSRR_BS_wr_pin_n;


В случае же с записью через FSMC, будет ещё интереснее:
Код:
// Запись байта данных
 FSMC_REGION_DATA = (uint8_t)Next_Data_Byte;
// Запись команды
 FSMC_REGION_CMD = (uint8_t)Command_Byte;

Но в этом случае нужно подключать дисплей в соответствии с распиновкой FSMC / FMC контроллера.
Например, для STM32F7 сопоставление пинов выглядит так (взял из комментариев в своём коде):
Код:
   // PORTD[0,1,4,5,7,11,13,14,15] = D2, D3, Rd, Wr, Cs, A16, D0, D1
   // PORTE[7-10] = D4, D5, D6, D7

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 09:43:24

А вы можете использовать пины более... компактно? Или так разведено на плате?
Там Nucleo с шилдом. Даже с такой разводкой можно что-то выжать. Просто надо поработать, чтобы всё нормально оптимизировалось и заинлайнилось по скорости.

Добавлено after 1 hour 2 minutes 35 seconds:
С таблицей перекодировки как-то так
Код:
// В глобальной области
#define MB(X) (((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)\
               | ((X&1)?(1<<3):0)\
               | ((X&2)?(1<<5):0)\
               | ((X&4)?(1<<4):0)\
               | ((X&8)?(1<<10):0))

const uint32_t MaskB[16] = { MB(0), MB(1), MB(2), MB(3),
                             MB(4), MB(5), MB(6), MB(7),
                             MB(8), MB(9), MB(10), MB(11),
                             MB(12), MB(13), MB(14), MB(15) };

Код:
GPIOB->BSRR = MaskB[(dt>>3)&0xF];


Добавлено after 1 hour 19 minutes 18 seconds:
Ещё наблюдение. Вы много-много раз пишете TFT9488_Write8(hi); TFT9488_Write8(lo); с одним и тем же значением hi и lo. И при каждом вызове функции вычисляются маски портов A,B,C. Можно это сделать один раз и передавать в TFT9488_Write8 указатель на структуру из трёх масок.
Код:
struct MASKS
{
  uint32_t MaskA;
  uint32_t MaskB;
  uint32_t MaskC;
};

void TFT9488_Wr(MASKS *masks)
{
  GPIOA->BSRR = masks->MaskA;
  GPIOB->BSRR = masks->MaskB;
  GPIOC->BSRR = masks->MaskC;
}
Красота
Код:
//void TFT9488_Wr(MASKS *masks)
//{
//  GPIOA->BSRR = masks->MaskA;
      LDR.N    R1,??DataTable2
      LDR      R2,[R0, #+0]
      STR      R2,[R1, #+0]
//  GPIOB->BSRR = masks->MaskB;
      LDR      R3,[R0, #+4]
      STR      R3,[R1, #+1024]
//  GPIOC->BSRR = masks->MaskC;
      LDR      R0,[R0, #+8]
      STR      R0,[R1, #+2048]
//}
      BX       LR
Если всё это заинлайнится, то и загрузка регистров R0-R3 дополнительно оптимизируется. Будет как пулемёт работать.

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 19:03:08

VladislavS писал(а):На какой скорости работает процессор и какой уровень оптимизации?

Уровень оптимизации не знаю где смотреть, я пишу в Cube. Про оптимизатор слышал только в видео про keil.

Скорости стоят максимальные SYSCLK 64 MHz и по портам тоже все по максимуму

VladislavS писал(а):Для начала вот так

Спасибо! Такое ещё 0.2 сек убрало с результата. Теперь экран перекрашивается не за 2.7с, а за 0.7с.

VladislavS писал(а):С таблицей перекодировки как-то так

К сожалению, я вообще не понимаю что тут написано ( Буду разбираться. Спасибо!

AlanDrakes писал(а):В случае же с записью через FSMC, будет ещё интереснее:

У меня 103RB, там вроде как нет FSMC...

AlanDrakes писал(а):А вы можете использовать пины более... компактно? Или так разведено на плате?

У меня nucleo плата и туда через ардуино разъем вставлен ардуиношилд с TFT. Поэтому такая и фигня с портами, обязательно, для теста оптимизированного кода подключу правильно логично все на 1 порт, и замерю скорость. Но пока хочется выжать из этого максималку.... Ибо уже и так благодаря помощи удалось снизить с 2.7 до 0.7с. Причем самый огромный прирост это с 2.7 до 1.1 сек дал переход на BSRR

Добавлено after 17 minutes 44 seconds:
Пересмотрел видео с AVR ( https://youtu.be/95gqElRb074?t=1862 )

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

Добавлено after 22 minutes:
Замерил стробы на WR при помощи анализатора,
Вложения
else.png
Вот так стробит, когда hi!=lo , как я понимаю, это будет основной режим работы
(67.06 KiB) Скачиваний: 66
if(hi==lo).png
Вот так стробит когда hi==lo
(67.31 KiB) Скачиваний: 72

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 19:05:36

Я думаю, без асма около 10 кадров в секунду должно получиться.

У F103 72 МГц штатная тактовая, включайте. Оптимизацию -О3 ставьте, ищите где.

К сожалению, я вообще не понимаю что тут написано
В порт B пишутся 4 бита одной группой, но они переставленны местами. 4 бита дают 16 разных значений для записи в BSRR. Их можно вычислить заранее, положить в массив и из него выбирать ставя в соответствие.

Вроде как у меня экран уже с похожей скоростью перекрашивается
Так вы ещё оптимизировать, по большому счёту, ещё не начали :)
Последний раз редактировалось VladislavS Пт мар 18, 2022 19:38:17, всего редактировалось 1 раз.

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Пт мар 18, 2022 19:35:59

VladislavS писал(а):У F103 72 МГц штатная тактовая, включайте. Оптимизацию -О3 ставьте, ищите где.


IDE не может поставить 72 MHz, при этом в ручную в умножителе я ничего менять не могу... а руками кодить тактирование даже и не учился

https://img.radiokot.ru/files/74784/med ... k3i6h7.png
Ответить