⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 这是一个arm7液晶屏的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  描  述: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 + -