找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1873|回复: 6
打印 上一主题 下一主题
收起左侧

PIC单片机驱动LCD问题,按住PIC单片机的复位键(MCLR 复位)ST7789V才有显示

[复制链接]
跳转到指定楼层
楼主

单片机型号:PIC16F1508
LCD驱动芯片:ST7789V
问题点:用PIC单片机SPI控制LCD(ST7789V),用示波器测量SPI波形是符合ST7789V的时序要求的,但是PIC和LCD连接后,LCD没有任何显示。按住PIC单片机的复位键(MCLR 复位),LCD有显示。
想咨询下各位高手,哪里出问题了?
示波器波形:
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);

        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:992128 发表于 2021-12-14 17:20 | 只看该作者
麻烦各位大佬帮忙分析一下
回复

使用道具 举报

板凳
ID:401564 发表于 2021-12-14 20:28 | 只看该作者
MCLR 是复位引脚
你按下复位才显示,这本身就是问题,正常来说,按复位应该什么都不行的,也不知道你说的显示是不是按下复位就行,还是说按下复位只是亮了而已

1:把电路上传,看一下复位对不对,或者是看一下你自己焊得对不对
2:PIC的端口是有优先等级的,SPI部分是有最优等级,不用设置
这三个端口要设置的
RC0                       RESET(P15)
  RC1                       WR(P11)
  RC2                       CS(P9)
比如RC0,要把CLC2这个功能关闭了,才能轮到端口
RC1就要先关闭NCO1 (2)和PWM4,才作为端口
回复

使用道具 举报

地板
ID:992336 发表于 2021-12-14 23:31 | 只看该作者
按下复位单片机不工作却显示,说明之前写到st7789v里的数据有用了。
可能是无限清屏造成的,试试主程序里增加100ms延时
回复

使用道具 举报

5#
ID:992128 发表于 2021-12-15 10:28 | 只看该作者
Y_G_G 发表于 2021-12-14 20:28
MCLR 是复位引脚
你按下复位才显示,这本身就是问题,正常来说,按复位应该什么都不行的,也不知道你说的显示 ...

按住单片机复位键,LCD是全屏显示红色(调试的时候只让它刷红色),松开复位键,就只剩背光了,上传了视频。
1、上传了单片机的电路图,MCLR复位在其他项目中使用是正常的。
2、RC0关闭CLC2,RC1关闭NCO1和PWM4在调试时试过,没有解决问题。而且程序里不单独去关闭,用示波器测出的波形也是符合设定要求的,所以在贴出的程序里把这个删除了。

PIC16F1508最小系统_V1.1.jpg (329.3 KB, 下载次数: 37)

原理图

原理图

视频.rar

2.75 MB, 下载次数: 7

回复

使用道具 举报

6#
ID:992128 发表于 2021-12-15 10:47 | 只看该作者
0x0A 发表于 2021-12-14 23:31
按下复位单片机不工作却显示,说明之前写到st7789v里的数据有用了。
可能是无限清屏造成的,试试主程序里 ...

"按下复位单片机不工作却显示,说明之前写到st7789v里的数据有用了。"
是的,我觉得数据是有传输到st7789V,只是因为某种原因无法显示,当复位时单片机停止工作,st7789V就可以正常显示了。
您说可能是无限清屏造成的,我这边加延时调试了下,也没效果。
根据您给的思路,我改了下PIC内部振荡器的频率,发现500KHz时,按住复位键,LCD显示全屏红色(调试只让显示红色),4MHz时,按住复位键,LCD上边显示红色,下边是麻点
回复

使用道具 举报

7#
ID:401564 发表于 2021-12-15 12:50 | 只看该作者
hanyao 发表于 2021-12-15 10:28
按住单片机复位键,LCD是全屏显示红色(调试的时候只让它刷红色),松开复位键,就只剩背光了,上传了视频 ...

手上没有东西,没法调试,仿真我不会
你可以看一下复位引脚的电压,和元件贴得对不对,
或者是先把MCLR关闭,使能为IO端口,这样就可以排除复位的问题了
对于端口的设置是肯定要的,不管有没有解决问题,PIC端口的优先等级都是存在的,有时不设定也能用,那就是个运气好而已
我用的时候,都是先在IO接一个1K电阻,然后再写一个输出的代码,看一下端口能不能输出自己想要的波形,先把所有端口优先等级解决了,再去调试别的功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表