主控芯片(STC90C516RD+PG5151028)介绍
ROM=64K,RAM=1280字节,40Pin,3个定时器,1个串口,8个中断源(分别是:外部中断0(INTO)、外部中断 1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)、定时器 0中断、定时器 1 中断、定时器 2 中断、串口(UART)中断),所有的中断都具有4个中断优先级
1.LCD1602
1.1.LCD1602简介
1602 液晶也叫 1602 字符型液晶,它能显示 2 行字符信息,每行又能显示 16个字符。它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若干个 5x7 或者 5x10 的点阵字符位组成,每个点阵字符位都可以用显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。
引脚说明(16引脚):
VSS: 电源地
VDD:电源正极(+5V)
VO:液晶显示偏压信号,用于调整 LCD1602 的显示对比度,一般会外接电位器用以调整偏压信号,注意此脚电压为 0 时可以得到最强的对比度。
RS:数据/命令选择端,当此脚为高电平时,可以对 1602 进行数据字节的传输操作,而为低电平时,则是进行命令字节的传输操作。命令字节,即是用来对 LCD1602 的一些工作方式作设置的字节;数据字节,即使用以在 1602 上显示的字节。值得一提的是,LCD1602 的数据是 8 位的。
RW:读写选择端。当此脚为高电平可对 LCD1602 进行读数据操作,反之进行写数据操作。
E:使能信号,其实是 LCD1602 的数据控制时钟信号,利用该信号的上升沿实现对 LCD1602 的数据传输。
D0-D7:8 位并行数据口,而 51 单片机一组 IO 也是 8 位,使得对 LCD1602的数据读写大为方便。
A:背光源正极
K:背光源负极
在 LCD1602 内部含有 80 个字节的 DDRAM,它是用来寄存显示字符的。不是所有的地址都可以直接用来显示字符数据,只有第一行中的 00-0F,第二行中的 40-4F 才能显示,其他地址只能用于存储。
LCD1602 操作步骤如下所示: (1)初始化 (2)写命令(RS=L),设置显示坐标 (3)写数据(RS=H)
①当要写指令字,设置 LCD1602 的工作方式时:需要把 RS 置为低电平,RW置为低电平,然后将数据送到数据口 D0~D7,最后 E 引脚一个高脉冲将数据写入。
②当要写入数据字,在 1602 上实现显示时:需要把 RS 置为高电平,RW 置为低电平,然后将数据送到数据口 D0~D7,最后 E 引脚一个高脉冲将数据写入。
硬件连接:
VSS------GND
VDD------5V
RS-------P2.6
RW-------P2.5
E--------P2.7
D0-D7-------P0
VO---------RJ6调节背光
1.2驱动代码
led.h
#ifndef __LCD_H_
#define __LCD_H_/**********************************
包含头文件
**********************************/
#include<reg52.h>//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c); //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/
void LcdWriteData(uchar dat) ;
/*LCD1602初始化子程序*/
void LcdInit();
void lcd_clear();
void lcd_show_string(uchar x,uchar y,uchar *str); #endif
lcd.c
#include "lcd.h"/*******************************************************************************
* 函 数 名 : Lcd1602_Delay1ms
* 函数功能 : 延时函数,延时1ms
* 输 入 : c
* 输 出 : 无
* 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/void Lcd1602_Delay1ms(uint c) //误差 0us
{uchar a,b;for (; c>0; c--){for (b=199;b>0;b--){for(a=1;a>0;a--);} }}/*******************************************************************************
* 函 数 名 : LcdWriteCom
* 函数功能 : 向LCD写入一个字节的命令
* 输 入 : com
* 输 出 : 无
*******************************************************************************/void LcdWriteCom(uchar com) //写入命令
{LCD1602_E = 0; //使能LCD1602_RS = 0; //选择发送命令LCD1602_RW = 0; //选择写入LCD1602_DATAPINS = com; //放入命令Lcd1602_Delay1ms(1); //等待数据稳定LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5); //保持时间LCD1602_E = 0;
}/*******************************************************************************
* 函 数 名 : LcdWriteData
* 函数功能 : 向LCD写入一个字节的数据
* 输 入 : dat
* 输 出 : 无
*******************************************************************************/ void LcdWriteData(uchar dat) //写入数据
{LCD1602_E = 0; //使能清零LCD1602_RS = 1; //选择输入数据LCD1602_RW = 0; //选择写入LCD1602_DATAPINS = dat; //写入数据Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5); //保持时间LCD1602_E = 0;
}/*******************************************************************************
* 函 数 名 : LcdInit()
* 函数功能 : 初始化LCD屏
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void LcdInit() //LCD初始化子程序
{LcdWriteCom(0x38); //开显示LcdWriteCom(0x0c); //开显示不显示光标LcdWriteCom(0x06); //写一个指针加1LcdWriteCom(0x01); //清屏LcdWriteCom(0x80); //设置数据指针起点
}/*******************************************************************************
* 函 数 名 : lcd_clear
* 函数功能 : LCD 清屏
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void lcd_clear()
{LcdWriteCom(0x01);
}/*******************************************************************************
* 函 数 名 : lcd_show_string
* 函数功能 : LCD 显示字符
* 输 入 : x,y:显示坐标,x=0~15,y=0~1;str:显示字符串
* 输 出 : 无
*******************************************************************************/void lcd_show_string(uchar x,uchar y,uchar *str)
{uchar i = 0;if(y>1||x>15)return;//行列参数不对则强制退出if(y<1) //第 1 行显示{while(*str!='\0')//字符串是以'\0'结尾,只要前面有内容就显示{if(i<16-x)//如果字符长度超过第一行显示范围,则在第二行继续显示{LcdWriteCom(0x80+i+x);//第一行显示地址设置}else{LcdWriteCom(0x40+0x80+i+x-16);//第二行显示地址设置}LcdWriteData(*str);//显示内容str++;//指针递增i++;}}else{while(*str!='\0'){if(i<16-x) //如果字符长度超过第二行显示范围,则在第一行继续显示LcdWriteCom(0x80+0x40+i+x); elseLcdWriteCom(0x80+i+x-16);LcdWriteData(*str);//显示内容str++;//指针递增i++;}}}
main.c
/**************************************************************************************
* LCD1602液晶显示实验 *
实现现象: 具体接线操作请参考视频教程下载程序后插上LCD1602液晶在开发板上,即可显示
注意事项:
***************************************************************************************/#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "lcd.h"typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{LcdInit();lcd_clear();lcd_show_string(0,0,"Hello World!");//第一行显示lcd_show_string(0,1,"0123456789");//第二行显示while(1);
}
1.3显示效果图
2.LCD12864
2.1LCD12864简介
12864 是以 128 列像素,64 行像素,也就是有 12864 个像素点组成,通常显示一个汉字需要 1616 个像素点,所以 LCD12864 一行最多能显示 8个汉字,最多能显示 4 行。通常显示一个字符需要 8*8 个像素点,所以 LCD12864 一行最多能显示 16 个字符,最多能显示 8 行。
引脚说明(16引脚):
GND:电源地(0V)
VCC:电压输入(+5V)
RS:寄存器选择端,高:读操作 低:写操作
RD:读使能,低电平有效,高电平读失能
WR:读写信号,高:读操作 低:写操作
D0-D7:数据总线
CS:片选信号,低有效
RESET:复位信号,低有效
从上图可知,LCD12864 能直接显示的地址范围如下:
第一行:0X80-0X87;(一个汉字占用 2 个字节,共 8 个汉字)
第二行:0X90-0X97;
第三行:0X88-0X8F;
第四行:0X98-0X9F;
不带字库的 LCD12864 背面没有芯片,一般为转接板,将 12864 显示屏转接到开发板,所有的显示都需要取模,取模方法和点阵取模一样。内部驱动芯片是 ST7565P,ST7565P 数据手册是液晶屏内核手册,里面有驱动方法和指令和程序有关的数据。
硬件连接:
D0-D7--------P0
CS-----------P3.2
RESET--------P3.3
RS-----------P2.6
RW-----------P2.7
RD-----------P2.5
2.2驱动代码
lcd12864.h
#ifndef __ST7565_H
#define __ST7565_H#include<reg51.h>
#include<intrins.h>//---包含字库头文件
#define CHAR_CODE//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif#ifndef uint
#define uint unsigned int
#endif//--定时使用的IO口--//
#define DATA_PORT P0
sbit LCD12864_CS = P3^2;
sbit LCD12864_RSET = P3^3;
sbit LCD12864_RS = P2^6;
sbit LCD12864_RW = P2^7;
sbit LCD12864_RD = P2^5;//--定义全局函数--//
void LcdSt7565_WriteCmd(cmd);
void LcdSt7565_WriteData(dat);
void Lcd12864_Init();
void Lcd12864_ClearScreen(void);
uchar Lcd12864_Write16CnCHAR(uchar x, uchar y, uchar *cn);#endif
lcd12864.c
#include"st7565.h"/*******************************************************************************
* 函 数 名 : LCD12864_WriteCmd
* 函数功能 : 写入一个命令到12864
* 输 入 : cmd
* 输 出 : 无
*******************************************************************************/void LcdSt7565_WriteCmd(cmd)
{LCD12864_CS = 0; //chip select,打开片选LCD12864_RD = 1; //disable read,读失能 LCD12864_RS = 0; //select command,选择命令LCD12864_RW = 0; //select write,选择写模式_nop_();_nop_();DATA_PORT = cmd; //put command,放置命令_nop_();_nop_();LCD12864_RW = 1; //command writing ,写入命令
}/*******************************************************************************
* 函 数 名 : LcdSt7565_WriteData
* 函数功能 : 写入一个数据到12864
* 输 入 : dat
* 输 出 : 无
*******************************************************************************/void LcdSt7565_WriteData(dat)
{ LCD12864_CS = 0; //chip select,打开片选LCD12864_RD = 1; //disable read,读失能 LCD12864_RS = 1; //select data,选择数据LCD12864_RW = 0; //select write,选择写模式_nop_();_nop_();DATA_PORT = dat; //put data,放置数据_nop_();_nop_();LCD12864_RW = 1; //data writing,写数据
}/*******************************************************************************
* 函 数 名 : LCD12864_Init
* 函数功能 : 初始化12864
* 输 入 : 无
* 输 出 : 无
* 说 明 : LCD12864的命令指令可以查看例程文件夹下的《ST7565p数据手册》
* * 的第51页的位置。
*******************************************************************************/void Lcd12864_Init()
{uchar i;LCD12864_RSET = 0;for (i=0; i<100; i++);LCD12864_CS = 0;LCD12864_RSET = 1;//----------------Star Initial Sequence-------////------程序初始化设置,具体命令可以看文件夹下---////--软件初始化--//LcdSt7565_WriteCmd(0xE2); //resetfor (i=0; i<100; i++); //延时一下//--表格第8个命令,0xA0段(左右)方向选择正常方向(0xA1为反方向)--//LcdSt7565_WriteCmd(0xA1); //ADC select segment direction //--表格第15个命令,0xC8普通(上下)方向选择选择反向,0xC0为正常方向--// LcdSt7565_WriteCmd(0xC8); //Common direction //--表格第9个命令,0xA6为设置字体为黑色,背景为白色---////--0xA7为设置字体为白色,背景为黑色---//LcdSt7565_WriteCmd(0xA6); //reverse display//--表格第10个命令,0xA4像素正常显示,0xA5像素全开--//LcdSt7565_WriteCmd(0xA4); //normal display//--表格第11个命令,0xA3偏压为1/7,0xA2偏压为1/9--//LcdSt7565_WriteCmd(0xA2); //bias set 1/9//--表格第19个命令,这个是个双字节的命令,0xF800选择增压为4X;--////--0xF801,选择增压为5X,其实效果差不多--// LcdSt7565_WriteCmd(0xF8); //Boost ratio setLcdSt7565_WriteCmd(0x01); //x4//--表格第18个命令,这个是个双字节命令,高字节为0X81,低字节可以--////--选择从0x00到0X3F。用来设置背景光对比度。---/LcdSt7565_WriteCmd(0x81); //V0 a setLcdSt7565_WriteCmd(0x23);//--表格第17个命令,选择调节电阻率--//LcdSt7565_WriteCmd(0x25); //Ra/Rb set//--表格第16个命令,电源设置。--//LcdSt7565_WriteCmd(0x2F);for (i=0; i<100; i++);//--表格第2个命令,设置显示开始位置--//LcdSt7565_WriteCmd(0x40); //start line//--表格第1个命令,开启显示--//LcdSt7565_WriteCmd(0xAF); // display onfor (i=0; i<100; i++);}/*******************************************************************************
* 函 数 名 : LCD12864_ClearScreen
* 函数功能 : 清屏12864
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Lcd12864_ClearScreen(void)
{uchar i, j;for(i=0; i<8; i++){//--表格第3个命令,设置Y的坐标--////--Y轴有64个,一个坐标8位,也就是有8个坐标--////所以一般我们使用的也就是从0xB0到0x07,就够了--// LcdSt7565_WriteCmd(0xB0+i); //--表格第4个命令,设置X坐标--////--当你的段初始化为0xA1时,X坐标从0x10,0x04到0x18,0x04,一共128位--////--当你的段初始化为0xA0时,X坐标从0x10,0x00到0x18,0x00,一共128位--////--在写入数据之后X坐标的坐标是会自动加1的,我们初始化使用0xA0所以--////--我们的X坐标从0x10,0x00开始---//LcdSt7565_WriteCmd(0x10); LcdSt7565_WriteCmd(0x04); //--X轴有128位,就一共刷128次,X坐标会自动加1,所以我们不用再设置坐标--//for(j=0; j<128; j++){LcdSt7565_WriteData(0x00); //如果设置背景为白色时,清屏选择0XFF}}
}/*******************************************************************************
* 函 数 名 : LCD12864_Write16CnCHAR
* 函数功能 : 在12864上面书写16X16的汉字
* 输 入 : x, y, cn
* 输 出 : 无
* 说 明 : 该函数可以直接书写字符串,但是书写是从右到左,所以输入的时
* * 侯注意输入。汉字的取模方式请观看文件夹下的《汉字取模软件的
* * 使用说明》
*******************************************************************************/#ifdef CHAR_CODE#include"charcode.h"uchar Lcd12864_Write16CnCHAR(uchar x, uchar y, uchar *cn)
{uchar j, x1, x2, wordNum;//--Y的坐标只能从0到7,大于则直接返回--//if(y > 7){return 0;}//--X的坐标只能从0到128,大于则直接返回--//if(x > 128){return 0;}y += 0xB0; //求取Y坐标的值//--设置Y坐标--//LcdSt7565_WriteCmd(y);while ( *cn != '\0') //在C语言中字符串结束以‘\0’结尾{ //--设置Y坐标--//LcdSt7565_WriteCmd(y);x1 = (x >> 4) & 0x0F; //由于X坐标要两句命令,分高低4位,所以这里先取出高4位x2 = x & 0x0F; //去低四位//--设置X坐标--//LcdSt7565_WriteCmd(0x10 + x1); //高4位LcdSt7565_WriteCmd(0x04 + x2); //低4位for (wordNum=0; wordNum<50; wordNum++){//--查询要写的字在字库中的位置--//if ((CN16CHAR[wordNum].Index[0] == *cn)&&(CN16CHAR[wordNum].Index[1] == *(cn+1))){for (j=0; j<32; j++) //写一个字{ if (j == 16) //由于16X16用到两个Y坐标,当大于等于16时,切换坐标{//--设置Y坐标--//LcdSt7565_WriteCmd(y + 1);//--设置X坐标--//LcdSt7565_WriteCmd(0x10 + x1); //高4位LcdSt7565_WriteCmd(0x04 + x2); //低4位}LcdSt7565_WriteData(CN16CHAR[wordNum].Msk[j]);}x += 16;}//if查到字结束 } //for查字结束 cn += 2;} //while结束return 1;
}#endif
main.c
#include<reg51.h>
#include"st7565.h"//---声明一个全局变量---//
void Delay10ms(unsigned int c);/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void main()
{uchar i = 128;Lcd12864_Init();Lcd12864_ClearScreen();while (1){for (i=0; i<2; i += 2){Lcd12864_ClearScreen();//--由于这个函数显示方向正好相反--//Lcd12864_Write16CnCHAR(32, i, "钟时子电气天");Delay10ms(100);}}
}/*******************************************************************************
* 函 数 名 : Delay10ms
* 函数功能 : 延时函数,延时10ms
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void Delay10ms(unsigned int c) //误差 0us
{unsigned char a,b;for(;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);
}
2.3显示效果图
3.OLED(IIC)
3.1简介
OLED显示和传统的LCD显示不同,其可以自发光,所以不需要背光灯,这使得OLED显示屏相对于LCD显示屏尺寸更薄,同时显示效果更优。 常用的OLED屏幕有蓝色、黄色、白色等几种。屏的大小为0.96寸,像素点为 128*64,所以我们称为0.96oled屏或者12864屏。电源电压为3.3-5.5V,驱动芯片为SSD1306
硬件连接
GND-------OLED模块电源地
VCC-------OLED模块电源正极(3.3V/5V)
SCL--------IIC总线时钟信号,P0.2
SDA--------IIC总线数据信号,P0.3
3.2代码
oled.h
#ifndef __OLED_H
#define __OLED_H
#include <reg52.h>#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned int#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据sbit OLED_SCL=P0^2;//SCL
sbit OLED_SDA=P0^3;//SDA
sbit OLED_RES =P0^4;//RES//-----------------OLED端口定义----------------#define OLED_SCL_Clr() OLED_SCL=0
#define OLED_SCL_Set() OLED_SCL=1#define OLED_SDA_Clr() OLED_SDA=0
#define OLED_SDA_Set() OLED_SDA=1#define OLED_RES_Clr() OLED_RES=0
#define OLED_RES_Set() OLED_RES=1//OLED控制用函数
void delay_ms(unsigned int ms);
void OLED_ColorTurn(u8 i);
void OLED_DisplayTurn(u8 i);
void OLED_WR_Byte(u8 dat,u8 cmd);
void OLED_Set_Pos(u8 x, u8 y);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Clear(void);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey);
u32 oled_pow(u8 m,u8 n);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey);
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey);
void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey);
void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[]);
void OLED_Init(void);#endif
oled.c
#include "oled.h"
#include "oledfont.h" //OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
void delay_ms(unsigned int ms)
{ unsigned int a;while(ms){a=1800;while(a--);ms--;}return;
}//反显函数
void OLED_ColorTurn(u8 i)
{if(i==0){OLED_WR_Byte(0xA6,OLED_CMD);//正常显示}if(i==1){OLED_WR_Byte(0xA7,OLED_CMD);//反色显示}
}//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{if(i==0){OLED_WR_Byte(0xC8,OLED_CMD);//正常显示OLED_WR_Byte(0xA1,OLED_CMD);}if(i==1){OLED_WR_Byte(0xC0,OLED_CMD);//反转显示OLED_WR_Byte(0xA0,OLED_CMD);}
}//起始信号
void I2C_Start(void)
{OLED_SDA_Set();OLED_SCL_Set();OLED_SDA_Clr();OLED_SCL_Clr();}//结束信号
void I2C_Stop(void)
{OLED_SDA_Clr();OLED_SCL_Set();OLED_SDA_Set();
}//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{OLED_SDA_Set();OLED_SCL_Set();OLED_SCL_Clr();}//写入一个字节
void Send_Byte(u8 dat)
{u8 i;for(i=0;i<8;i++){OLED_SCL_Clr();//将时钟信号设置为低电平if(dat&0x80)//将dat的8位从最高位依次写入{OLED_SDA_Set();}else{OLED_SDA_Clr();}OLED_SCL_Set();OLED_SCL_Clr();dat<<=1;}
}//发送一个字节
//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 mode)
{I2C_Start();Send_Byte(0x78);I2C_WaitAck();if(mode){Send_Byte(0x40);}else{Send_Byte(0x00);}I2C_WaitAck();Send_Byte(dat);I2C_WaitAck();I2C_Stop();
}//坐标设置void OLED_Set_Pos(u8 x, u8 y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD); //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{ u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新显示
}//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//sizey:选择字体 6x8 8x16
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey)
{ u8 c=0,sizex=sizey/2;u16 i=0,size1;if(sizey==8)size1=6;else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);c=chr-' ';//得到偏移后的值OLED_Set_Pos(x,y);for(i=0;i<size1;i++){if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);if(sizey==8) OLED_WR_Byte(asc2_0806[c][i],OLED_DATA);//6X8字号else if(sizey==16) OLED_WR_Byte(asc2_1608[c][i],OLED_DATA);//8x16字号
// else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号else return;}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{u32 result=1; while(n--)result*=m; return result;
}
//显示数字
//x,y :起点坐标
//num:要显示的数字
//len :数字的位数
//sizey:字体大小
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey)
{ u8 t,temp,m=0;u8 enshow=0;if(sizey==8)m=2;for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(sizey/2+m)*t,y,' ',sizey);continue;}else enshow=1;}OLED_ShowChar(x+(sizey/2+m)*t,y,temp+'0',sizey);}
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey)
{u8 j=0;while (chr[j]!='\0'){ OLED_ShowChar(x,y,chr[j++],sizey);if(sizey==8)x+=6;else x+=sizey/2;}
}
//显示汉字
void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey)
{u16 i,size1=(sizey/8+((sizey%8)?1:0))*sizey;for(i=0;i<size1;i++){if(i%sizey==0) OLED_Set_Pos(x,y++);if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号
// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号else return;}
}//显示图片
//x,y显示坐标
//sizex,sizey,图片长宽
//BMP:要显示的图片
void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[])
{ u16 j=0;u8 i,m;sizey=sizey/8+((sizey%8)?1:0);for(i=0;i<sizey;i++){OLED_Set_Pos(x,i+y);for(m=0;m<sizex;m++){ OLED_WR_Byte(BMP[j++],OLED_DATA); }}
} //初始化
void OLED_Init(void)
{OLED_RES_Clr();delay_ms(200);OLED_RES_Set();OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panelOLED_WR_Byte(0x00,OLED_CMD);//---set low column addressOLED_WR_Byte(0x10,OLED_CMD);//---set high column addressOLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control registerOLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current BrightnessOLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常OLED_WR_Byte(0xA6,OLED_CMD);//--set normal displayOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 dutyOLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)OLED_WR_Byte(0x00,OLED_CMD);//-not offsetOLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequencyOLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/SecOLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge periodOLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configurationOLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomhOLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect LevelOLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WR_Byte(0x02,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disableOLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disableOLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_Clear();OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
}
main.c
#include <reg52.h>
#include "oled.h"int main(void)
{ u8 t=' ';OLED_Init();//初始化OLEDOLED_ColorTurn(0);//0正常显示,1 反色显示OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示while(1) { OLED_ShowChinese(18,0,0,16);//OLED_ShowChinese(36,0,1,16);//OLED_ShowChinese(54,0,2,16);//OLED_ShowChinese(72,0,3,16);//OLED_ShowChinese(90,0,4,16);//OLED_ShowChinese(108,0,5,16);//OLED_ShowString(20,4,"2024/06/06",16);}
}
3.3显示效果图
4.下载链接
51驱动LCD