作业题目:通过单片机的四个按键,能画出四种图形(蜂鸣器提示);单片机型号89C52,0.96寸I2C通信 128*64OLED液晶屏模块;
题目可拆分为:
89C51I2C通信的相关配置
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
SCL = high;
SDA = high;
_nop_();
SDA = low;
_nop_();_nop_();
SCL = low;
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
SDA = low;
_nop_();
SCL = high;
_nop_();_nop_();
SDA = high;
}
/**********************************************
// IIC Write byte
**********************************************/
bit Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
bit Ack_Bit; //应答信号
for(i=0;i<8;i++)
{
if(IIC_Byte & 0x80) //1?0?
SDA=high;
else
SDA=low;
//Delay_us(1);
SCL=high;
_nop_();_nop_();
SCL=low;
//Delay_us(1);
IIC_Byte<<=1; //loop
}
SDA = high; //释放IIC SDA总线为主器件接收从器件产生应答信号
_nop_();_nop_();
SCL = high; //第9个时钟周期
_nop_();_nop_();
Ack_Bit = SDA; //读取应答信号
SCL = low;
return Ack_Bit;
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
Write_IIC_Byte(0x00); //write command
Write_IIC_Byte(IIC_Command);
IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78);
Write_IIC_Byte(0x40); //write data
Write_IIC_Byte(IIC_Data);
IIC_Stop();
}
void OLED_Init(void)
{
Delay_50ms(2); //这里的延时很重要
Write_IIC_Command(0xAE); //关显示
Write_IIC_Command(0x20); //设置内存寻址模式
Write_IIC_Command(0x10); //00,水平寻址模式;01,垂直寻址模式;10,页面寻址模式(重置);11,无效
Write_IIC_Command(0xb0); //为页面寻址模式设置页面开始地址,0-7
Write_IIC_Command(0xc8); //设置COM输出扫描方向
Write_IIC_Command(0x00); //---设置低列地址
Write_IIC_Command(0x10); //---设置高列地址
Write_IIC_Command(0x40); //--设置起始行地址
Write_IIC_Command(0x81); //--set contrast control register
Write_IIC_Command(0xff); //亮度调节 0x00~0xff
Write_IIC_Command(0xa1); //--设置段重新映射0到127
Write_IIC_Command(0xa6); //--设置正常显示
Write_IIC_Command(0xa8); //--设置复用比(1 ~ 64)
Write_IIC_Command(0x3F); //
Write_IIC_Command(0xa4); //0xa4,输出遵循RAM内容;0xa5,Output忽略RAM内容
Write_IIC_Command(0xd3); //-设置显示抵消
Write_IIC_Command(0x00); //-not offset
Write_IIC_Command(0xd5); //--设置显示时钟分频/振荡器频率
Write_IIC_Command(0xf0); //--设置分率
Write_IIC_Command(0xd9); //--设置pre-charge时期
Write_IIC_Command(0x22); //
Write_IIC_Command(0xda); //--设置com大头针硬件配置
Write_IIC_Command(0x12);
Write_IIC_Command(0xdb); //--设置vcomh
Write_IIC_Command(0x20); //0x20,0.77xVcc
Write_IIC_Command(0x8d); //--设置DC-DC
Write_IIC_Command(0x14); //--打开电荷泵
Write_IIC_Command(0xaf); //--打开oled面板
}
void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
Write_IIC_Command(0xb0+y);
Write_IIC_Command(((x&0xf0)>>4)|0x10);
Write_IIC_Command((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)//全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
Write_IIC_Command(0xb0+m); //page0-page1
Write_IIC_Command(0x00); //low column start address
Write_IIC_Command(0x10); //high column start address
for(n=0;n<128;n++)
{
Write_IIC_Data(fill_Data);
}
}
}
void OLED_CLEAR(void)//清屏
{
OLED_Fill(0x00);
}
//--------------------------------------------------------------
//让OLED休眠 – 休眠模式下,OLED功耗不到10uA
void OLED_OFF(void)
{
Write_IIC_Command(0X8D); //设置电荷泵
Write_IIC_Command(0X10); //关闭电荷泵
Write_IIC_Command(0XAE); //OLED休眠
}
void OLED_ON(void)
{
Write_IIC_Command(0X8D); //设置电荷泵
Write_IIC_Command(0X14); //打开电荷泵
Write_IIC_Command(0XAF); //OLED启动
}
//--------------------------------------------------------------
void OLED_ShowChar(uchar x,uchar y,uchar chr)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1){
x=0;y=y+2;}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
Write_IIC_Data(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
Write_IIC_Data(F8X16[c*16+i+8]);
}
void OLED_ShowString(uchar x,uchar y,uchar *chr)
{
unsigned char j=0;
while (chr[j]!='\0')
{
OLED_ShowChar(x,y,chr[j]);
x+=8;
if(x>120){
x=0;y+=2;}
j++;
}
}
unsigned long oled_pow(uchar m,uchar n)
{
unsigned long result=1;
while(n--)result*=m;
return result;
}
void OLED_ShowNum(uchar x,uchar y,unsigned long num,uchar len,uchar size2)
{
uchar t,temp;
uchar enshow=0;
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+(size2/2)*t,y,' ');
continue;
}else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0');
}
}
//--------------------------------------------------------------
// Prototype : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls :
// Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCHinese(uchar x,uchar y,uchar no)
{
uchar t,adder=0;
OLED_SetPos(x,y);
for(t=0;t<16;t++)
{
Write_IIC_Data(Hzk[2*no][t]);
adder+=1;
}
OLED_SetPos(x,y+1);
for(t=0;t<16;t++)
{
Write_IIC_Data(Hzk[2*no+1][t]);
adder+=1;
}
}
//--------------------------------------------------------------
// Prototype : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls :
// Parameters : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description : 显示BMP位图
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0)
y = y1/8;
else
y = y1/8 + 1;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
Write_IIC_Data(BMP[j++]);
}
}
}
图片制作:尺寸大小 >> 转BMP格式 >> 取模
通过PS制作需要大小的图片,导出为.jpg格式,使用Image2Lcd 2.9装换为BMP格式,用PCtoLCD2002完美版取模。
89C52单片机按键,蜂鸣器
void main(void)
{
unsigned char num_photo = 0;
unsigned char Hz = 0;
OLED_Init();
Delay_1ms(5);
while(1)
{
if(key_1 == 0)
{
num_photo = 1;
for(Hz = 0; Hz < 200; Hz++)
{
beep=~beep;
delay(200);
}
OLED_CLEAR();//清屏
}
if(key_2 == 0)
{
num_photo = 2;
for(Hz = 0; Hz < 200; Hz++) //open beep
{
beep=~beep;
delay(200);
}
OLED_CLEAR();//清屏
}
if(key_3 == 0)
{
num_photo = 3;
for(Hz = 0; Hz < 200; Hz++) //open beep
{
beep=~beep;
delay(200);
}
OLED_CLEAR();//清屏
}
if(key_4 == 0)
{
num_photo = 4;
for(Hz = 0; Hz < 200; Hz++) //open beep
{
beep=~beep;
delay(200);
}
OLED_CLEAR();//清屏
}
if(num_photo == 1)
{
Delay_1ms(5);
OLED_DrawBMP(0,0,128,8,BMP1); // show photo_1
}
if(num_photo == 2)
{
Delay_1ms(5);
OLED_ShowString(0,0,"xxxxxxx");
}
if(num_photo == 3)
{
Delay_1ms(5);
OLED_ShowString(0,2,"xxxxx xxxxxx xxxxxxxxx");
}
if(num_photo == 4)
{
Delay_1ms(5);
OLED_ShowString(0,4,"xxxxx");
}
}
}
三连后私信博主,送工程文件(含Image2Lcd 2.9、PCtoLCD2002)
侵删,谢谢!