12864.h
#ifndef __12864_H__
#define __12864_H__
#include<reg52.h>
#include <intrins.h>
/***************************************
利用I/O口模拟点阵液晶所需时序
点阵液晶控制端口定义,需根据硬件适当改变
****************************************/
sbit LCD_RS = P2^0;//控制端口定义
sbit LCD_RW = P2^1;
sbit LCD_E = P2^2;
sbit LCD_CSA = P2^3;//H选通,即高电平有效
sbit LCD_CSB = P2^4;
#define LCD_Data P0//LCD数据端口8位
#define R 1
#define L 2
/*****************************************
函数声明
*****************************************/
void ReadStatusLCD(unsigned char select);//从LCD读出忙标志位
unsigned char ReadDataLCD(unsigned char select);//从LCD读出数据
void WriteDataLCD(unsigned char WDLCD,unsigned char select);//向LED写入数据
void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select);//向LCD写入命令
void LcdReset(void) ;//初始化函数,完成液晶模块的初始设置
void clear_LCD(unsigned char select);//清屏函数
void Clr_All_Lcd(void);//全清屏函数
void set_XY(unsigned char Column,unsigned char Page);//设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址
void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW);//向指定行列写数据
void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte );//显示点
void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] );//显示16×16点阵的编码
void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,
unsigned char V_num, unsigned char * puts );//通用的显示函数
void Drawing_dot(unsigned char x,unsigned char y);
void Drawing_line_vertical(unsigned x);
#endif
12864.c
/****************************************************
LCD12864点阵液晶屏,
通过I/O口直接控制,采用模拟时序控制
****************************************************/
#include"12864.h"
#include<math.h>
/***********************************************************
功能:从LCD读取状态位
变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏
***********************************************************/
void ReadStatusLCD(unsigned char select)
{
switch(select)
{
case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左
case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右
default: break;
}
LCD_Data = 0xff;//置位输入口,已实现输入
LCD_RS=0;LCD_RW=1;LCD_E=1;//高电平读取数据
//_nop_(); //若晶振速度高,可在此作延时处理
while(LCD_Data&0x80);//最高位为忙标志,检测忙信号状态
LCD_E=0;
//_nop_(); //若晶振速度高,可在此作延时处理
}
/***********************************************************
功能:从LCD读取数据
变量:select用于选择LCD屏的左右,1选择左屏,2选择右屏
***********************************************************/
unsigned char ReadDataLCD(unsigned char select)
{
unsigned char dataR;
LCD_Data = 0xff;//置位输入口,已实现输入
switch(select)
{
case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左
case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右
default: break;
}
LCD_RW=1;LCD_RS=1;LCD_E = 1;// 操作允许脉冲信号,高电平读出
//_nop_(); //若晶振速度高,可在此作延时处理
dataR = LCD_Data;
LCD_E= 0;
return dataR;
}
/***********************************************************
功能: 向LCD写入数据
参数: WDLCD待写入的字符数据
select用于选择LCD屏的左右,1选择左屏,2选择右屏
***********************************************************/
void WriteDataLCD(unsigned char WDLCD,unsigned char select)
{
switch(select)
{
case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左
case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右
default: break;
}
ReadStatusLCD(select);//检测忙标志
LCD_RS = 1;LCD_RW = 0;
LCD_Data = WDLCD;
LCD_E = 1;
//_nop_(); //若晶振速度高,可在此作延时处理
LCD_E = 0; //下降沿写入数据
//_nop_(); //若晶振速度高,可在此作延时处理
}
/***********************************************************
功能:向LCD写入命令
参数: WDLCD待写入的字符数据
BusyC是否要检查忙标志位选择标志,1为进行,0为不检测
select用于选择LCD屏的左右,1选择左屏,2选择右屏
***********************************************************/
void WriteCommandLCD(unsigned char WCLCD , unsigned char BusyC,unsigned char select)
{
if(BusyC) ReadStatusLCD(select);//根据需要检测忙
switch(select)
{
case 1:{LCD_CSA=1;LCD_CSB=0;break;}//左
case 2:{LCD_CSA=0;LCD_CSB=1;break;}//右
default: break;
}
LCD_Data = WCLCD;
LCD_RS = 0;LCD_RW = 0;LCD_E = 1;
//_nop_(); //若晶振速度高,可在此作延时处理
LCD_E = 0;
}
/******************************************************************************
功能:清显示RAM区(清屏)
参数:select为驱动控制器选择 1为左 2为右
********************************************************************************/
void clear_LCD(unsigned char select)
{
unsigned char i,j;
for(i=0;i<8;i++)
{ //8页,换页清零
WriteCommandLCD( 0xb8|i,1 ,select);//页面地址设置,并分别写入左右模块中
WriteCommandLCD( 0x40,1 ,select);//列地址设置,设置为0列,并分别写入左右三个模块中
for(j=0;j<64;j++)
{ //页内清零
WriteDataLCD( 0 ,select);
}
}
}
/*****************************************************************************
功能:清LCD左右屏
*****************************************************************************/
void Clr_All_Lcd(void)
{
clear_LCD(1);
clear_LCD(2);
}
/******************************************************************************
功能:LCD初始化,分为左,右模块初始化
参数:select为驱动控制器选择 1为左 2为右
********************************************************************************/
void LcdReset(void)
{
unsigned char i;
for(i=0;i<5;i++)
{
WriteCommandLCD( 0xc0,0 ,R);//设置显示起始行为第一行,并分别写入左右模块中,不检测忙标志
WriteCommandLCD( 0xc0,0 ,L);
//_nop_(); //若晶振速度高,可在此作延时处理
}
WriteCommandLCD( 0xc0,1 ,R);//设置显示起始行为第一行,并分别写入左右模块中,检测忙标志
WriteCommandLCD( 0xc0,1 ,L);
WriteCommandLCD( 0x3f,1 ,R);//开显示设置,并分别写入左右模块中
WriteCommandLCD( 0x3f,1 ,L);
clear_LCD(R);//清左屏
clear_LCD(L);//清右屏
}
/******************************************************************************
功能:设置数据写入或读出的地址,通过页号和列数可以唯一确定一个地址
参数:Column表示列号,Page表示页号
********************************************************************************/
void set_XY(unsigned char Column,unsigned char Page)
{
unsigned char x,y;
unsigned char select;
switch (Column&0x40) //完成左右屏的判断 ,根据列号完成区分,<64为左屏,>=64为右屏
{
case 0x00: {select = 1;ReadStatusLCD(select);break;}/*为左区 */
case 0x40: {select = 2;ReadStatusLCD(select);break;}/*为右区 */
}
x = Column&0x3F|0x40; /* col.and.0x3f.or.Set Y Address*/
y = Page&0x07|0xB8; /* row.and.0x07.or.set Page */
WriteCommandLCD( y,1 ,select);//设置页面地址
WriteCommandLCD( x,1 ,select);//设置列地址
}
/******************************************************************************
功能:根据地址值(页数和列号),写入数据,即写入显示缓冲区,便可以显示在LCD屏上
参数:Column表示列号,Page表示页号,dataW表示待写入的数据
********************************************************************************/
void xy_Write(unsigned char Column,unsigned char Page,unsigned char dataW)
{
set_XY(Column,Page);
LCD_RW=0;
LCD_RS=1;
_nop_();//若晶振速度高,可在此作延时处理
LCD_Data = dataW;// 送数据
_nop_(); //若晶振速度高,可在此作延时处理
LCD_E = 1;
_nop_(); //若晶振速度高,可在此作延时处理
LCD_E= 0; // 操作允许脉冲信号,下降沿写入
}
/******************************************************************************
功能: 用于显示点阵
参数:Column表示列号,Page表示页号,
********************************************************************************/
void LcmPutDots(unsigned char Column,unsigned char Page, unsigned char DotByte )
{
unsigned char i;
i=Column;
for(;Page<8;Page++)
{
for(;Column<128;Column++)
{
xy_Write(Column,Page,DotByte);
//DotByte = ~DotByte;
}
Column=i;
}
}
/******************************************************************************
功能:在指定列,指定页显示待显示的点阵编码,用于显示16*16点阵码
参数:Column表示列号,Page表示页号,puts待显示的点阵编码首指针
********************************************************************************/
void whiteword(unsigned char Column,unsigned char Page, const unsigned char puts[][16] )
{
unsigned char i,j;
for(i=0;i<2;i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数
{
for(j=0;j<16;j++)//此处控制每行显示的列数
{
xy_Write(Column+j,Page+i,puts[i][j]);
}
}
}
/******************************************************************************
功能:在指定列,指定页显示待显示指定点阵的编码
参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行 8的倍数),V_num为列(物理列)puts待显示的点阵编码首指针
********************************************************************************/
void WhiteWord_Com(unsigned char Column,unsigned char Page,unsigned char C_num,unsigned char V_num, unsigned char * puts)
{
unsigned char i,j;
for(i=0;i<(C_num/8);i++)//此处的2为控制点阵行数,实际点阵行数为2*8=16行,此处的16(对应的点行数)应为8的倍数
{
for(j=0;j<V_num;j++)//此处控制每行显示的列数
{
xy_Write(Column+j,Page+i,*(puts+i*V_num+j));//注意地址的变化规律
}
}
}
/******************************************************************************
功能:绘点
参数:Column表示列号,Page表示页号,C_num为显示点阵的行数(物理行 8的倍数),V_num为列(物理列)puts待显示的点阵编码首指针
********************************************************************************/
void Drawing_dot(unsigned char x,unsigned char y)
{
unsigned char y_byte,x_bit,y_bit,reverse_y;//此处y_byte为page,y_bit为具体行号,x_bit为行号
unsigned char dot;
reverse_y=63-y;
x_bit=x;
y_byte=reverse_y/8;
y_bit=y%8;
// for(;x_bit<128;x_bit++)
if(y_bit==0) dot=0x80;
if(y_bit==1) dot=0x40;
if(y_bit==2) dot=0x20;
if(y_bit==3) dot=0x10;
if(y_bit==4) dot=0x08;
if(y_bit==5) dot=0x04;
if(y_bit==6) dot=0x02;
if(y_bit==7) dot=0x01;
xy_Write(x_bit,y_byte,dot);
/* reverse_y=64-y;
if(y_bit==7) y_byte=y_byte-1;
y_bit=y%8;
if(y_byte==(-1)) break;*/
}
/******************************************************************************
功能:绘垂直直线
参数:x表示列号
********************************************************************************/
void Drawing_line_vertical(unsigned char x)
{
xy_Write(x,0,0xff);
xy_Write(x,1,0xff);
xy_Write(x,2,0xff);
xy_Write(x,3,0xff);
xy_Write(x,4,0xff);
xy_Write(x,5,0xff);
xy_Write(x,6,0xff);
xy_Write(x,7,0xff);
}
主程序.c
/**********************************************************************************************
12864液晶屏上显示"南京绝妙科技发展有限公司,025-84532868 开发板欢迎使用","0~9",刷新后重显。
*************************************************************************************************/
#include<reg52.h>
#include<math.h>
#include"12864.h"
#include"zifulib.h"
#define uint unsigned int
#define uchar unsigned char
sbit adrd=P3^7; //IO口定义
sbit adwr=P3^6;
sbit cs=P2^5;
unsigned adval;
/***********************************************************
功能:延时程序
入口参数:
日期:
***********************************************************/
void DelayMs(unsigned char count)
{
unsigned int temp;
while(count--)
{
for(temp=5000;temp;temp--)
;
}
}
void adc() // 主程序
{
//********************* 启动adc0804 **********************//
adrd=1;
cs=0;
adwr=1;
adwr=0;
_nop_();
adwr=1;
//********************* 读取adc0804 **********************//
DelayMs(1);
cs=0;
adrd=0; //重新打开有AD片选信号锁存器的锁存端
adval=P1; //同时把AD的值送八个发光二极显示
}
/*************************************
显示公司名称,电话等信息
*************************************/
/*void Dis_Information(void)
{
whiteword(16,0,nan);//南
whiteword(32,0,jing);//京
whiteword(48,0,jue);//绝
whiteword(64,0,miao);//妙
whiteword(80,0,ke);//科
whiteword(96,0,ji);//技
whiteword(16,2,fa);//发
whiteword(32,2,zhan);//展
whiteword(48,2,you);//有
whiteword(64,2,xian);//限
whiteword(80,2,gong);//公
whiteword(96,2,si);//司
WhiteWord_Com(16,4,16,8,shuzi[0]);//0
WhiteWord_Com(24,4,16,8,shuzi[2]);//2
WhiteWord_Com(32,4,16,8,shuzi[5]);//5
//WhiteWord_Com(40,4,16,8,heng);//-
WhiteWord_Com(48,4,16,8,shuzi[8]);//8
WhiteWord_Com(56,4,16,8,shuzi[4]);//4
WhiteWord_Com(64,4,16,8,shuzi[5]);//5
WhiteWord_Com(72,4,16,8,shuzi[3]);//3
WhiteWord_Com(80,4,16,8,shuzi[2]);//2
WhiteWord_Com(86,4,16,8,shuzi[8]);//8
WhiteWord_Com(92,4,16,8,shuzi[6]);//6
WhiteWord_Com(100,4,16,8,shuzi[8]);//8
whiteword(16,6,kai);//开
whiteword(32,6,fa);//发
whiteword(48,6,ban);//板
whiteword(64,6,huan);//欢
whiteword(80,6,ying);//迎
whiteword(96,6,shi);//使
whiteword(112,6,yong);//用
} */
/**************************************
主函数
***************************************/
void main(void)
{
unsigned char x,i,k;//x绘图坐标
xdata unsigned char y[128];//每个x对应的y坐标
float x_float;
//unsigned x_move;//图像向右移动
//unsigned char i,j;
//DelayMs(1);//如果上电速度过快,可做适当延时,以等待LCD完成复位
LcdReset();
//DelayMs(1);//可做适当延时,以等待LCD初始化完成
whiteword(48,0,xin);
whiteword(64,0,dian);
whiteword(80,0,tu);
whiteword(96,0,yi);
DelayMs(50);
while(1)
{
for(k=0;k<128;k++)
{
x_float=2*3.14*k/32;
y[0]=sin(x_float);//画出sin正弦波形
for(i=128;i>0;i--)//实现波形的移动
{
y[i]=y[i-1];
}
Clr_All_Lcd();
for(x=0;x<128;x++)
{
Drawing_dot(x,20+y[x]);
}
}
// adc();
//y=adval/2;
/*LcmPutDots(15,2, 0xff);//
DelayMs(50);
Clr_All_Lcd();
Dis_Information();//显示公司信息
DelayMs(100);
Clr_All_Lcd();
for(j=0;j<4;j++)
{
for(i=0;i<10;i++)
{
WhiteWord_Com((i+j)*8+j,j*2,16,8,shuzi[i]);
}
DelayMs(10);
Clr_All_Lcd();
}
DelayMs(10);
Clr_All_Lcd();*/
}
}
字库文件.h
#ifndef __ZIFULIB_H__
#define __ZIFULIB_H__
/****************************************************
*****************************************************/
//******心
code unsigned char xin[2][16]={
0x00,0x00,0x80,0x00,0x00,0xE0,0x02,0x04,0x18,0x00,0x00,0x00,0x40,0x80,0x00,0x00,
0x10,0x0C,0x03,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x78,0x00,0x01,0x0E,0x00
};
//******电
code unsigned char dian[2][16]={
0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00
};
//******图
code unsigned char tu[2][16]={
0x00,0xFE,0x02,0x42,0x22,0x32,0x5E,0x92,0x52,0x32,0x12,0x02,0x02,0xFE,0x00,0x00,
0x00,0xFF,0x42,0x42,0x42,0x51,0x55,0x64,0x69,0x41,0x42,0x42,0x42,0xFF,0x00,0x00
};
//******仪
code unsigned char yi[2][16]={
0x00,0x80,0x60,0xF8,0x07,0x00,0x1C,0xE0,0x01,0x06,0x00,0xE0,0x1E,0x00,0x00,0x00,
0x01,0x00,0x00,0xFF,0x00,0x80,0x40,0x20,0x13,0x0C,0x13,0x20,0x40,0x80,0x80,0x00
};
/***************************
阿拉伯数字
***************************/
code unsigned char shuzi[10][16]={
/*-- 文字: 0 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xF0,0x08,0x08,0x18,0xE0,0x00,0x00,0x00,0x0F,0x10,0x20,0x10,0x0F,0x00,
/*-- 文字: 1 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x00,0x00,0x00,
/*-- 文字: 2 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x30,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x14,0x13,0x10,0x08,0x00,
/*-- 文字: 3 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x10,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x10,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: 4 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x1F,0x02,0x00,
/*-- 文字: 5 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x70,0x48,0xC8,0x88,0x00,0x00,0x00,0x10,0x10,0x20,0x10,0x0F,0x00,0x00,
/*-- 文字: 6 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xE0,0x90,0x88,0x80,0x00,0x00,0x00,0x07,0x18,0x20,0x20,0x19,0x06,0x00,
/*-- 文字: 7 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x10,0x08,0x08,0x88,0x78,0x00,0x00,0x00,0x00,0x00,0x18,0x07,0x00,0x00,0x00,
/*-- 文字: 8 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x78,0x88,0x88,0x78,0x00,0x00,0x00,0x0C,0x12,0x21,0x21,0x1E,0x00,0x00,
/*-- 文字: 9 --*/
/*-- 楷体_GB231212; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x60,0x98,0x08,0x08,0xF8,0xC0,0x00,0x00,0x00,0x21,0x12,0x09,0x07,0x00,0x00
};
#endif |