📄 main.c
字号:
/*
描 述:KMX12864(基于ST7920驱动芯片)液晶屏测试程序
说 明:1. 程序为基于SPI(串口)的液晶测试。
2. ATSAM7S64系统设置:
2.1. 时钟为MCK 48mhz;
2.2. SPI时钟为 MCK/255 (由于ST7920反映速度较慢,因此尽量降低SPI时钟)
2.3. SPI时序以ST7920串行方式通讯时序为准,具体参考ST7920文档中时序部分
3。其他说明:
3.1. KMX12864本身调整了对比度,因此引脚3(V0)可直接悬空或接地,并不影响使用。
3.2. KMX12864串行接口引脚4(/CS片选信号)低电平有效
3.3. ATSAM7S64通过SPI0与KMX12864串行接口连接,需要注意的是:需程序控制片选KMX12864。
记 录:1. changyj 创建工程 2007-9-20:18:00
2. changyj 完成工程 2007-10-09
*/
#include "../Startup/Board.h"
#define LCM_MODE_TEXT 0
/*-SPI相关定义-*/
#define AT91C_SPI_CS0 0
#define AT91C_SPI_CS1 1
#define AT91C_SPI_CS2 2
#define AT91C_SPI_CS3 3
#define AT91C_SPI_CPOL0 0
#define AT91C_SPI_CPOL1 1
#define AT91C_SPI_CPHA0 0
#define AT91C_SPI_CPHA1 1
/*-SPI工作模式定义-*/
// SPI设备工作模式:<MSTR = 1:主机模式>+<PS = 0:固定片选0>+<PCSDEC = 0:片选直接与外设相连>+
// <FDIV = 1:SPI时钟为MCK/N>+<MODFDIS = 1:模式错误检测禁止>+<LLB = 0:本地回路禁用>+
// <PCS=0:片选0>+<DLYBCS=0:默认>
#define AT91C_SPI_MODE_MR (AT91C_SPI_MSTR|AT91C_SPI_MODFDIS|AT91C_SPI_PS_FIXED)
// 设置片选寄存器:<CPOL = 0>+<NCPHA = 1>+<CSAAT = 0>+<BITS = 0x00:8位传输数据>+<SCBR = 12:SPCK波特率 = AT91C_SPI_BAUD>
#define AT91C_SPI_MODE_CS0 AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|((unsigned int) 0xFF << 8)
/*- ST7920相关定义-*/
#define AT91C_PA11_CS AT91C_PIO_PA11
#define MSG_TYPE_COMM 0x0 // 命令消息类型
#define MSG_TYPE_DATA 0x1 // 数据消息类型
#define ST7920_DDRAM_ROW1 0x80
#define ST7920_DDRAM_ROW2 0x90
#define ST7920_DDRAM_ROW3 0x88
#define ST7920_DDRAM_ROW4 0x98
#define ST7920_GDRAM_BASE 0x80 // GDRAM基地址(起始地址)
#define ST7920_MODE_TEXT 0x0 // 文本模式
#define ST7920_MODE_GRAPHIC 0x1 // 图形模式
#define ST7920_COMMAND_TYPE_BASIC 0x30 // 基本命令操作
#define ST7920_COMMAND_TYPE_EXTEND 0x34 // 扩展命令操作
#define ST7920_COMMAND_BASIC_CLEAR 0x1 // 清屏命令
#define ST7920_COMMAND_BASIC_RESET 0x2 // LCD的DDRAM地址归位
#define ST7920_COMMAND_BASIC_DISPLAY_ON 0x0C // 显示状态开:整体显示+关光标+光标标位置不显示
#define ST7920_COMMAND_BASIC_ENTRY_MODE 0x06 // 进入点设定:显示字符/光标从左到右移位,DDRAM地址加1
#define ST7920_COMMAND_EXTEND_GRAPHIC_ON 0x36 // 扩展命令,开图形模式
#define ST7920_COMMAND_EXTEND_GRAPHIC_OFF 0x34 // 扩展命令,关图形模式
#define ST7920_COMMAND_EXTEND_STANDBY 0x1 // 扩展命令,待机
typedef unsigned int uint;
typedef unsigned char uchar;
void Delay(int ms); // 延迟
void SpiInilize(); // SPI初始化,设置时序波形、工作模式等
void SpiSendByte(uchar msg); // 向SPI发送字节
void ST7920Initlize(); // ST7920初始化,参考st7920手册
void ST7920WriteByte( uchar type, uchar msg); // 按照st7920串口时序向st7920发送字节数据/命令
void ST7920WriteString( uchar* string); // 按照st7920串口时序向st7920发送字符串数据(中英文均可)
void ST7920WriteChinese( uint msg); // 按照st7920串口时序向st7920发送单个汉字
void ST7920SetDdramLocation( uchar x, uchar y); // 按照st7920串口时序向st7920发送位置信息
void ST7920SetGdramLocation( uchar x, uchar y); // 设置gdram的坐标
void ST7920LcmClear(); // 清屏
void ST7920DrawDot(uchar x, uchar y); // 画点
void ST7920DrawPic(uchar* pic); // 画图
void ST7920DrawLine(uchar xSrc, uchar ySrc, uchar xDst, uchar yDst);// 画线
unsigned char pic12864[];
void main()
{
ST7920Initlize();
#if LCM_MODE_TEXT // 文本模式
unsigned char lineNo1[]="ST7920驱动芯片";
unsigned char lineNo2[]="KMX12864液晶屏";
unsigned char lineNo3[]="串行口测试程序";
unsigned char lineNo4[]="www.zzuli.edu.cn";
ST7920SetDdramLocation(0,0);
ST7920WriteString(lineNo1);
ST7920SetDdramLocation(1,0);
ST7920WriteString(lineNo2);
ST7920SetDdramLocation(2,0);
ST7920WriteString(lineNo3);
ST7920SetDdramLocation(3,0);
ST7920WriteString(lineNo4);
#else // 图形模式
//ST7920DrawDot(127, 63);
ST7920DrawPic(pic12864);
//ST7920DrawLine(0,0, 127,63);
#endif
while(1){;}
}
void SpiInilize()
{
// 使能SPI时钟
AT91F_SPI_CfgPMC();
// 使能PIO时钟
AT91F_PIOA_CfgPMC();
// 复位SPI()
AT91F_SPI_Reset(AT91C_BASE_SPI);
// 程序控制KMX12864片选(注意此处,若直接采用SPI控制片选,液晶屏不显示数据)
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PA11_CS);
// 为SPI0分配引脚
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, AT91C_PA13_MOSI|AT91C_PA14_SPCK, 0);
// 设置SPI主模式
AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MODE_MR);
// 设置SPI0工作模式
AT91F_SPI_CfgCs(AT91C_BASE_SPI, AT91C_SPI_CS0, AT91C_SPI_MODE_CS0);
// 允许SPI口
AT91F_SPI_Enable(AT91C_BASE_SPI);
// 禁止使能KMX12864
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, AT91C_PA11_CS);
}
void SpiSendByte(uchar msg)
{
// 使能KMX12864 -- 一个命令字或数据字开始
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PA11_CS);
AT91C_BASE_SPI->SPI_TDR = msg;
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE)){;}
// 禁止使能KMX12864 -- 一个命令字或数据字结束
AT91F_PIO_SetOutput(AT91C_BASE_PIOA, AT91C_PA11_CS);
// 这个延时是必须的,保证ST7920能够正常处理
Delay(1);
}
// 参考ST7920手册中《初始化》部分
void ST7920Initlize()
{
SpiInilize();
Delay(15); // Wait time > 40ms
ST7920WriteByte(MSG_TYPE_COMM, ST7920_COMMAND_TYPE_BASIC);
Delay(5); // Wait time > 100us
ST7920WriteByte(MSG_TYPE_COMM, ST7920_COMMAND_TYPE_BASIC);
Delay(1); // Wait time > 37us
ST7920WriteByte(MSG_TYPE_COMM, ST7920_COMMAND_BASIC_DISPLAY_ON);
Delay(1); // Wait time > 100us
ST7920WriteByte(MSG_TYPE_COMM, ST7920_COMMAND_BASIC_CLEAR);
Delay(1); // Wait time > 100us
ST7920WriteByte(MSG_TYPE_COMM, ST7920_COMMAND_BASIC_ENTRY_MODE);
Delay(1);
ST7920LcmClear();
}
// 参考ST7920手册《串行通讯时序》部分
void ST7920WriteByte( uchar type, uchar msg)
{
SpiSendByte(0xF8|type<<1); // 11111 + RW + RS + 0; RS = 0:命令字 ;RS = 1:数据字
SpiSendByte(msg&0xF0); //写数据的高4位
SpiSendByte((msg&0x0F)<<4); //写数据的低4位
}
void ST7920WriteWord(uint msg)
{
ST7920WriteByte(MSG_TYPE_DATA, msg>>8);
ST7920WriteByte(MSG_TYPE_DATA, msg);
}
/*
函数说明:文本模式下,设置ddram坐标
参数说明:unsigned char x :x水平坐标点(列)
unsigned char y :y垂直坐标点(行)
备 注:1.调用该函数应首先设置st7920处于图形模式下
2.关于坐标的说明:以左上角为原点,向左向下递增,水平方向为x,垂直方向为y。
*/
void ST7920SetDdramLocation( uchar x, uchar y)
{
unsigned int address;
if (x == 0) address = ST7920_DDRAM_ROW1 + y;
else if (x == 1) address = ST7920_DDRAM_ROW2 + y;
else if (x == 2) address = ST7920_DDRAM_ROW3 + y;
else if (x == 3) address = ST7920_DDRAM_ROW4 + y;
ST7920WriteByte(MSG_TYPE_COMM, address);
}
/*
函数说明:绘图模式下,设置gdram坐标
参数说明:unsigned char x :x水平坐标点(列);范围为(0~31)
unsigned char y :y垂直坐标点(行):范围为(0~63)
备 注:1.调用该函数应首先设置st7920处于图形模式下
2.关于坐标的说明:以左上角为原点,向左向下递增,水平方向为x,垂直方向为y。
3.详细资料参考《st7920手册》
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -