op_zcj 发表于 2012-3-24 16:19:54

有谁用过STC的硬件SPI驱动12864显示自定义字符啊

本帖最后由 op_zcj 于 2012-3-24 17:03 编辑

   我这几天刚学会 并行驱动12864,能显示自带汉字、自定义字符、图片。但是改成硬件SPI后,自定义的字符显示乱码,其他可以。是不是跟硬件SPI的分 高四位 低四位 发送数据有关啊,真心求教啊!
程序如下:
#include <stc12c5a60s2.h>
#include<intrins.h>
//============================================================================================================
#define uint unsigned int
#define uchar unsigned char

//引脚定义
sbit    LCD12864_CS    =P1^4;      // 片选 高电平有效 单片LCD使用时                     可固定高电平
sbit    LCD12864_PSB   =P3^5;      // 低电平时表示用串口驱动,                        可固定低电平
sbit    LCD12864_RES   =P3^6;      // LCD复位,LCD模块自带复位电路。                  可不接

//======================单主单从,查询方式===============================
#define MASTER                  //define:master undefine:slave
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
#define SPIF      0x80      //SPSTAT.7
#define WCOL      0x40      //SPSTAT.6
#define SSIG      0x80      //SPCTL.7
#define SPEN      0x40      //SPCTL.6
#define DORD      0x20      //SPCTL.5
#define MSTR      0x10      //SPCTL.4
#define CPOL      0x08      //SPCTL.3
#define CPHA      0x04      //SPCTL.2
#define SPDHH       0x00      //CPU_CLK/4
#define SPDH      0x01      //CPU_CLK/16
#define SPDL      0x02      //CPU_CLK/64
#define SPDLL       0x03      //CPU_CLK/128
sbit SPISS      =   P1^3;       //SPI slave select, connect to slave' SS(P1.4) pin

void InitSPI()
{
    SPDAT = 0;                  //initial SPI data
    SPSTAT = SPIF | WCOL;       //clear SPI status
#ifdef MASTER
    SPCTL = SPEN | MSTR | CPHA | CPOL | SPDHH; //master mode
#else
    SPCTL = SPEN;               //slave mode
#endif
}
BYTE SPISwap(BYTE dat)
{
#ifdef MASTER
    SPISS = 0;                  //pull low slave SS
#endif
    SPDAT = dat;                //trigger SPI send
    while (!(SPSTAT & SPIF));   //wait send complete
    SPSTAT = SPIF | WCOL;       //clear SPI status
#ifdef MASTER
    SPISS = 1;                  //push high slave SS
#endif
    return SPDAT;               //return received SPI data
}
//=======================以上为硬件SPI程序==================================

uchar code user[]={ //取模方法:从左到右,自上而下

0x0F,0xF0,0x10,0x08,0x20,0x04,0x40,0x02,0x9C,0x39,0xBE,0x7D,0x80,0x01,0x80,0x01,
0x80,0x01,0x88,0x11,0x84,0x21,0x43,0xC2,0x20,0x04,0x10,0x08,0x0F,0xF0,0x00,0x00, //32 笑脸

0x10,0x80,0x08,0x80,0x7E,0xFC,0x24,0x80,0x18,0xFC,0xFF,0x04,0x00,0xFC,0x3E,0x80,
0x22,0xF8,0x3E,0x80,0x22,0xF8,0x3E,0x80,0x22,0xFA,0x22,0x82,0x2A,0x82,0x24,0x7E, //64 繁体中文字“龍”

0x08,0x20,0x1c,0x10,0x1c,0x1c,0xff,0x9e,0x7f,0x1e,0x1c,0x1f,0x3e,0x1f,0x3e,0x1f, //96 一个星星、一个月亮
0x77,0x1f,0x41,0x3f,0x00,0x7e,0x00,0xfe,0x83,0xfc,0x7f,0xf8,0x3f,0xf0,0x0f,0xc0,

0x00,0x39,0x00,0x6A,0x00,0xA8,0x01,0x29,0x7E,0x2A,0xFC,0x28,0xFC,0x29,0xCC,0x2A, //喇叭
0xCC,0x28,0xFC,0x29,0xFC,0x2A,0x7E,0x28,0x01,0x29,0x00,0xAA,0x00,0x68,0x00,0x38,

};

uchar code pic1[]=      // 图片代码
{
/*--调入了一幅图像:C:\Documents and Settings\Administrator\桌面\12864LCD显示的图像.bmp--*/
/*--宽度x高度=128x64--*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x81,0xFF,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xB0,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x6F,0xFF,0xFF,0xFF,0xFF,0x81,0xBF,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xF6,0xC0,
0x7F,0xFF,0xFF,0xFD,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xDC,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xB6,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0x9E,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xFB,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0x81,0xCC,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFE,0x81,0xB8,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0x7E,0x81,0x8C,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xFC,0x81,0xFF,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0xFF,0x3F,0xFC,0x81,0x80,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x00,0x80,0x0C,0x00,
0x7F,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xFF,0x80,0xC0,0x00,0x83,0xFE,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x7F,0x40,0x00,0xC0,0x00,0x80,0xD9,0x80,
0x7F,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x1F,0xC0,0x62,0x00,0x00,0x80,0xDB,0x00,
0x7F,0xFF,0xFE,0xFF,0xF8,0x00,0x00,0x00,0x1F,0xC0,0x6F,0x00,0x00,0x80,0xDE,0xC0,
0x7F,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x1F,0x80,0x6F,0x00,0x00,0x83,0xFD,0x80,
0x7F,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0xCF,0x83,0x0F,0xC0,0x00,0x80,0xDB,0x00,
0x77,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x11,0x0F,0x88,0x7E,0x84,0x00,0x80,0xDE,0x60,
0x7F,0xFF,0xFF,0xFF,0x80,0x00,0x03,0xFC,0x1F,0x88,0xFF,0xF8,0x83,0x80,0xD8,0xC0,
0x7F,0x7F,0xFF,0xFF,0xFF,0xF0,0x07,0xFE,0xC7,0xFB,0xFF,0xFF,0xC1,0x80,0xD9,0x80,
0x7F,0x7F,0xFF,0xFF,0xFF,0xF0,0x07,0xFF,0x03,0xF9,0xFF,0xFF,0x05,0x81,0x9B,0x00,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x03,0xA7,0xFF,0xFF,0xFF,0x1F,0x83,0x1E,0x00,
0x7F,0xFF,0xFF,0xFF,0xE0,0x36,0x03,0xFE,0x37,0xBF,0xFD,0xFF,0xFF,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0xFF,0xA2,0x03,0x7E,0x13,0x3F,0xFF,0xFF,0xFF,0x81,0x86,0x00,
0x7F,0xFF,0xFF,0xFF,0xFF,0x3E,0x00,0x03,0x03,0x4F,0xFF,0xFF,0xFF,0x80,0xFF,0xE0,
0x7F,0xFF,0xFF,0xFF,0xFE,0x1E,0x00,0x00,0x1B,0x0F,0xFF,0xFF,0xFF,0x80,0x30,0x60,
0x7F,0xFF,0xFF,0xFF,0xF8,0x0E,0x00,0x00,0x1A,0x0B,0xFF,0xFF,0x1F,0x83,0x1F,0xC0,
0x7F,0xFF,0xFF,0xFF,0xFC,0x06,0x00,0x00,0x1E,0x0B,0xFF,0xFF,0xFF,0x81,0x86,0x00,
0x7F,0xFF,0xFF,0xFF,0xFC,0x06,0x00,0x00,0x0E,0x0B,0xFF,0xFF,0xFF,0x80,0x3F,0xC0,
0x7F,0xFF,0xFF,0xFF,0xC0,0x06,0x00,0x00,0x02,0x0B,0xF7,0xFF,0xFF,0x80,0xF6,0xC0,
0x7F,0xFF,0xFF,0xFF,0x80,0x06,0x00,0x00,0x02,0x0B,0xE7,0xFF,0xF7,0x81,0xBF,0xC0,
0x7F,0xFF,0xFF,0xFF,0x80,0x06,0x00,0x00,0x02,0x08,0x27,0xFE,0x66,0x83,0xB6,0xC0,
0x7F,0xFF,0xFF,0xFF,0x80,0x1E,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x81,0xBF,0xC0,
0x7F,0xFF,0xFF,0xFF,0x00,0x3E,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x81,0x99,0x80,
0x7F,0xFF,0xFF,0xFF,0x00,0xC4,0x00,0x00,0x02,0x00,0x00,0x07,0xFC,0x81,0xF0,0xE0,
0x7F,0xFF,0xFF,0xFF,0x01,0xC2,0x03,0x00,0x02,0x00,0x20,0x0F,0xCF,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0x81,0xFE,0x08,0x04,0x02,0x03,0x78,0xBB,0x9E,0x80,0x01,0x80,
0x7F,0xFF,0xFE,0xFF,0x80,0xFF,0xC0,0x06,0x06,0x20,0x79,0xA3,0x00,0x80,0xFF,0xC0,
0x7F,0xFF,0xFF,0xFF,0x80,0xFE,0x00,0x03,0x06,0x00,0x71,0x03,0x30,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0x83,0xFC,0x00,0x01,0x06,0x00,0xB0,0x03,0x70,0x80,0x00,0xC0,
0x7F,0xFF,0xFF,0xFF,0x87,0xFC,0x00,0x00,0x06,0x00,0x10,0xB9,0x00,0x81,0xFF,0xE0,
0x7F,0xFF,0xFF,0xF7,0xAF,0xFF,0x0F,0xF0,0x0C,0x08,0x40,0x39,0xE0,0x80,0x0C,0x00,
0x7F,0xFF,0xFF,0xE7,0xAF,0xFF,0x99,0xF8,0x0C,0x08,0x13,0x1B,0xE0,0x80,0x6F,0x00,
0x7F,0xFF,0xFF,0x87,0x8F,0xFF,0xC0,0x18,0x0D,0x00,0x03,0x0B,0x00,0x80,0x6D,0x80,
0x7F,0xFF,0xFF,0x53,0x87,0xE4,0x00,0x10,0x1D,0x00,0x0F,0x34,0x02,0x80,0xCC,0xC0,
0x7F,0xFF,0xFF,0xC1,0x4B,0xE0,0x00,0xE0,0x30,0x00,0x00,0x05,0xC0,0x81,0x8C,0x60,
0x7F,0xFF,0xFF,0xEB,0xE0,0xFE,0x03,0x00,0xE0,0x03,0x87,0x80,0x90,0x83,0x0C,0x60,
0x7F,0xFF,0xFF,0xEB,0xE0,0xFE,0x00,0x00,0xE0,0x03,0x80,0x22,0xD0,0x80,0x1C,0x00,
0x7F,0xFF,0xFF,0xF3,0xF1,0x7E,0x00,0x00,0xE0,0x00,0x07,0x3C,0xF0,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xF0,0x7B,0xBE,0x00,0x01,0xE0,0x00,0x1C,0x3B,0xFC,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xF7,0x7F,0xFC,0x00,0x01,0xE0,0x04,0x1C,0x3B,0xFC,0x80,0x00,0x00,
0x7F,0xFF,0xFD,0xE7,0x7F,0xDC,0x00,0x03,0xC0,0x04,0x10,0x3B,0xF8,0x80,0x00,0x00,
0x7F,0xFF,0xFC,0x75,0x7D,0xF0,0x00,0x03,0x80,0x02,0x00,0xFF,0xD8,0x80,0x00,0x00,
0x7F,0xFF,0xFC,0x07,0x7E,0xF0,0x00,0x07,0x40,0x00,0x00,0x07,0xF8,0x81,0x8C,0x60,
0x7F,0xFF,0xFE,0x03,0xFF,0xE0,0x00,0x0E,0x00,0x03,0x83,0xC7,0xF0,0x82,0x52,0x90,
0x7F,0xFF,0xFE,0x63,0xFF,0xE0,0x00,0x0E,0x18,0x03,0x03,0xC7,0xD0,0x82,0x52,0x90,
0x7F,0xFF,0xFE,0xE3,0xFF,0xE0,0x00,0x0C,0x0C,0x00,0x03,0x4F,0xDA,0x81,0x8C,0x60,
0x7F,0xFF,0xFE,0xE7,0x7F,0xE0,0x00,0x10,0x0C,0x49,0x81,0xCF,0x82,0x80,0x00,0x00,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

};

void delay100us(uchar n)   
{
        uchar a,b;
        while(n--!=0)
        {
    for(b=3;b>0;b--)
      for(a=98;a>0;a--);
        }
}

void delay1s(uchar n)
{
    uchar a,b,c;
        while(n--!=0)
        {
    for(c=71;c>0;c--)
      for(b=168;b>0;b--)
            for(a=250;a>0;a--);
        }
}

/*****************************************************/

void LCD12864_Sendbyte(uchar Byte)
{
    SPISwap(Byte);
}
/******************SPI写指令*************************/

void LCD12864_Write_Cmd(uchar Cbyte )
{
   LCD12864_Sendbyte(0xf8);            //11111,RW(0),RS(0),0
                delay100us(1);

   LCD12864_Sendbyte(0xf0&Cbyte);      //高四位
               delay100us(1);

   LCD12864_Sendbyte(0xf0&Cbyte<<4);   //低四位(先执行<<)
               delay100us(1);
                     
}
/******************SPI写数据*************************/
void LCD12864_Write_Dat(uchar Dbyte )
{
   
   LCD12864_Sendbyte(0xfa);               // 发送起始信号 第1字节-格式:11111010
   delay100us(1);                     

   LCD12864_Sendbyte(0xf0&Dbyte);                  // 发送高四位   第2字节-格式:DDDD0000
   delay100us(1);                     

   LCD12864_Sendbyte(0xf0&Dbyte<<4);                  // 发送低四位   第3字节-格式:0000DDDD
   delay100us(1);                           
}

/********************初始化**************************/

void Init_ST7920()
{
//        delay100us(400);          //大于40MS的延时程序
   LCD12864_PSB=0;               //设置为8BIT 串 口工作模式
        delay100us(1);            //延时
   LCD12864_RES=0;               //复位
        delay100us(1);             //延时
   LCD12864_RES=1;               //复位置高
   LCD12864_CS=1;
        delay100us(1);
   LCD12864_Write_Cmd(0x30);       //选择基本指令集
        delay100us(1);      //延时大于100us
   LCD12864_Write_Cmd(0x30);       //选择8bit数据流
        delay100us(1);         //延时大于37us
   LCD12864_Write_Cmd(0x0c);       //开显示(无游标、不反白)
        delay100us(1);      //延时大于100us
   LCD12864_Write_Cmd(0x01);       //清除显示,并且设定地址指针为00H
        delay100us(100);       //延时大于10ms
   LCD12864_Write_Cmd(0x06);       //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动
        delay100us(1);         //延时大于100us
}
/*------------------------------------------------
               写入用户自定义字符
------------------------------------------------*/
void LCD12864_CGRAM()
{
   uchar i;
   LCD12864_Write_Cmd(0x30);            //选择基本指令集
   LCD12864_Write_Cmd(0x40);
   for(i=0;i<64;i++)
       {
          LCD12864_Write_Dat(user);
      LCD12864_Write_Dat(user);
      }
}   
/*------------------------------------------------
                   显示用户自定义字符
------------------------------------------------*/
void LCD12864_DisplayCGRAM(uchar x,uchar y,uchar z)
{
switch(y)
   {
          case 1: LCD12864_Write_Cmd(0x80+x);break;
          case 2: LCD12864_Write_Cmd(0x90+x);break;
          case 3: LCD12864_Write_Cmd(0x88+x);break;
          case 4: LCD12864_Write_Cmd(0x98+x);break;
      default:break;
       }
    LCD12864_Write_Dat(0x00);
    LCD12864_Write_Dat(z);

}         
/*------------------------------------------------
                   显示字符串
x:横坐标值,范围0~8
y:纵坐标值,范围1~4
------------------------------------------------*/
void LCD12864_PutString(uchar x,uchar y,uchar code *s)
{
switch(y)
   {
          case 1: LCD12864_Write_Cmd(0x80+x);break;
          case 2: LCD12864_Write_Cmd(0x90+x);break;
          case 3: LCD12864_Write_Cmd(0x88+x);break;
          case 4: LCD12864_Write_Cmd(0x98+x);break;
      default:break;
       }
while(*s>0)
   {
      LCD12864_Write_Dat(*s);
      s++;
        delay100us(1);
   }
}
/*------------------------------------------------
                      清屏
------------------------------------------------*/
void LCD12864_ClrScreen()
{
    LCD12864_Write_Cmd(0x01);
        delay100us(100);
}
          
/*------------------------------------------------
                   显示图片
------------------------------------------------*/
void LCD12864_PutGraphic(uchar code *img)
{
uchar i,j;
//显示上半屏内容设置
   for(i=0;i<32;i++)       //上半屏,共扫描32行   
    {
      LCD12864_Write_Cmd(0x80 + i); //SET垂直地址 VERTICAL ADD
      LCD12864_Write_Cmd(0x80);   //SET水平地址 HORIZONTAL ADD
      for(j=0;j<16;j++)           //写每一小行,每次8bits,要16次才能写完8个字
       {
         LCD12864_Write_Dat(*img);
         img++;
       }
    }
//显示下半屏内容设置
   for(i=0;i<32;i++)            
    {
      LCD12864_Write_Cmd(0x80 + i); //SET 垂直地址 VERTICAL ADD
      LCD12864_Write_Cmd(0x88);   //SET 水平地址 HORIZONTAL ADD
      for(j=0;j<16;j++)
       {
         LCD12864_Write_Dat(*img);
         img++;
       }
    }
         
}
/*------------------------------------------------
               设置到绘图模式
------------------------------------------------*/
void LCD12864_SetGraphicMode()
{
   LCD12864_Write_Cmd(0x36);       //选择8bit数据流 图形模式
        delay100us(1);

}
/*------------------------------------------------
               主程序
------------------------------------------------*/
void main()
{
   InitSPI();
   LCD12864_CGRAM();   //写入自定义字符
   Init_ST7920();   //初始化
   while(1)
   {
          Init_ST7920();   //初始化
          LCD12864_ClrScreen();   
      LCD12864_PutString(0,1,"    学习单片机");
          LCD12864_PutString(0,2,"findbest技术论坛");
          LCD12864_PutString(0,3,"LCD12864点阵液晶");
      LCD12864_PutString(0,4,"ST7920测试程序");   
          LCD12864_DisplayCGRAM(0,1,00);//最后一个位置写入自定义图片笑脸
          LCD12864_DisplayCGRAM(7,1,02); //在第一行第一个位置和

          delay1s(2);

          LCD12864_ClrScreen();          //清屏
          LCD12864_PutString(0,2,"专用技术论坛");
      LCD12864_PutString(0,3,"专业成就卓越! ");   
          LCD12864_DisplayCGRAM(0,1,04); //写入自定义图片笑脸
          LCD12864_DisplayCGRAM(0,4,06);

           delay1s(2);

          LCD12864_ClrScreen();          //清屏
          LCD12864_SetGraphicMode();   //设置成绘图模式
      LCD12864_PutGraphic(pic1); //调入一幅图画

           delay1s(2);                
   }
}

op_zcj 发表于 2012-3-24 18:05:37

哎,问题还是出在程序上,在void LCD12864_CGRAM()里加了句 LCD12864_CS=1;,问题解决了

longwu911 发表于 2012-3-24 19:11:05

make,不错

hbx310 发表于 2012-3-24 19:16:13

手册应该有相应的时序图,操作说明什么的,:)

a312835782 发表于 2012-3-31 10:20:56

速度不够啊,并行的快点

jetli 发表于 2012-3-31 19:11:51

你用的液晶是st7920 的“串行模式” 么?

op_zcj 发表于 2012-4-7 18:56:11

jetli 发表于 2012-3-31 19:11 static/image/common/back.gif
你用的液晶是st7920 的“串行模式” 么?

是的,st7920 的“串行模式”

jetli 发表于 2012-4-8 00:09:20

op_zcj 发表于 2012-4-7 18:56 static/image/common/back.gif
是的,st7920 的“串行模式”

st7920的 自定义字符 要用绘图模式写

在串行方式下,绘图模式比较繁琐。{:sleepy:}
页: [1]
查看完整版本: 有谁用过STC的硬件SPI驱动12864显示自定义字符啊