/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
/************* 本程序功能说明 **************
驱动LCD128*64黑白点阵屏.
用户可以修改宏来选择时钟频率.
显示效果为: 第一行显示模拟的RTC时间, 7、8行显示8个16*16点的汉字. 本程序使用的LCD是有两个片选的.
注意: LCD接口的16脚是空脚, 本程序要把这个脚接到P2.2做另一页的片选.
******************************************/
#include "stc32g.h"
#include "intrins.h"
#include "LCD12864.h"
#define MAIN_Fosc 11059200L //定义主时钟
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
/************* IO口定义 **************/
sbit P_HC595_SER = P4^0; //pin 14 SER data input
sbit P_HC595_RCLK = P5^4; //pin 12 RCLk store (latch) clock
sbit P_HC595_SRCLK = P4^3; //pin 11 SRCLK Shift data clock
u8 hour,minute,second;
void delay_ms(u8 ms);
void DisableHC595(void);
void SetStartAddress(u8 x,u8 y);
void FillPage(u8 y,u8 color); //Clear Page LCD RAM
void FillAll(u8 color); //Clear CSn LCD RAM
void Initialize_LCD(void); //initialize LCD
void WriteAscii6x8(u8 x,u8 y,u8 ascii,u8 color);
void WriteHZ16(u8 x,u8 y,u16 hz,u8 color);
#define P0n_push_pull(bitn) P0M1 &= ~(bitn), P0M0 |= (bitn) //01
/**************** 外部函数声明和外部变量声明 *****************/
/********************** 显示时钟函数 ************************/
void DisplayRTC(void)
{
if(hour >= 10) WriteAscii6x8(0,0,hour / 10 + '0',0);
else WriteAscii6x8(0,0,':',0);
WriteAscii6x8(6, 0,hour % 10 +'0',0);
WriteAscii6x8(12,0,':',0);
WriteAscii6x8(18,0,minute / 10+'0',0);
WriteAscii6x8(24,0,minute % 10+'0',0);
WriteAscii6x8(30,0,':',0);
WriteAscii6x8(36,0,second / 10 +'0',0);
WriteAscii6x8(42,0,second % 10 +'0',0);
}
/********************** RTC演示函数 ************************/
void RTC(void)
{
if(++second >= 60)
{
second = 0;
if(++minute >= 60)
{
minute = 0;
if(++hour >= 24) hour = 0;
}
}
}
/********************** 主函数 ************************/
void main(void)
{
u8 i;
P0M1 = 0; P0M0 = 0; //设置为准双向口
P1M1 = 0; P1M0 = 0; //设置为准双向口
P2M1 = 0; P2M0 = 0; //设置为准双向口
P3M1 = 0; P3M0 = 0; //设置为准双向口
P4M1 = 0; P4M0 = 0; //设置为准双向口
P5M1 = 0; P5M0 = 0; //设置为准双向口
P6M1 = 0; P6M0 = 0; //设置为准双向口
P7M1 = 0; P7M0 = 0; //设置为准双向口
Initialize_LCD();
DisableHC595(); //禁止掉学习板上的HC595显示,省电
hour = 12; //初始化时间值
minute = 0;
second = 0;
DisplayRTC();
for(i=0; i<8; i++) WriteHZ16(i*16,4,i,0);
while(1)
{
delay_ms(250); //延时1秒
delay_ms(250);
delay_ms(250);
delay_ms(250);
RTC();
DisplayRTC();
}
}
/**********************************************/
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do{
i = MAIN_Fosc / 13000;
while(--i) ; //14T per loop
}while(--ms);
}
void DisableHC595(void)
{
u8 i;
P_HC595_SER = 1;
for(i=0; i<20; i++)
{
P_HC595_SRCLK = 1;
P_HC595_SRCLK = 0;
}
P_HC595_RCLK = 1;
P_HC595_RCLK = 0; //锁存输出数据
P_HC595_RCLK = 1;
P_HC595_RCLK = 0; //锁存输出数据
}
unsigned char code HZK16[]={
0X10,0X50,0X92,0X14,0XF0,0X10,0X20,0X24,0X24,0XA4,0X24,0XFF,0X20,0X24,0X28,0X00, //1783斌
0X20,0X10,0X0D,0X02,0X05,0X18,0X40,0X7F,0X40,0X3F,0X22,0X07,0X38,0X40,0XE0,0X00,
0X20,0X42,0X0C,0X40,0X7C,0X40,0XFF,0X48,0X4A,0XF2,0X1A,0XD6,0X12,0XFB,0X12,0X00, //1784濒
0X04,0X7C,0X03,0X44,0X23,0X10,0X0F,0X84,0X82,0X4F,0X20,0X1F,0X20,0X4F,0XC0,0X00,
0X20,0X42,0X0C,0XD0,0X0C,0X04,0XE4,0XA4,0XA5,0X96,0X94,0XC4,0X84,0X14,0X0C,0X00, //1785滨
0X04,0X04,0XFE,0X09,0X08,0X88,0X6F,0X28,0X08,0X08,0X2F,0X48,0XC8,0X0C,0X08,0X00,
0X00,0X10,0X0C,0X04,0XE4,0XA4,0XA5,0XA6,0X94,0X94,0XD4,0X84,0X14,0X0C,0X00,0X00, //1786宾
0X08,0X08,0X08,0X88,0X6F,0X28,0X08,0X08,0X08,0X2F,0X48,0XC8,0X08,0X0C,0X08,0X00,
0X10,0X10,0X10,0XFF,0X90,0X5C,0X04,0XE4,0XA4,0XA5,0X96,0XD4,0X84,0X14,0X0C,0X00, //1787摈
0X02,0X42,0X81,0X7F,0X08,0X08,0X88,0X6F,0X28,0X08,0X08,0X2F,0X48,0XCC,0X08,0X00,
0X00,0X00,0X00,0X00,0XFC,0X44,0X44,0X44,0X42,0XC2,0X43,0X62,0X40,0X00,0X00,0X00, //1788兵
0X04,0X04,0X84,0X44,0X27,0X34,0X04,0X04,0X04,0X17,0X24,0X64,0XC4,0X06,0X04,0X00,
0X00,0X02,0X04,0XCC,0X20,0X20,0XA0,0X60,0XFF,0XC0,0X20,0X10,0X08,0X0C,0X00,0X00, //1789冰
0X02,0X02,0XFF,0X10,0X08,0X06,0X41,0X80,0X7F,0X00,0X01,0X02,0X0C,0X18,0X08,0X00,
0X10,0X10,0XD0,0XFF,0X90,0X14,0XC4,0X44,0X44,0XFC,0X44,0X44,0X44,0XE6,0X44,0X00, //1790柄
0X04,0X03,0X00,0XFF,0X00,0X01,0XFF,0X08,0X04,0X03,0X02,0X44,0X8C,0X7F,0X00,0X00,
};
unsigned char code ASCII6x8[]={
0x3E,0x51,0x49,0x45,0x3E,0x00, //0 0
0x00,0x42,0x7F,0x40,0x00,0x00, //1 1
0x42,0x61,0x51,0x49,0x46,0x00, //2 2
0x21,0x41,0x45,0x4B,0x31,0x00, //3 3
0x18,0x14,0x12,0x7F,0x10,0x00, //4 4
0x27,0x45,0x45,0x45,0x39,0x00, //5 5
0x3C,0x4A,0x49,0x49,0x30,0x00, //6 6
0x01,0x01,0x79,0x05,0x03,0x00, //7 7
0x36,0x49,0x49,0x49,0x36,0x00, //8 8
0x06,0x49,0x49,0x29,0x1E,0x00, //9 9
0x7E,0x11,0x11,0x11,0x7E,0x00, //A A
0x41,0x7F,0x49,0x49,0x36,0x00, //B B
0x3E,0x41,0x41,0x41,0x22,0x00, //C C
0x41,0x7F,0x41,0x41,0x3E,0x00, //D D
0x7F,0x49,0x49,0x49,0x49,0x00, //E E
0x7F,0x09,0x09,0x09,0x01,0x00, //F F
0x3E,0x51,0x49,0x45,0x3E,0x00, //10 0
0x00,0x42,0x7F,0x40,0x00,0x00, //11 1
0x42,0x61,0x51,0x49,0x46,0x00, //12 2
0x21,0x41,0x45,0x4B,0x31,0x00, //13 3
0x18,0x14,0x12,0x7F,0x10,0x00, //14 4
0x27,0x45,0x45,0x45,0x39,0x00, //15 5
0x3C,0x4A,0x49,0x49,0x30,0x00, //16 6
0x01,0x01,0x79,0x05,0x03,0x00, //17 7
0x36,0x49,0x49,0x49,0x36,0x00, //18 8
0x06,0x49,0x49,0x29,0x1E,0x00, //19 9
0x7E,0x11,0x11,0x11,0x7E,0x00, //1A A
0x41,0x7F,0x49,0x49,0x36,0x00, //1B B
0x3E,0x41,0x41,0x41,0x22,0x00, //1C C
0x41,0x7F,0x41,0x41,0x3E,0x00, //1D D
0x7F,0x49,0x49,0x49,0x49,0x00, //1E E
0x7F,0x09,0x09,0x09,0x01,0x00, //1F F
0x00,0x00,0x00,0x00,0x00,0x00, //20 CHAR address=ASCII*6
0x00,0x00,0x4F,0x00,0x00,0x00, //21 !
0x00,0x07,0x00,0x07,0x00,0x00, //22 "
0x14,0x7F,0x14,0x7F,0x14,0x00, //23 #
0x24,0x2A,0x7F,0x2A,0x12,0x00, //24 $
0x23,0x13,0x08,0x64,0x62,0x00, //25 %
0x36,0x49,0x55,0x22,0x50,0x00, //26 &
0x00,0x05,0x03,0x00,0x00,0x00, //27 '
0x00,0x1C,0x22,0x41,0x00,0x00, //28 (
0x00,0x41,0x22,0x1C,0x00,0x00, //29 )
0x14,0x08,0x3E,0x08,0x14,0x00, //2A *
0x08,0x08,0x3E,0x08,0x08,0x00, //2B +
0x00,0x50,0x30,0x00,0x00,0x00, //2C ,
0x08,0x08,0x08,0x08,0x08,0x00, //2D -
0x00,0x60,0x60,0x00,0x00,0x00, //2E .
0x20,0x10,0x08,0x04,0x02,0x00, //2F /
0x3E,0x51,0x49,0x45,0x3E,0x00, //30 0
0x00,0x42,0x7F,0x40,0x00,0x00, //31 1
0x42,0x61,0x51,0x49,0x46,0x00, //32 2
0x21,0x41,0x45,0x4B,0x31,0x00, //33 3
0x18,0x14,0x12,0x7F,0x10,0x00, //34 4
0x27,0x45,0x45,0x45,0x39,0x00, //35 5
0x3C,0x4A,0x49,0x49,0x30,0x00, //36 6
0x01,0x01,0x79,0x05,0x03,0x00, //37 7
0x36,0x49,0x49,0x49,0x36,0x00, //38 8
0x06,0x49,0x49,0x29,0x1E,0x00, //39 9
0x00,0x36,0x36,0x00,0x00,0x00, //3A :
0x00,0x56,0x36,0x00,0x00,0x00, //3B ;
0x08,0x14,0x22,0x41,0x00,0x00, //3C <
0x14,0x14,0x14,0x14,0x14,0x00, //3D =
0x00,0x41,0x22,0x14,0x08,0x00, //3E >
0x02,0x01,0x51,0x09,0x06,0x00, //3F ?
0x32,0x49,0x79,0x41,0x3E,0x00, //40 @
0x7E,0x11,0x11,0x11,0x7E,0x00, //41 A
0x41,0x7F,0x49,0x49,0x36,0x00, //42 B
0x3E,0x41,0x41,0x41,0x22,0x00, //43 C
0x41,0x7F,0x41,0x41,0x3E,0x00, //44 D
0x7F,0x49,0x49,0x49,0x49,0x00, //45 E
0x7F,0x09,0x09,0x09,0x01,0x00, //46 F
0x3E,0x41,0x41,0x49,0x7A,0x00, //47 G
0x7F,0x08,0x08,0x08,0x7F,0x00, //48 H
0x00,0x41,0x7F,0x41,0x00,0x00, //49 I
0x20,0x40,0x41,0x3F,0x01,0x00, //4A J
0x7F,0x08,0x14,0x22,0x41,0x00, //4B K
0x7F,0x40,0x40,0x40,0x40,0x00, //4C L
0x7F,0x02,0x0C,0x02,0x7F,0x00, //4D M
0x7F,0x06,0x08,0x30,0x7F,0x00, //4E N
0x3E,0x41,0x41,0x41,0x3E,0x00, //4F O
0x7F,0x09,0x09,0x09,0x06,0x00, //50 P
0x3E,0x41,0x51,0x21,0x5E,0x00, //51 Q
0x7F,0x09,0x19,0x29,0x46,0x00, //52 R
0x26,0x49,0x49,0x49,0x32,0x00, //53 S
0x01,0x01,0x7F,0x01,0x01,0x00, //54 T
0x3F,0x40,0x40,0x40,0x3F,0x00, //55 U
0x1F,0x20,0x40,0x20,0x1F,0x00, //56 V
0x7F,0x20,0x18,0x20,0x7F,0x00, //57 W
0x63,0x14,0x08,0x14,0x63,0x00, //58 X
0x07,0x08,0x70,0x08,0x07,0x00, //59 Y
0x61,0x51,0x49,0x45,0x43,0x00, //5A Z
0x00,0x7F,0x41,0x41,0x00,0x00, //5B {
0x02,0x04,0x08,0x10,0x20,0x00, /*5C \*/
0x00,0x41,0x41,0x7F,0x00,0x00, //5D }
0x04,0x02,0x01,0x02,0x04,0x00, //5E ^
0x40,0x40,0x40,0x40,0x40,0x00, //5F _
0x01,0x02,0x04,0x00,0x00,0x00, //60 '
0x20,0x54,0x54,0x54,0x78,0x00, //61 a
0x7F,0x48,0x44,0x44,0x38,0x00, //62 b
0x38,0x44,0x44,0x44,0x28,0x00, //63 c
0x38,0x44,0x44,0x48,0x7F,0x00, //64 d
0x38,0x54,0x54,0x54,0x18,0x00, //65 e
0x00,0x08,0x7E,0x09,0x02,0x00, //66 f
0x0C,0x52,0x52,0x4C,0x3E,0x00, //67 g
0x7F,0x08,0x04,0x04,0x78,0x00, //68 h
0x00,0x44,0x7D,0x40,0x00,0x00, //69 i
0x20,0x40,0x44,0x3D,0x00,0x00, //6A j
0x00,0x7F,0x10,0x28,0x44,0x00, //6B k
0x00,0x41,0x7F,0x40,0x00,0x00, //6C l
0x7C,0x04,0x78,0x04,0x78,0x00, //6D m
0x7C,0x08,0x04,0x04,0x78,0x00, //6E n
0x38,0x44,0x44,0x44,0x38,0x00, //6F o
0x7E,0x0C,0x12,0x12,0x0C,0x00, //70 p
0x0C,0x12,0x12,0x0C,0x7E,0x00, //71 q
0x7C,0x08,0x04,0x04,0x08,0x00, //72 r
0x58,0x54,0x54,0x54,0x64,0x00, //73 s
0x04,0x3F,0x44,0x40,0x20,0x00, //74 t
0x3C,0x40,0x40,0x3C,0x40,0x00, //75 u
0x1C,0x20,0x40,0x20,0x1C,0x00, //76 v
0x3C,0x40,0x30,0x40,0x3C,0x00, //77 w
0x44,0x28,0x10,0x28,0x44,0x00, //78 x
0x1C,0xA0,0xA0,0x90,0x7C,0x00, //79 y
0x44,0x64,0x54,0x4C,0x44,0x00, //7A z
0x00,0x08,0x36,0x41,0x00,0x00, //7B {
0x00,0x00,0x77,0x00,0x00,0x00, //7C |
0x00,0x41,0x36,0x08,0x00,0x00, //7D }
0x02,0x01,0x02,0x04,0x02,0x00, //7E ~
0xFF,0xFF,0xFF,0xFF,0xFF,0x00, //7F all display
0xFF,0x00,0x00,0x00,0x00,0x00}; //80 cursor
/************* 功能说明 **************
LCD12864的基本驱动程序,兼容IC:HD61202 KS0108B SED1520.
******************************************/
/********************* LCD 128*64 Module, Controler HD61202U *************************************
R_W L: write data to LCD; H: read data from LCD
RS L: Instruction Code Input or state output; H: data input or output
RESET H: normal work; L: reset LCD
CS1 H: disable Pice 1, L:enable Pice 1
CS2 H: disable Pice 2, L:enable Pice 2
CS3 H: disable Pice 3, L:enable Pice 3
E L: disable; H: read State or data from LCD;
H-->L: write command or data to LCD
D0~D7 Data bus
RS R/W
0 0 :write command to LCD
0 1 :read status from LCD
1 0 :write display data to LCD
1 1 :read display data from LCD
;********************************************************************************/
#define C_Busy 0x80
#define C_On_Off 0x20
#define C_Reset 0x10
#define LCD_On 0x3F
#define LCD_Off 0x3E
#define LCD_StartLine0 0xC0 //Set display start line(0~3FH), real start line=(0C0H+Line Number)
#define LCD_Page0 0xB8 //Set Page (X Address)(0~7), real page = 0B8H+Page Number
#define LCD_SetColumn0 0x40 //Set Y address (0~3FH), real column = 40H + column number
// 1----VSS
// 2----VDD +5V
// 3----Vo LCD Opration Voltage
sbit RS = P2^5; // 4----RS L-->Command,H-->Data
sbit R_W = P2^6; // 5----R_W L-->Write, H-->Read
sbit LCD_EN = P2^7; // 6----E H-->L: write command or data to LCD,H: read State or data from LCD;
sfr LCD_DATA = 0x80; // 7~14--D0~D7 Data bus
sbit CS1 = P2^4; // 15---CS1 L-->Chip select1
sbit CS2 = P2^2; // 16---CS2 L-->Chip select2
sbit LCD_RESET = P2^3; // 17---RESET L-->Enable
// 18---VEE L-->Chip select3
// 19---LED- LED A Back Light LED Drive
// 20---LED+ LED K Back Light LED Drive
sbit LCD_BUSY = LCD_DATA^7;
#define CMD_WriteCMD() RS=0, R_W=0
#define CMD_ReadStatus() RS=0, R_W=1
#define CMD_WriteData() RS=1, R_W=0
#define CMD_ReadData() RS=1, R_W=1
#define SELECT 1
#define UNSELECT 0
//******************************************
void LCD_delay(void)
{
u8 i;
// i = (u8)(MAIN_Fosc / 2000000UL);
i = (u8)(MAIN_Fosc / 1000000UL);
while(--i) ;
}
//******************************************
u8 CheckBusy(void) //不需要检测忙
{
/*
u8 i;
LCD_DATA = 0xFF;
CMD_ReadStatus();
LCD_EN = 1;
LCD_delay();
for(i=0; i<100; i++) //检测忙, 一般最大 大约10us, 这个使用超时退出
{
if(LCD_BUSY == 0) break; // 11T / loop, 0.5us at 11.0592MHZ
}
LCD_EN = 0;
if(i >= 100) return 1; //超时
*/
return 0; //正确
}
//******************************************
void WriteCMD(u8 cmd)
{
if(CheckBusy() > 0) return; //检测忙错误
CMD_WriteCMD();
LCD_DATA = cmd;
LCD_delay();
LCD_EN = 1;
LCD_delay();
LCD_EN = 0;
LCD_delay();
LCD_DATA = 0xFF;
}
//******************************************
void WriteData(u8 dat) //write display data to LCD
{
if(CheckBusy() > 0) return; //检测忙错误
CMD_WriteData();
LCD_DATA = dat;
LCD_delay();
LCD_EN = 1;
LCD_delay();
LCD_EN = 0;
LCD_DATA = 0xFF;
}
//******************************************
void SetStartAddress(u8 x,u8 y)
{
WriteCMD(x + LCD_SetColumn0);
WriteCMD(y + LCD_Page0);
}
//******************************************
void FillPage(u8 y,u8 color) //Clear Page LCD RAM
{
u8 j;
SetStartAddress(0,y);
for(j=0; j<64; j++) WriteData(color);
}
//******************************************
void FillAll(u8 color) //Clear CSn LCD RAM
{
u8 i;
for(i=0; i<8; i++) FillPage(i,color);
}
//******************************************
void Initialize_LCD(void) //initialize LCD
{
LCD_RESET = 0;
delay_ms(10);
LCD_RESET = 1;
delay_ms(150);
// CS1 = SELECT;
// CS2 = SELECT;
WriteCMD(LCD_Off); //0x3E turn off LCD
WriteCMD(LCD_StartLine0); //#0C0H set the start line is the first line
WriteCMD(LCD_On); //#3FH turn on display
FillAll(0);
CS1 = UNSELECT;
CS2 = UNSELECT;
}
//******************************************
void WriteAscii6x8(u8 x,u8 y,u8 ascii,u8 color)
{
u8 code *p;
u8 i;
p = ascii * 6 + ASCII6x8;
if(x < 64) CS1 = SELECT;
else CS2 = SELECT, x -= 64;
SetStartAddress(x,y);
for(i=0; i<6; i++) {WriteData((*p) ^ color); p++;}
CS1 = UNSELECT;
CS2 = UNSELECT;
}
//******************************************
void WriteHZ16(u8 x,u8 y,u16 hz,u8 color)
{
u8 code *p;
u8 i;
p = hz * 32 + HZK16;
if(x < 64) CS1 = SELECT;
else CS2 = SELECT, x -= 64;
SetStartAddress(x,y);
for(i=0; i<16; i++) {WriteData((*p) ^ color); p++;}
SetStartAddress(x,y+1);
for(i=0; i<16; i++) {WriteData((*p) ^ color); p++;}
CS1 = UNSELECT;
CS2 = UNSELECT;
}
|