有谁用过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);
}
} 哎,问题还是出在程序上,在void LCD12864_CGRAM()里加了句 LCD12864_CS=1;,问题解决了 make,不错 手册应该有相应的时序图,操作说明什么的,:) 速度不够啊,并行的快点 你用的液晶是st7920 的“串行模式” 么? jetli 发表于 2012-3-31 19:11 static/image/common/back.gif
你用的液晶是st7920 的“串行模式” 么?
是的,st7920 的“串行模式” op_zcj 发表于 2012-4-7 18:56 static/image/common/back.gif
是的,st7920 的“串行模式”
st7920的 自定义字符 要用绘图模式写
在串行方式下,绘图模式比较繁琐。{:sleepy:}
页:
[1]