呵呵,那什么练手好呢,看了下7920的12864,就是他了,先对比下时序
一步步来。
上面是7920的SPI时序,下面是STC的SPI时序,用的是STC12C5A60S2,STC的英文资料,难得吧,感觉E文的广告能少点。。。。
继续折腾完毕~
下面是结果~~
//========================================代码区==========================================//
//#include <STC_NEW_8051.H>
#include "reg51.h"
//============================================================================================================
#define uint unsigned int
#define uchar unsigned char
//引脚定义
sbit LCD_CS =P1^4; // 片选 高电平有效 单片LCD使用时 可固定高电平
sbit LCD_SID =P1^5; // 数据
sbit LCD_CLK =P1^7; // 时钟
sbit LCD_PSB =P3^5; // 低电平时表示用串口驱动, 可固定低电平
sbit LCD_RST =P3^6; // LCD复位,LCD模块自带复位电路。 可不接
//sbit LCD_BACK =P2^6; // LCD背光控制
//=========================================================================
#define MASTER //define:master undefine:slave
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
sfr AUXR = 0x8e; //Auxiliary register
sfr SPSTAT = 0xcd; //SPI status register 84
#define SPIF 0x80 //SPSTAT.7
#define WCOL 0x40 //SPSTAT.6
sfr SPCTL = 0xce; //SPI control register 85
#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
sfr SPDAT = 0xcf; //SPI data register 86
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 | SPDH; //master mode
#else
SPCTL = SPEN; //slave mode
#endif
}
BYTE SPISwap(BYTE dat)
{
#ifdef MASTER
SPISS = 1; //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 = 0; //push high slave SS
#endif
return SPDAT; //return received SPI data
}
//=========================================================================
void Delay(uint Number)
{
uint i,j;
for (i=0; i<Number; i++)
{
for(j=0; j<10; j++)
{
;
}
}
}
/*****************************************************/
void Send_byte(uchar Byte)
{
SPISwap(Byte);
// 以下方式为模拟SPI
// uchar i;
// for (i=0; i<8; i++)
// {
// LCD_SID = Byte&0x80; // 取出最高位 写入串行数据
// LCD_CLK = 1; // 串行同步时钟信号
// LCD_CLK = 0;
// Byte <<= 1; // 左移
// }
}
/*****************************************************/
void WriteCommandLCM(uchar WCLCM)
{
uchar Start_data,Hdata,Ldata;
Start_data = 0xf8; // 写指令 11111000
Hdata = WCLCM&0xf0; // 取高四位 DDDD0000
Ldata = (WCLCM << 4) & 0xf0; // 取低四位 0000DDDD
Send_byte(Start_data); // 发送起始信号 第1字节-格式:1111ABC
Delay(5); // 延时是必须的
Send_byte(Hdata); // 发送高四位 第2字节-格式DDD0000
Delay(1); // 延时是必须的
Send_byte(Ldata); // 发送低四位 第3字节-格式:0000DDDD
Delay(1); // 延时是必须的
}
/*****************************************************/
void WriteDataLCM(uchar WDLCM)
{
uchar Start_data,Hdata,Ldata;
Start_data = 0xfa; // 写数据 11111010
Hdata = WDLCM & 0xf0; // 取高四位 DDDD0000
Ldata = (WDLCM << 4) & 0xf0; // 取低四位 0000DDDD
Send_byte(Start_data); // 发送起始信号 第1字节-格式:1111ABC
Delay(5); // 延时是必须的
Send_byte(Hdata); // 发送高四位 第2字节-格式DDD0000
Delay(1); // 延时是必须的
Send_byte(Ldata); // 发送低四位 第3字节-格式:0000DDDD
Delay(1); // 延时是必须的
}
/*****************************************************/
void Lcdinit(void)
{
Delay(10); // 启动等待,等LCM讲入工作状态
LCD_PSB = 0; // 串口驱动模式
LCD_RST = 0;
Delay(1);
LCD_RST = 1; // 复位LCD
LCD_CS = 1; // 片选
WriteCommandLCM(0x30); // 8 位介面,基本指令集
WriteCommandLCM(0x0c); // 显示打开,光标关,反白关
WriteCommandLCM(0x01); // 清屏,将DDRAM的地址计数器归零
}
/*****************************************************/
void DisplayListChar(uchar x, uchar y, uchar code *s)
{
uchar add; // 显示地址
switch (y) // 显示地址计数
{
case 0: add = x + 0x80; break; // 第一行的地址
case 1: add = x + 0x90; break; // 第二行的地址
case 2: add = x + 0x88; break; // 第三行的地址
case 3: add = x + 0x98; break; // 第四行的地址
default: break;
}
WriteCommandLCM(0x30); // 8位介面,基本指令集
WriteCommandLCM(add); // 写入地址
while (*s > 0) // 写入字符串
{
WriteDataLCM(*s);
s++;
Delay(50);
}
}
/*****************************************************/
//图形方式
//void DisplayPicture(uint code *img)
//{
// uchar Line,Row; // Line为行地址;Row为列地址
// uint regist = 0; // 图形地址寄存器
//
// WriteCommandLCM(0x36); // 图形方式,扩展指令
// // -------------- 上半屏 ----------------
// for (Line=0; Line<32; Line++)
// {
// WriteCommandLCM(0x80 + Line); // 写入行地址
// WriteCommandLCM(0x80); // 写入列
//
// for (Row=0; Row<16; Row++)
// {
// WriteDataLCM(img[regist++]); // 写入图片数据
// }
// }
// // --------------- 下半屏 ---------------
// regist=512; // 下半屏起始数据
//
// for (Line=0; Line<32; Line++)
// {
// WriteCommandLCM(0x80 + Line); // 写入行地址
// WriteCommandLCM(0x88); // 写入列
//
// for (Row=0; Row<16; Row++)
// {
// WriteDataLCM(img[regist++]); // 写入图片数据
// }
// }
//
// WriteCommandLCM(0x30); // 基本指令
//}
/*****************************************************/
void main(void)
{
InitSPI(); //initial SPI
Delay(10);
Lcdinit(); // 初始化LCD
Delay(100);
DisplayListChar(0,0,"人生若只是初见,");
DisplayListChar(0,1,"何事秋风悲画扇。");
DisplayListChar(0,2,"等闲变却故人心,");
DisplayListChar(0,3,"却道故人心易变。");
while(1)
{
}
}
//========================================代码区完==pp上场==================================//
实际的IO用了两个,片选直接接高!
秉承一贯闹着玩的做风~
P.S: 这句话!!
SPCTL = SPEN | MSTR | CPHA | CPOL | SPDH; //master mode
注意SPI的设置!!换了别的东西还得先看看手册啊!!
|