成功点亮12832的OLED
#include "./comm/stc8h.h"#include <oled.h>
#define MAIN_Fosc 24000000L //定义主时钟
void delay_ms(u8 ms)
{
u16 i;
do{
i = MAIN_Fosc / 10000;
while(--i); //10T per loop
}while(--ms);
}
void main(void)
{
unsigned char i=0;
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
OLED_Init();
OLED_ColorTurn(0);//0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
OLED_Display_Off();
OLED_Display_On();
OLED_Clear_Left_To_Right();
for(i=0;i<8;i++)
NumberShow(i, 16*i, 0, 0) ;
OLED_Clear_Left_To_Right();
for(i=0;i<8;i++)
NumberShow(i, 16*i, 0, 1) ;
OLED_Clear_Left_To_Right();
while(1)
{
P20 = 0; //LED On
delay_ms(250);
P20 = 1; //LED Off
delay_ms(250);
for(i=0;i<8;i++)
NumberShow(i, 16*i, 0, 0) ;
for(i=0;i<8;i++)
NumberShow(i, 16*i, 2, 1) ;
delay_ms(500);
OLED_Clear_Left_To_Right();
for(i=0;i<8;i++)
{
OLED_Set_Pos(i,3);
OLED_WR_Byte(0xFF,OLED_DATA);
OLED_Set_Pos(i,2);
OLED_WR_Byte(0xF0,OLED_DATA);
}
for(i=10;i<18;i++)
{
OLED_Set_Pos(i,3);
OLED_WR_Byte(0xFF,OLED_DATA);
OLED_Set_Pos(i,2);
OLED_WR_Byte(0xFF,OLED_DATA);
}
}
}
#ifndef __OLED_H
#define __OLED_H
#include "./comm/stc8h.h"
#defineu8 unsigned char
#defineu16 unsigned int
#defineu32 unsigned int
#define OLED_CMD0 //写命令
#define OLED_DATA 1 //写数据
#define OLED_SCL P30 //SCL
#define OLED_SDA P31 //SDA
//-----------------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
//OLED控制用函数
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_Clear_Left_To_Right(void);
void OLED_Init(void);
void NumberShow(unsigned char numb, unsigned char x, unsigned char y, unsigned char flag);
#endif
#include "oled.h"
//#include "oledfont.h"
/*
OLED的显存存放格式如下
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
PAGE 0 1 2 3 ……127
*/
unsigned char code num[]={
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},/*"0",0*/
{0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00},/*"1",1*/
{0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},/*"2",2*/
{0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00},/*"3",3*/
{0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24},/*"4",4*/
{0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00},/*"5",5*/
{0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00},/*"6",6*/
{0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00},/*"7",7*/
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},/*"8",8*/
{0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00},/*"9",9*/
};
//反显函数
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 IIC_delay(void)
{
u8 t=1;
while(t--);
}
//起始信号
void I2C_Start(void)
{
OLED_SDA_Set();
OLED_SCL_Set();
IIC_delay();
OLED_SDA_Clr();
IIC_delay();
OLED_SCL_Clr();
}
//结束信号
void I2C_Stop(void)
{
OLED_SDA_Clr();
OLED_SCL_Set();
IIC_delay();
OLED_SDA_Set();
}
//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{
OLED_SDA_Set();
IIC_delay();
OLED_SCL_Set();
IIC_delay();
OLED_SCL_Clr();
IIC_delay();
}
//写入一个字节
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();
}
IIC_delay();
OLED_SCL_Set();
IIC_delay();
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();
}
/*
坐标设置,对于128*32分辨率的OLED:x从127;y从0到3
*/
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 ON
OLED_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 OFF
OLED_WR_Byte(0XAE,OLED_CMD);//DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<4;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);
} //更新显示
}
void OLED_Clear_Left_To_Right(void)
{
u8 i,n;
for(i=0;i<128;i++)
{
for(n=0;n<4;n++)
{
OLED_WR_Byte(0xb0+n,OLED_CMD);
OLED_WR_Byte(((i&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((i&0x0f),OLED_CMD);
OLED_WR_Byte(0,OLED_DATA);
}
}
}
//初始化
void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD); /*display off*/
OLED_WR_Byte(0x00,OLED_CMD); /*set lower column address*/
OLED_WR_Byte(0x10,OLED_CMD); /*set higher column address*/
OLED_WR_Byte(0x00,OLED_CMD); /*set display start line*/
OLED_WR_Byte(0xB0,OLED_CMD); /*set page address*/
OLED_WR_Byte(0x81,OLED_CMD); /*contract control*/
OLED_WR_Byte(0xff,OLED_CMD); /*128*/
OLED_WR_Byte(0xA1,OLED_CMD); /*set segment remap*/
OLED_WR_Byte(0xA6,OLED_CMD); /*normal / reverse*/
OLED_WR_Byte(0xA8,OLED_CMD); /*multiplex ratio*/
OLED_WR_Byte(0x1F,OLED_CMD); /*duty = 1/32*/
OLED_WR_Byte(0xC8,OLED_CMD); /*Com scan direction*/
OLED_WR_Byte(0xD3,OLED_CMD); /*set display offset*/
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xD5,OLED_CMD); /*set osc division*/
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD); /*set pre-charge period*/
OLED_WR_Byte(0x1f,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD); /*set COM pins*/
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xdb,OLED_CMD); /*set vcomh*/
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x8d,OLED_CMD); /*set charge pump enable*/
OLED_WR_Byte(0x14,OLED_CMD);
OLED_Clear();
OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
}
/*
numb:显示的数字,0-9
x:坐标:0-127
y:坐标:0-3
flag:0为正显示,1为反显示
*/
void NumberShow(unsigned char numb, unsigned char x, unsigned char y, unsigned char flag) {
unsigned char i;
for (i = 0; i < 16; i++) {
if (i == 0 || i == 15) {
OLED_Set_Pos(x + i, y + 0);
OLED_WR_Byte(flag ? ~0xFF : 0xFF, OLED_DATA);
OLED_Set_Pos(x + i, y + 1);
OLED_WR_Byte(flag ? ~0xFF : 0xFF, OLED_DATA);
} else if ((i > 0 && i < 4) || (i > 12 && i < 16)) {
OLED_Set_Pos(x + i, y + 0);
OLED_WR_Byte(flag ? ~0x01 : 0x01, OLED_DATA);
OLED_Set_Pos(x + i, y + 1);
OLED_WR_Byte(flag ? ~0x80 : 0x80, OLED_DATA);
} else {
OLED_Set_Pos(x + i, y + 0);
OLED_WR_Byte(flag ? ~(0x01 | num) : (0x01 | num), OLED_DATA);
OLED_Set_Pos(x + i, y + 1);
OLED_WR_Byte(flag ? ~(0x80 | num) : (0x80 | num), OLED_DATA);
}
}
}
有个问题,我用P1的端口的,怎么都不行,这个P1有什么特殊的吗、
用的板子是免费申请的 开天斧3.1
P1端口没问题的,这个IIC的屏幕要注意以下几点
1.选择的引脚记得对照下原理图,是不是接到了什么别的元器件或者芯片上
2.IIC需要上啦电阻,没有外部的上啦可以使能模块内部上啦
3.不要接错线
肯定能点亮的 本帖最后由 gaoyang9992006 于 2023-5-18 15:07 编辑
电子DIY小家 发表于 2023-5-12 14:24
P1端口没问题的,这个IIC的屏幕要注意以下几点
1.选择的引脚记得对照下原理图,是不是接到了什么别的元器件 ...
不好意思,我接到其他端口都是可以正常工作的,就接到这个P1对应的上没反应,我再看看是不是端口模式没设置好。
嗯,设置成推挽输出就可以了。搞定
页:
[1]