请教ST7920控制器的液晶串口驱动,我这里怎么弄都乱码

2020-01-25 15:28发布

本帖最后由 lswhome 于 2013-12-12 11:33 编辑

如题,调试了一个晚上了,死活就是不行,源代码贴出来了

//------- IO口 -------
sbit        ST7920_CS=P1^5;//片选(RS)
sbit        ST7920_SDA=P1^7;//数据端口(SID)
sbit        ST7920_SCL=P1^6;//数据的时钟线
sbit        ST7920_RST=P1^3;//复位
sbit        lig=P1^0;

//---- 函数定义 ----
//---- [基础函数] ----
void        ST7920_Send_Data(UINT8 Data);//串行写入数据
UINT8        ST7920_Read_Data(void);//串行读出数据
bit                ST7920_Check_Busy(void);//判断是否繁忙,返回1=繁忙,返回0=空闲
void        ST7920_Write_Cmd(UINT8 Cmd);//写入命令
void        ST7920_Write_Data(UINT8 Data);//写入数据
UINT8        ST7920_Get_Data(void);//读取数据
void        ST7920_Delay(UINT16 us);//延时
void        ST7920_Init(void);//初始化

//---- [图形函数]
//在任意位置(并非真正意义上的任意位置,必须对应ST7920上对应的大列)画一个BMP图片,y,x=起始的坐标,bmp_x,bmp_y=图片的大小,*bmp指向一个图片的指针,flag=1反相显示,=0正常显示
void        ST7920_Draw_Bmp(UINT8 y,UINT8 x,UINT8 bmp_x,UINT8 bmp_y,UINT8 *bmp,bit flag);

//----------------------------------------------------------------------------------------------------------------
void        ST7920_Send_Data(UINT8 Data)//串行写入数据
{
        UINT8 i;
        for(i=0;i<8;i++)
        {
               
               
                ST7920_SCL=0;//时钟线拉低
                //Data=Data<<1;
                //ST7920_SDA=CY;//写入一位数据
                if(Data&0x80)
                        ST7920_SDA=1;
                else
                        ST7920_SDA=0;

                ST7920_SCL=1;//写入完毕,拉高时钟线
                Data=Data<<1;
                _nop_();_nop_();_nop_();_nop_();
        }
}
//----------------------------------------------------------------------------------------------------------------
UINT8        ST7920_Read_Data(void)//串行读出数据
{
        UINT8 i,t1,t2;
        t1=t2=0;

        for(i=0;i<8;i++)
        {
                //t1<<=1;
                ST7920_SCL=0;//时钟线拉低
                ST7920_SCL=1;//拉高的时候,开始读取数据
                if(ST7920_SDA) t1++;//取得一位1
                t1<<=1;
        }

        for(i=0;i<8;i++)
        {
                //t1<<=1;
                ST7920_SCL=0;//时钟线拉低
                ST7920_SCL=1;//拉高的时候,开始读取数据
                if(ST7920_SDA) t2++;//取得一位1
                t2<<=1;
        }
       
        return(t1&0xf0+t2&0x0f);//返回得到的数据

}
//----------------------------------------------------------------------------------------------------------------
bit                ST7920_Check_Busy(void)//判断是否繁忙,返回1=繁忙,返回0=空闲
{
        UINT8 tmp;
        ST7920_Send_Data(0xfc);//11111,RW(1),RS(0),0
        tmp=ST7920_Read_Data();

        if(tmp>0x7f)
                return(1);
        else
                return(0);
}
//----------------------------------------------------------------------------------------------------------------
void        ST7920_Write_Cmd(UINT8 Cmd)//写入命令
{
        ST7920_CS=1;
       
        //while(ST7920_Check_Busy());//判断是否繁忙
        ST7920_Delay(50);
        ST7920_Send_Data(0xf8);//11111,RW(0),RS(0),0
       
        ST7920_Send_Data(Cmd&0xf0);//高4位
        ST7920_Send_Data(Cmd<<4);//低4位
        ST7920_CS=0;
        //ST7920_Delay(1);
}
//----------------------------------------------------------------------------------------------------------------
void        ST7920_Write_Data(UINT8 Data)//写入数据
{
        ST7920_CS=1;

        //while(ST7920_Check_Busy());//判断是否繁忙
        ST7920_Delay(50);
        ST7920_Send_Data(0xfa);//11111,RW(0),RS(1),0
        ST7920_Send_Data(Data&0xf0);//高4位
        ST7920_Send_Data(Data<<4);//低4位
        ST7920_CS=0;
        //ST7920_Delay(1);
}
//----------------------------------------------------------------------------------------------------------------
UINT8        St7920_Get_Data(void)//读取数据
{
        ST7920_CS=1;
        ST7920_Delay(10);
        //while(ST7920_Check_Busy());//判断是否繁忙
        ST7920_Delay(20);
        ST7920_Send_Data(0xfe);//11111,RW(1),RS(1),0
        ST7920_CS=0;
        return(ST7920_Read_Data());//读取数据并返回
}
//----------------------------------------------------------------------------------------------------------------
void        ST7920_Delay(UINT16 us)//延时
{
        while(--us);
}
//----------------------------------------------------------------------------------------------------------------
void        ST7920_Init(void)//初始化
{       
        ST7920_Delay(10);
        ST7920_RST=0;
        ST7920_Delay(20);
        ST7920_RST=1;
        ST7920_Delay(20);
        ST7920_Write_Cmd(0x30);//8位模式,基本指令集
        ST7920_Write_Cmd(0x01);//清屏
        ST7920_Write_Cmd(0x06);//地址计数器自动+1
        ST7920_Write_Cmd(0x0C);//开显示

        ST7920_Write_Cmd(0x34);//扩展指令
        ST7920_Write_Cmd(0x36);//启动图形模式



        //ST7920_Write_Cmd(0x80);
        //ST7920_Write_Data(0x74);
}
//----------------------------------------------------------------------------------------------------------------
//在任意位置()画一个BMP图片,y,x=起始的坐标,bmp_x,bmp_y=图片的大小,*bmp指向一个图片的指针,flag=1反相显示,=0正常显示
void        ST7920_Draw_Bmp(UINT8 y,UINT8 x,UINT8 bmp_x,UINT8 bmp_y,UINT8 *bmp,bit flag)
{
//                x=横向坐标
//                y=纵向坐标       



        UINT8 xdata i,addr_x,addr_y;

        bmp_y+=y;//图片的最低端在屏幕上的绝对地址
       
        for(;y<bmp_y;y++)
        {
                if(y<32)//如果在上半屏
                {
                        addr_x=x;
                        addr_y=y;
                }
                else
                {
                        addr_x=x+8;//下半屏的X地址比上半屏多8列
                        addr_y=y-32;//下半屏的Y地址与上半屏相等
                }
                ST7920_Write_Cmd(0x80+addr_y);//先下Y地址
                ST7920_Write_Cmd(0x80+addr_x);//再写X地址
                //ST7920_CS=1;
                for(i=x;i<bmp_x;i++)
                {
                        ST7920_Write_Data(flag?~*bmp++:*bmp++);//flag=1反相显示
                        ST7920_Write_Data(flag?~*bmp++:*bmp++);//flag=1反相显示
                }
                //ST7920_CS=0;
        }
       
        ST7920_Write_Cmd(0x36);
}

void main(void)
{
        ST7920_Init();
        //ST7920_Write_Cmd(0x34);//扩展指令
        ST7920_Draw_Bmp(0,0,8,64,pLogo,0);
        //ST7920_Write_Cmd(0x36);//启动图形模式
       




        while(1);
}

各位高手帮我看看,到底是哪里不对?时序不对吗?字符模式啥也不显示,初始化为图形模式,满屏的乱七八糟的。。。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。