找回密码
 立即注册
查看: 88|回复: 7

用STC32G12K128驱动320240LCD,RA8806芯片,总是有雪花点,还会死机

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 2026-2-7 13:25:44 | 显示全部楼层 |阅读模式
下面是RA8806的驱动,奇怪的是 Readreg()函数,RA8806按说明,BRD=0 应该放在dat = DATA_BUS;前面
可是就没有图像显示,放在后面却显示图像了
//== RA8806.c   ===========================================================
#include "STC32G.h"
#include "delay.h"
#include "stdio.h"
#include "intrins.h"
#include "RA8806.h"
#include "NtGUI.h"

extern void delay_ms(unsigned int MS);

//写命令
//写完命令后片选仍为0!BRS仍保留状态!而BWR回复到1!
//在执行完此函数后,可以:
//1.后跟LCD_DataWrite(unsigned char DataByte),BRS=0,BWR=0>>1,写DataByt到CommandByte(reg#)。
//2.后跟LCD_DataRea(),BRS=0,BRD=0>>1,读CommandByte(reg#)中的数据。
void LCD_CmdWrite(unsigned char CommandByte)
{
        BRD = 1;
  BCS = 0;        //写完命令后片选仍为0!
  BRS = 1;        //寄存器操作       
  BWR = 0;
        DATA_BUS = CommandByte;         
        delay_us(2);
  BWR = 1;
  DATA_BUS = 0xff;
        BCS = 1;
}

//写数据
void LCD_DataWrite(unsigned char DataByte)
{
  BRS = 0;                //数据操作
        BCS = 0;
        BWR = 0;
        DATA_BUS = DataByte;       
        delay_us(2);
  BWR = 1;
  BCS = 1;
  DATA_BUS = 0xff;
}

//读寄存器数据
unsigned char LCD_DataRead(void)
{
        unsigned char dat;
  BRS = 0;                                                                //对寄存器操作
  BCS = 0;
        DATA_BUS = 0xff;                                //数据端口应为开漏加上拉电阻
  BRD = 0;
        dat = DATA_BUS;
        //BRD = 0;                                                                //源程序此句在dat = DATA_BUS;上面
        delay_us(2);
  BRD = 1;
  BCS = 1;
  return dat;
}

//写指令: LCD_CmdWrite(CmdByte) & LCD_DataWrite(DataByte) 组合
void WriteCommand(unsigned char CommandReg,unsigned char CommandByte)
{
  BRD = 1;
  BRS = 1;                //寄存器操作
        BCS = 0;
        BWR = 0;
        DATA_BUS = CommandReg;       
        delay_us(2);
  BWR = 1;
       
  BRS = 0;                //数据操作  
        BWR = 0;
        DATA_BUS = CommandByte;
        delay_us(2);
  BWR = 1;
  BCS = 1;
  DATA_BUS = 0xff;
}
//LCD_CmdWrite(CmdByte) & LCD_DataRead()组合
//读寄存器:
unsigned char Readreg(unsigned char CommandReg)
{
  unsigned char dat;
  BCS = 0;                //CS=0
  BRS = 1;                //寄存器操作-指定寄存器
        BWR = 0;
        DATA_BUS = CommandReg;               
  BWR = 1;       
        BCS = 1;
        delay_us(15);
       
  BRS = 0;                //读出寄存器的内容
        BCS = 0;
        DATA_BUS = 0xff;
        //BRD = 0;
        dat = DATA_BUS;       
        BRD = 0;                         //源程序此句应该在dat = DATA_BUS前面
  BRD = 1;
  BCS = 1;                //CS=1
  return dat;
}

//等于LCD_CmdRead()
unsigned char Read_status(void)
{
  unsigned char dat;
  BWR = 1;
  BRS = 1;                                                                //对寄存器操作,但此时不会去读CommandByte内的数据,而是去读ststus
  BCS = 0;
        DATA_BUS = 0xff;                                //数据端口应为开漏加上拉电阻
       
        BRD = 0;
        dat = DATA_BUS;
        delay_us(2);
  BRD = 1;
  BCS = 1;
  return dat;
}

//读内存,此命令是应跟在写命令B1后面,连续读内存,用到结束应将CS=1
unsigned char LCD_DDRamRead(void)
{
        unsigned char dat;
  BRS = 1;                                                                //对寄存器操作
        BCS = 0;
  DATA_BUS = 0xff;                                //数据端口应为开漏加上拉电阻

        BRD = 0;
        dat = DATA_BUS;
  BRD = 1;
  return dat;                                                        //
}

//读命令数据
unsigned char LCD_CmdRead(void)
{
        unsigned char dat;
  BRS = 1;                                                                //对寄存器操作
        BCS = 0;
  DATA_BUS = 0xff;                                //数据端口应为开漏加上拉电阻

        BRD = 0;
        dat = DATA_BUS;
        delay_us(1);
  BRD = 1;
        BCS = 1;
  return dat;                                                        //
}

void CheckBusy(void)
{
  unsigned char temp;
  do
  {
          temp=LCD_DataRead();
  }
  while(temp & 0x80);
}


void LCD_Graphic(void)
{
  unsigned char temp;
  temp = Readreg(0x00);
  temp &= 0xf7;
  WriteCommand(0x00,temp);
       
//        unsigned char temp;
//        //No_Snow_Mode();
//        LCD_CmdWrite(0x00);
//        temp = LCD_DataRead();
//        temp &= cClrb3;
//        LCD_CmdWrite(0x00);
//        LCD_DataWrite(temp);                        //如果LCD_DataRead()执行后RCS=1片选关闭,则此句前要加LCD_CmdWrite(0x00);
}

void LCD_Text(void)
{
  unsigned char temp;
  temp = Readreg(0x00);
  temp |= 0x08;
  WriteCommand(0x00,temp);
}

void LCD_on(void)
{
  unsigned char temp;
  temp = Readreg(0x00);
  temp |= 0x04;
  WriteCommand(0x00,temp);
}


//== RA8806.h ========================================================
#ifndef _RA8806_H
#define _RA8806_H

#include "STC32G.h"
#include "def.h"
#include "config.h"


/****************************** 用户定义宏 ***********************************/
sbit    BRS = P4^5;  //定义引脚
sbit    BWR = P4^2;  //9.5版本之前实验箱需要将P42与P44对调才能正常使用
sbit    BRD = P4^4;
sbit                BCS = P4^3;                //CS1
//sbit  PSB = P3^5;      //PSB脚为12864的串、并通讯功能切换,我们使用8位并行接口,PSB=1  320240:CS2
sbit    bRST   =   P3^4;   //  17---RESET  L-->Enable
sbit                P6pullup = P4^0;         //实验箱中给P6端口通过LED4,LED12-LED17加上拉
#define DATA_BUS P6

//#define Busy    0x80 //用于检测LCD状态字中的Busy标识
/*****************************************************************************/

//定义RA8806寄存器
#define WLCR                0x00
#define MISC                0x01
#define ADSR                0x03
#define INTR                0x0F
#define WCCR                0x10
#define CHWI            0x11                                               
#define MAMR                0x12
#define AWRR                0x20
#define DWWR                0x21
#define AWBR                0x30
#define DWHR                0x31                                               
#define AWLR                0x40
#define AWTR                0x50
#define CURX                0x60                                               
#define BGSG                0x61
#define EDSG            0x62                                               
#define CURY                0x70                                                 
#define BGCM                0x71
#define EDCM                0x72
#define BTMR                0x80
#define ITCR                0x90                                               
#define KSCR1                0xA0
#define KSCR2            0xA1
#define KSDR0          0xA2                                               
#define KSDR1          0xA3
#define KSDR2          0xA4
#define MWCR                0xB0                                               
#define MRCR                0xB1                                                 
#define TPCR1                0xC0
#define TPXR                0xC1
#define TPYR                0xC2
#define TPZR                0xC3
#define TPCR2      0xC4
#define PCR             0xD0                                               
#define PDCR            0xD1                                               
#define PNTR                0xE0
#define FNCR                0xF0
#define FVHT                0xF1

/**********************************************************/
#define        cSetb0                0x01
#define        cSetb1                0x02
#define        cSetb2                0x04
#define        cSetb3                0x08
#define        cSetb4                0x10
#define        cSetb5                0x20
#define        cSetb6                0x40
#define        cSetb7                0x80

#define        cClrb0                0xfe
#define        cClrb1                0xfd
#define        cClrb2                0xfb
#define        cClrb3                0xf7
#define        cClrb4                0xef
#define        cClrb5                0xdf
#define        cClrb6                0xbf
#define        cClrb7                0x7f

void Init_Device(void);
void LCD_CmdWrite(unsigned char CommandByte);
void LCD_DataWrite(unsigned char DataByte);
unsigned char LCD_CmdRead(void);
unsigned char LCD_DataRead(void);
unsigned char LCD_DDRamRead(void);
void WriteCommand(unsigned char CommandReg,unsigned char CommandByte);
unsigned char Readreg(unsigned char CommandReg);
unsigned char Read_status(void);
void CheckBusy(void);
void LCD_CheckScanBusy(void);
void LCD_Graphic(void);
void LCD_Text(void);
void LCD_on(void);
void LCD_Clear(void);                                //unsigned char y
void LCD_Rotate90(void);
void LCD_Rotate90_Disable(void);
void Reverse_Data(void);
void Display_Window_Size(unsigned char DW_Width, unsigned char DW_Height);
void LocateXY(unsigned char x,unsigned char y);
void LCD_GotoXY(unsigned char x, unsigned char y);
void LcdInit(void);
void Test_Display(void);
void PutBMP(unsigned char *puts);
void w_dot(unsigned char x1,unsigned char x2);
void LCD_DataWritetocmd(unsigned char CmdReg,unsigned char udata);  ///写数据到到寄存器
//============================Reg[00h]
void SleepWakeup(void);
void LCD_SleepMode(void);
void LCD_Graphic(void);
void LCD_Text(void);
void LCD_ON(void);
void LCD_OFF(void);
void LCD_NoBlink(void);
void LCD_Blink(void);
//=============================Reg[01h]
void No_Snow_Mode(void);
void Snow_Mode(void);
//=============================Reg[03h]
void Scroll_Disable(void);
//=============================Reg[0fh]
void Clr_KeyScan_INT_Flag(void);
unsigned char Get_Key(void);
unsigned char Touch_Status(void);
void clear_TP_interrupt(void);
//=============================Reg[10h]
void LCD_AlignOn(void);
void LCD_AlignOff(void);
void LCD_Bold_Font(void);
void LCD_No_Bold_Font(void);
//=============================Reg[12h]
void Gray_Mode(void);
void Only_Show_Page2(void);               
void Only_Show_Page1(void);
void Show_Two_Layer(void);
void Two_Layer_OR(void);
void Two_Layer_XOR(void);
void Two_Layer_NOR(void);
void Two_Layer_AND(void);
void Access_CGRAM(void);
void Access_Page2(void);                       
void Access_Page1(void);
void Access_2Page(void);
//====================================================Reg[20h,30h,40h,50h]
void Set_Active_Window_Size(unsigned char, unsigned char, unsigned char, unsigned char);
//====================================================Reg[21h,31h]
void Set_Display_Window_Size(unsigned char, unsigned char);       
//==================================================Reg[60h,70h]
void LCD_GotoXY(unsigned char, unsigned char);
//===========================================================Reg[61h,62h,71h,72h]
void Set_Scroll_Window_Size(unsigned char seg_start, unsigned char seg_end, unsigned char com_start, unsigned char com_end);
//===================================Reg[A0h,A1h]
void Enable_KeyScan(void);
void Enable_LongKey(void);
void Enable_KeyScan_WakeUp(void);
//===================================Reg[C0h]
void Enable_Touch(void);
void Enable_Touch_WakeUp(void);
//===================================Reg[C1,C2,C3]
unsigned char ADC_Y(void);
unsigned char ADC_X(void);
unsigned char ADC_XY(void);
//===================================Reg[E0h]
void LCD_Clear(void);
//===================================Reg[F0h]
void Fill_PNTR_to_DPRAM(void);
void ASCII_Block_1(void);
void ASCII_Block_2(void);
void ASCII_Block_3(void);
void ASCII_Block_4(void);
//===================================Reg[F1h]
void LCD_FontSize(unsigned char);

void LCD_FontSizeNormal(void);
void LCD_FontSizeTwoTimes(void);
void LCD_FontSizeThreeTimes(void);
void LCD_FontSizeFourTimes(void);
//===================================other

void LCD_ShowStr(char *text,unsigned int t);

//=============================================================================
//general mono stn lcd driver for ra8806
//=============================================================================
void LCD_SoftwareClear(unsigned char BlackOrWhite);
void LCD_DrawPoint(unsigned int x,unsigned int y,unsigned char BlackOrWhite);
void LCD_DrawHorizontalLine(unsigned int x0,unsigned int y,unsigned int x1,unsigned char BlackOrWhite);
void LCD_DrawVerticalLine(unsigned int x,unsigned int y0,unsigned int y1,unsigned char BlackOrWhite);
void LCD_DrawLine(unsigned int x0,unsigned int y0,unsigned int x1,unsigned int y1,unsigned char BlackOrWhite);       
void LCD_DrawRectangle(unsigned int x0,unsigned int y0,unsigned int x1,unsigned int y1,unsigned char BlackOrWhite);
void LCD_DrawRectangleFill(unsigned int x0,unsigned int y0,unsigned int x1,unsigned int y1,unsigned char BlackOrWhite);
void LCD_DrawCircle(unsigned int x0,unsigned int y0,unsigned char Radius,unsigned char BlackOrWhite);
void LCD_DrawCircleFill(unsigned int x0,unsigned int y0,unsigned char Radius,unsigned char BlackOrWhite);

void LCD_Draw_Picture(unsigned int x0,unsigned int y0,unsigned int width,unsigned int height,const unsigned char *picdata);                       
void LCD_Draw_ReversePicture(unsigned int x0,unsigned int y0,unsigned int width,unsigned int height,const unsigned char *picdata);

void LCD_PutInternalString(char *text,unsigned int t);
void LCD_PutReverseInternalString(char *text,unsigned int t);

//add by njj 2016.12.02
void LCD_CursorControl(unsigned char turn);

#endif


//== main.c =====================================================
//<<AICUBE_USER_HEADER_REMARK_BEGIN>>
////////////////////////////////////////
// 在此添加用户文件头说明信息  
// 文件名称: main.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2026-01-18) 创建文件
////////////////////////////////////////
//<<AICUBE_USER_HEADER_REMARK_END>>


#include "config.h"                     //默认已包含stdio.h、intrins.h等头文件


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含
#include "delay.h"
#include "RA8806.h"
#include "NtGUI.h"
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明
extern void Tab0(void);
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// 项目主函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void main(void)
{
    //<<AICUBE_USER_MAIN_INITIAL_BEGIN>>
    // 在此添加用户主函数初始化代码  
    //<<AICUBE_USER_MAIN_INITIAL_END>>

    SYS_Init();
                //Init_Device();
    //<<AICUBE_USER_MAIN_CODE_BEGIN>>
    // 在此添加主函数中运行一次的用户代码  
          BCS =1;
                P6pullup = 0;        //P6上拉
                delay_ms(10);        //10

                //9.初始化GUI
                NT_GUIInit();
          delay_ms(3000);
               
                //18.显示Tab界面
          NT_TabCardInit();
    //<<AICUBE_USER_MAIN_CODE_END>>

    while (1)
    {
        //USBLIB_OUT_Done();              //查询方式处理USB接收的数据
                                _nop_();
        //<<AICUBE_USER_MAIN_LOOP_BEGIN>>
        // 在此添加主函数中用户主循环代码  
        //<<AICUBE_USER_MAIN_LOOP_END>>
    }
}

////////////////////////////////////////
// 系统初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void SYS_Init(void)
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基

    //<<AICUBE_USER_PREINITIAL_CODE_BEGIN>>
    // 在此添加用户预初始化代码  
    //<<AICUBE_USER_PREINITIAL_CODE_END>>

    PORT3_Init();                       //P3口初始化
    PORT4_Init();                       //P4口初始化
    PORT6_Init();                       //P6口初始化
    delay_ms(1);
//    USBLIB_Init();                      //USB库初始化
    delay_ms(1);

    //<<AICUBE_USER_INITIAL_CODE_BEGIN>>
    // 在此添加用户初始化代码  
    //<<AICUBE_USER_INITIAL_CODE_END>>

    EnableGlobalInt();                  //使能全局中断
}





//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码  
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:417
  • 最近打卡:2026-03-07 11:27:49

12

主题

541

回帖

1260

积分

金牌会员

积分
1260
发表于 3 天前 | 显示全部楼层
云里雾里的头晕
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 前天 18:21 | 显示全部楼层
搞定了, LCD供应商提供的例程不对, 仔细核对了RA8806说明书,修正了BRS,BWR,BRD时序,显示正常,雪花也没有了
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 前天 18:38 | 显示全部楼层
新问题: 按STC实验箱提供的RTC例程,
void RTC_config(void)
{
    INIYEAR = 24;     //Y:2021
    INIMONTH = 02;    //M:12
    INIDAY = 14;      //D:31
    INIHOUR = 15;     //H:23
    INIMIN = 43;      //M:59
    INISEC = 50;      //S:50
    INISSEC = 0;      //S/128:0

    ALAHOUR = 0;        //闹钟小时
    ALAMIN  = 0;        //闹钟分钟
    ALASEC  = 0;        //闹钟秒
    ALASSEC = 0;        //闹钟1/128秒

    //STC32G 芯片使用内部32K时钟,休眠无法唤醒
//    IRC32KCR = 0x80;   //启动内部32K晶振.
//    while (!(IRC32KCR & 1));  //等待时钟稳定
//    RTCCFG = 0x03;    //选择内部32K时钟源,触发RTC寄存器初始化

    X32KCR = 0x80 + 0x40;   //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
    while (!(X32KCR & 1));  //等待时钟稳定
    RTCCFG = 0x01;    //选择外部32K时钟源,触发RTC寄存器初始化

    RTCIF = 0x00;     //清中断标志
    RTCIEN = 0x88;    //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
    RTCCR = 0x01;     //RTC使能

    while(RTCCFG & 0x01);        //等待初始化完成,需要在 "RTC使能" 之后判断.
    //设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
    //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
}
执行完后,后续程序里的 延时函数
void delay_us(uint16_t us)
{
    do
    {
        NOP(18);              //(MAIN_Fosc + 500000) / 1000000 - 6
    } while (--us);
}
就无法运行,执行就死机
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 前天 21:19 | 显示全部楼层
可能是内存堆栈分配问题, LCD显示有一幅静态320240图片,9600字节
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 前天 21:23 | 显示全部楼层
试过在实验箱例程中加delay_us(u16 us)完全没问题, 在出问题的程序前半部分用delay_us(u16 us)也没问题
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:29
  • 最近打卡:2026-03-06 06:05:49

24

主题

127

回帖

582

积分

高级会员

积分
582
发表于 昨天 14:38 | 显示全部楼层
这么老的方案还在用?这个芯片查了一下,不便宜啊,简单的应用就用STC32G144k246直接驱动,复杂一点的用LT7850,比用8806便宜多了。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2026-03-06 21:51:37
已绑定手机

2

主题

9

回帖

30

积分

新手上路

积分
30
发表于 昨天 21:51 | 显示全部楼层
深山*** 发表于 2026-3-6 14:38
这么老的方案还在用?这个芯片查了一下,不便宜啊,简单的应用就用STC32G144k246直接驱动,复杂一点的用LT7 ...

原产品指定用的。 STM32F407驱动,要求换用国产芯片。
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-7 13:23 , Processed in 0.109956 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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