问答

汇集网友智慧,解决技术难题

21ic问答首页 - PIC单片机驱动LCD(ST7789)问题

pic LCD spi 单片机驱动 ST

PIC单片机驱动LCD(ST7789)问题

hanyao2021-12-17
本帖最后由 pzsh 于 2021-12-24 11:15 编辑

单片机型号:PIC16F1508
LCD驱动芯片:ST7789V
问题点1:用PIC单片机SPI控制LCD(ST7789V),用示波器测量SPI波形是符合ST7789V的时序要求的,但是PIC和LCD连接后,LCD没有任何显示。按住PIC单片机的复位键(MCLR 复位),LCD有显示。
问题点2:使用的是内部晶振,设置成4MHz和500KHz,SPI的SCK波形周期竟然是一样的,SCK设置的是Fosc/4
回答 +关注 0
1824人浏览 9人回答问题 分享 举报
9 个回答
  • 示波器本身就会带进去干扰
  • 为什么我的波形都是杂波呢
  • 波形非常的规整
  • 是不是就是波特率的事情啊
  • 更换一下io口的模式
  • 用MCC生成代码试试看
  • 您是使用硬件SPI并通过MCC配置生成基本代码么?如果是的话,MCC在生成代码时会自动根据主频计算SPI的时序,所以无论您设置的主频多少,其SPI的时序当然的一样的,除非您修改了SPI的传输率。
  • 示波器波形:
    1号探头:SCK时钟
    2号探头:SDO,示波器测试时数据是0x33
    3号探头:CS片选
    4号探头:不用在意,随便接了一个
  • 源代码如下:

    /******************************************************************************
      PIC侧                      LCD侧

      PIC                       LCD
      RC7(SDO)                  SDI(P13)
      RB6(SCK)                  SCK(P10)
      RC0                       RESET(P15)
      RC1                       WR(P11)
      RC2                       CS(P9)
    ******************************************************************************/
    #include <xc.h>

    //-------------------------------CONFIG1设置--------------------------------//
    #pragma config FOSC = INTOSC    // 内部振荡器
    #pragma config WDTE = OFF       // 看门狗器关
    #pragma config PWRTE = OFF      // 上电延时关
    #pragma config MCLRE = ON       // MCLR使能,弱上拉
    #pragma config CP = OFF         // 代码保护关
    #pragma config BOREN = OFF      // 欠压复位关
    #pragma config CLKOUTEN = OFF   // 时钟输出关
    #pragma config IESO = OFF       // 内/外部切换关
    #pragma config FCMEN = ON       // 故障保护开

    //-------------------------------CONFIG2设置--------------------------------//
    #pragma config WRT = OFF        // 闪存保护关
    #pragma config STVREN = ON      // 堆栈溢出复位
    #pragma config BORV = LO        // 欠压复位电压选择低跳变点
    #pragma config LPBOR = OFF      // 低功耗欠压复位关
    #pragma config LVP = OFF        // 高电压编程

    //-------------------------------振荡器设置---------------------------------//
    //#pragma osccon = 0x6A           //4MHz内部振荡器,指令周期1us
    //#define _XTAL_FREQ 4000000      //振荡器频率4MHz
    #pragma osccon = 0x3A           //500KHz内部振荡器
    #define _XTAL_FREQ 500000      //振荡器频率500KHz
    //#pragma osccon = 0x7A           //16MHz内部振荡器
    //#define _XTAL_FREQ 16000000      //振荡器频率16MHz
    //-------------------------------引脚定义---------------------------------//
    unsigned char LCD_SDI;
    #define LCD_SDI RC7
    unsigned char LCD_SCK;
    #define LCD_SCK RB6
    unsigned char LCD_RESET;
    #define LCD_RESET RC0
    unsigned char LCD_WR;
    #define LCD_WR RC1
    unsigned char LCD_CS;
    #define LCD_CS RC2

    //-------------------------------颜色定义---------------------------------//
    #define     RED          0XF800          //红色
    #define     GREEN        0X07E0          //绿色
    #define     BLUE         0X001F          //蓝色
    #define     WHITE        0XFFFF          //白色

    /******************************************************************************
          函数说明:IO初始化函数
          入口数据:无
          返回值:  无
    ******************************************************************************/
    void Initial_IO()
    {
      INTCON=0x00;                  //禁止所有中断

      OPTION_REG=0x00;              //使能弱上拉

      TRISA=0x3F;                   //RA0-RA5设置为输入
      PORTA=0x3F;                   //RA0-RA5高电平
      ANSELA=0x00;                  //RA0-RA2、RA4设置为数字I/O
      WPUA=0x3F;                    //RA0-RA5使能上拉

      TRISB=0xB0;                   //RB4、RB5、RB7设置为输入,RB6(SCK)设置为输出
      PORTB=0xF0;                   //RB4-RB7高电平
      ANSELB=0x00;                  //RB4-RB5设置为数字I/O
      WPUB=0xF0;                    //RB4-RB7使能上拉


      TRISC=0x00;                   //RC0-RC7设置为输出
      PORTC=0xFF;                   //RC0-RC7高电平
      ANSELC=0x00;                  //RC0-RC3、RC6-RC7设置为数字I/O

    }

    /******************************************************************************
          函数说明:SPI初始化函数
          入口数据:无
          返回值:  无
    ******************************************************************************/
    void Initial_SPI()
    {
        SSP1STAT=0xC0;             //CKE=1 时钟状态从有效转换到空闲时发送
        SSP1CON1=0X30;            //主控方式,Fosc/4,CKP=1空闲时钟电平为高,SSPEN=1使能同步串行功能

    //    SSP1STAT=0x80;             //CKE=0 时钟状态从空闲转换到有效时发送
    //    SSP1CON1=0X20;             //主控方式,Fosc/4,CKP=0空闲时钟电平为低,SSPEN=1使能同步串行功能

    //    SSP1STAT=0x80;             //CKE=1 时钟状态从空闲转换到有效时发送
    //    SSP1CON1=0X30;            //主控方式,Fosc/4,CKP=1空闲时钟电平为高,SSPEN=1使能同步串行功能


    }

    /******************************************************************************
          函数说明:SPI发送函数
          入口数据:unsigned char data
          返回值:  无
    ******************************************************************************/
    void SPI_RW(unsigned char data)
    {
            SSP1BUF = data;
        do
        {
            ;
        }
        while(!SSP1IF);         //等待产生SSP中断,等待发送完成
        SSP1IF=0;
    }

    /******************************************************************************
          函数说明:LCD写数据函数(8位)
          入口数据:unsigned char val
          返回值:  无
    ******************************************************************************/
    void LCD_WRITE_DATA(unsigned char val)
    {
        LCD_RESET=1;
        LCD_WR=1;
        __delay_ms(1);
        LCD_CS=0;
            SPI_RW(val);
            LCD_CS=1;
    }

    /******************************************************************************
          函数说明:LCD写数据函数(16位)
          入口数据:unsigned int val
          返回值:  无
    ******************************************************************************/
    void LCD_WRITE_16BIT_DATA(unsigned int val)
    {
        LCD_RESET=1;
        LCD_WR=1;
        __delay_ms(1);
        LCD_CS=0;
            SPI_RW(val>>8);
            SPI_RW(val);
            LCD_CS=1;
    }

    /******************************************************************************
          函数说明:LCD写指令函数
          入口数据:unsigned char reg
          返回值:  无
    ******************************************************************************/
    void LCD_WRITE_COMMAND(unsigned char reg)
    {
        LCD_RESET=1;
        LCD_WR=0;
        __delay_ms(1);
        LCD_CS=0;
            SPI_RW(reg);
            LCD_CS=1;
    }

    /******************************************************************************
          函数说明:LCD初始化函数
          入口数据:无
          返回值:  无
    ******************************************************************************/
    void Initial_LCD()
    {
        LCD_RESET=0;
            __delay_ms(100);
            LCD_RESET=1;
            __delay_ms(200);

            LCD_WRITE_COMMAND(0x11);        //唤醒
            __delay_ms(120);               

    //--------------------------显示和颜色格式设置-------------------------------//
            LCD_WRITE_COMMAND(0x36);    //内存数据访问控制(P215)
            LCD_WRITE_DATA(0x00);      
            LCD_WRITE_COMMAND(0x3A);    //接口像素格式
            LCD_WRITE_DATA(0x05);      
    //-------------------------------帧速率设置----------------------------------//
            LCD_WRITE_COMMAND(0xB2);        //门廊控制
            LCD_WRITE_DATA(0x0C);
            LCD_WRITE_DATA(0x0C);
            LCD_WRITE_DATA(0x00);
            LCD_WRITE_DATA(0x33);
            LCD_WRITE_DATA(0x33);
            LCD_WRITE_COMMAND(0xB7);        //门控制
            LCD_WRITE_DATA(0x35);
    //------------------------------电源设置-------------------------------------//
            LCD_WRITE_COMMAND(0xBB);        //VCOMS设置
            LCD_WRITE_DATA(0x28);
            LCD_WRITE_COMMAND(0xC0);        //LCM控制
            LCD_WRITE_DATA(0x2C);
            LCD_WRITE_COMMAND(0xC2);        //VDV和VRH命令使能
            LCD_WRITE_DATA(0x01);
            LCD_WRITE_COMMAND(0xC3);        //VRH设置
            LCD_WRITE_DATA(0x0B);
            LCD_WRITE_COMMAND(0xC4);        //VDV设置
            LCD_WRITE_DATA(0x20);
            LCD_WRITE_COMMAND(0xC6);        //正常模式下的帧速率控制
            LCD_WRITE_DATA(0x0F);
            LCD_WRITE_COMMAND(0xD0);        //电源控制1
            LCD_WRITE_DATA(0xA4);
            LCD_WRITE_DATA(0xA1);
    //--------------------------------Gamma设置-----------------------------------//
            LCD_WRITE_COMMAND(0xE0);        //正电压Gamma控制
            LCD_WRITE_DATA(0xD0);
            LCD_WRITE_DATA(0x01);
            LCD_WRITE_DATA(0x08);
            LCD_WRITE_DATA(0x0F);
            LCD_WRITE_DATA(0x11);
            LCD_WRITE_DATA(0x2A);
            LCD_WRITE_DATA(0x36);
            LCD_WRITE_DATA(0x55);
            LCD_WRITE_DATA(0x44);
            LCD_WRITE_DATA(0x3A);
            LCD_WRITE_DATA(0x0B);
            LCD_WRITE_DATA(0x06);
            LCD_WRITE_DATA(0x11);
            LCD_WRITE_DATA(0x20);
            
        LCD_WRITE_COMMAND(0xE1);        //负电压Gamma控制
            LCD_WRITE_DATA(0xD0);
            LCD_WRITE_DATA(0x02);
            LCD_WRITE_DATA(0x07);
            LCD_WRITE_DATA(0x0A);
            LCD_WRITE_DATA(0x0B);
            LCD_WRITE_DATA(0x18);
            LCD_WRITE_DATA(0x34);
            LCD_WRITE_DATA(0x43);
            LCD_WRITE_DATA(0x4A);
            LCD_WRITE_DATA(0x2B);
            LCD_WRITE_DATA(0x1B);
            LCD_WRITE_DATA(0x1C);
            LCD_WRITE_DATA(0x22);
            LCD_WRITE_DATA(0x1F);
            LCD_WRITE_COMMAND(0x29);        //开显示
            LCD_WRITE_COMMAND(0x2C);        //写存储
    }

    /******************************************************************************
          函数说明:LCD区域设置函数
          入口数据:unsigned int stx
                    unsigned int sty
                    unsigned int endx
                    unsigned int endy
          返回值:  无
    ******************************************************************************/
    void LCD_SetArea(unsigned int stx,unsigned int sty,unsigned int endx,unsigned int endy)
    {
            LCD_WRITE_COMMAND(0x2A);        //列地址设置
            LCD_WRITE_16BIT_DATA(stx);               
            LCD_WRITE_16BIT_DATA(endx);         

            LCD_WRITE_COMMAND(0x2B);        //行地址设置
            LCD_WRITE_16BIT_DATA(sty);               
            LCD_WRITE_16BIT_DATA(endy);         
    }

    /******************************************************************************
          函数说明:LCD颜色设置函数
          入口数据:unsigned int color
          返回值:  无
    ******************************************************************************/
    void LCD_WRITE_ColorData(unsigned int color)
    {
        LCD_WRITE_16BIT_DATA(color);
    }

    /******************************************************************************
          函数说明:LCD清屏函数
          入口数据:unsigned int color
          返回值:  无
    ******************************************************************************/
    void LCD_Clear(unsigned int color)
    {  
            unsigned int i,j;

            LCD_SetArea(0,0,239,319);
        LCD_WRITE_COMMAND(0x2C);        //写存储
            for(i=0;i<320;i++)
            {
                    for(j=0;j<240;j++)
                    {
                            LCD_WRITE_ColorData(color);
                    }
            }
    }

    /******************************************************************************
          函数说明:主函数
    ******************************************************************************/
    void main()
    {
        Initial_IO();
        Initial_SPI();
            Initial_LCD();
    //        LCD_WRITE_COMMAND(0x28);
            while(1)
            {
    //                LCD_Clear(WHITE);
    //                __delay_ms(10);
                    LCD_Clear(RED);
    //                __delay_ms(100);
    //                LCD_Clear(BLUE);
    //                __delay_ms(100);
    //                LCD_Clear(GREEN);
    //                __delay_ms(100);

            }
    }

您需要登录后才可以回复 登录 | 注册