STM32F407 LCD扫描过慢问题,LCD控制芯片T6963

2019-03-23 17:57发布

昨天写了一个LCD驱动,LCD控制芯片是T6963,240*128的单 {MOD}屏,用的是STM32的FSMC驱动的,使用BANK1,第一区,八位数据传输。驱动可以使用,打点画圆正常,就是扫描速度太慢,单片机用的主频是168M。但清屏一次要两秒,画圆划线也是肉眼可见的速度。请问有哪些地方什么原因可能引起?我哪里配设使用的不对吗?下面是LCD的配设程序和打点程序,填充整个屏幕程序。望有经验的人指点下。
void HMI_LCDInit(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
                FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
          FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
                FSMC_NORSRAMTimingInitTypeDef  writeTiming;

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE, ENABLE);//使能PD,PE时钟  
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC时钟  

        //背光控制
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOD,&GPIO_InitStructure);


        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOD,&GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
        GPIO_Init(GPIOE,&GPIO_InitStructure);

          GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//FSMC_D2
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//FSMC_D3
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);//FSMC_NOE
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);//FSMC_NWE
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource7,GPIO_AF_FSMC);//FSMC_NE1
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_FSMC);//FSMC_A17
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);//FSMC_D0
          GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15,AF12

          GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);//FSMC_D4
          GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);//FSMC_D5
          GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);//FSMC_D6
          GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);//FSMC_D7

  readWriteTiming.FSMC_AddressSetupTime = 3;         //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns        
  readWriteTiming.FSMC_AddressHoldTime = 0x00;         //地址保持时间(ADDHLD)模式A未用到        
  readWriteTiming.FSMC_DataSetupTime = 14;                        //数据保存时间为15个HCLK        =6*15=90ns
  readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
  readWriteTiming.FSMC_CLKDivision = 0x00;
  readWriteTiming.FSMC_DataLatency = 0x00;
  readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;         //模式A


        writeTiming.FSMC_AddressSetupTime =3;              //地址建立时间(ADDSET)为9个HCLK =54ns
  writeTiming.FSMC_AddressHoldTime = 0x00;         //地址保持时间(A               
  writeTiming.FSMC_DataSetupTime = 14;                 //数据保存时间为15个HCLK=90ns
  writeTiming.FSMC_BusTurnAroundDuration = 0x00;
  writeTiming.FSMC_CLKDivision = 0x00;
  writeTiming.FSMC_DataLatency = 0x00;
  writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;         //模式A

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;//  这里我们使用NE1 ,也就对应BTCR[0],[1]。
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
  FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM;  //SRAM   
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;//存储器数据宽度为8bit   
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
        FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;   
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;        //  存储器写使能
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;   
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 读写使用不同的时序
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming;  //写时序

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  //初始化FSMC配置

  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  // 使能BANK1

        delay_ms(50);

   LCD_WriteTCommand3(LCD_TXT_STP, 0x00, 0x00);                        // 设置文本方式RAM起始地址
   LCD_WriteTCommand3(LCD_TXT_WID, 30, 0x00);                        // 设置文本模式的宽度,宽度为N/6或N/8,N为宽度点数,如240
   LCD_WriteTCommand3(LCD_GRH_STP, 0x00, 0x00);                        // 设置图形方式RAM起始地址
   LCD_WriteTCommand3(LCD_GRH_WID, 30, 0x00);                        // 设置图形模式的宽度,宽度为N/6或N/8,N为宽度点数,如240
   LCD_WriteTCommand1(LCD_MOD_OR);                                                // 设置显示方式为"或"
   LCD_WriteTCommand1(LCD_DIS_SW|0x08);                        // 设置纯图形显示模式

  LCD_FillScreen(0x00);

}
//画点
u8  LCD_DrawPoint(u32 x, u32 y, u32 color)
{
   u32  addr;

   /* 参数过滤 */
   if(x>=GUI_LCM_XMAX) return(0);
   if(y>=GUI_LCM_YMAX) return(0);

   /* 设置缓冲区相应的点 */
   if( (color&0x01) != 0 ) gui_disp_buf[y][x>>3] |= DCB_HEX_TAB[x&0x07];//之所以用|=算法,目的是不影响点坐标临近的显示
      else  gui_disp_buf[y][x>>3] &= ~DCB_HEX_TAB[x&0x07];

   /* 刷新显示 */
   /* 找出目标地址 */
   addr = y*(GUI_LCM_XMAX>>3) + (x>>3);                 //ADDR是现显存的绝对字节编码地址,从0000~显存结尾地址
   LCD_WriteTCommand3(LCD_ADR_POS, addr&0xFF, addr>>8);        // 置地址指针(高8位=ADDR/256,低8位=ADDR截去高位,保留低8位)

   /* 输出数据 */
   LCD_WriteTCommand2(LCD_INC_WR, gui_disp_buf[y][x>>3]);
   return(1);
}
//LCD填充。以图形方式进行填充,只填充可显示部分
u8 LCD_FillScreen(u8 dat)
{  u32  i, j;

   for(i=0; i<GUI_LCM_YMAX; i++)                // 历遍所有列
   {  for(j=0; j<GUI_LCM_XMAX/8; j++)        // 历遍所有行
      {  gui_disp_buf[j] = dat;                // 填充数据
          }
   }

   /* 填充LCM */
   LCD_WriteTCommand3(LCD_ADR_POS, 0x00, 0x00);                        // 置地址指针
   LCD_WriteTCommand1(LCD_AUT_WR);                                                // 自动写
   for(i=0;i<128*30;i++)
   {  LCD_WriteTData1(dat);        
      //OSTimeDly(1);                                                        // 写数据
   }


   LCD_WriteTCommand1(LCD_AUT_OVR);                                                // 自动写结束
   LCD_WriteTCommand3(LCD_ADR_POS,0x00,0x00);                        // 重置地址指针

   return 0;
}
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
wenyangzeng
1楼-- · 2019-03-24 21:15
wk好好学习 发表于 2016-11-17 12:28
不行,改成13最小了,再小屏幕就出乱码丢数据了。

这种LCD是慢扫描器件,写完数据需要等LCD应答信号,用FSMC驱动时并等待应答信号就发送下一个数据,有可能LCD并未正确接收处理。
另外:GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;这个100MHZ太高了,应该选最慢的速度。
wk好好学习
2楼-- · 2019-03-25 00:55
wenyangzeng 发表于 2016-11-17 13:23
这种LCD是慢扫描器件,写完数据需要等LCD应答信号,用FSMC驱动时并等待应答信号就发送下一个数据,有可能 ...

谢谢,我找到问题了,仿真一步步的查,写入数据前的查询状态,公司以前的代码是直接等待一个毫秒再跳出,我把优化成查询到状态就跳出就好了。谢谢你了。

一周热门 更多>