打印
[PIC®/AVR®/dsPIC®产品]

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

[复制链接]
4819|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hanyao|  楼主 | 2021-12-17 15:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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

使用特权

评论回复
沙发
hanyao|  楼主 | 2021-12-17 15:40 | 只看该作者

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

源代码如下:

/******************************************************************************
  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);

        }
}

使用特权

评论回复
板凳
hanyao|  楼主 | 2021-12-17 15:47 | 只看该作者
示波器波形:
1号探头:SCK时钟
2号探头:SDO,示波器测试时数据是0x33
3号探头:CS片选
4号探头:不用在意,随便接了一个

微信图片_20211217153424.jpg (416.65 KB )

微信图片_20211217153424.jpg

使用特权

评论回复
地板
hu9jj| | 2021-12-18 18:17 | 只看该作者
您是使用硬件SPI并通过MCC配置生成基本代码么?如果是的话,MCC在生成代码时会自动根据主频计算SPI的时序,所以无论您设置的主频多少,其SPI的时序当然的一样的,除非您修改了SPI的传输率。

使用特权

评论回复
5
pzsh| | 2021-12-24 11:15 | 只看该作者
用MCC生成代码试试看

使用特权

评论回复
6
tfqi| | 2022-1-8 10:04 | 只看该作者
更换一下io口的模式

使用特权

评论回复
7
wiba| | 2022-1-8 10:07 | 只看该作者
是不是就是波特率的事情啊

使用特权

评论回复
8
zljiu| | 2022-1-8 10:11 | 只看该作者
波形非常的规整

使用特权

评论回复
9
coshi| | 2022-1-8 10:13 | 只看该作者
为什么我的波形都是杂波呢

使用特权

评论回复
10
aoyi| | 2022-1-8 10:15 | 只看该作者
示波器本身就会带进去干扰

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

0

粉丝