gaoyang9992006 发表于 2023-5-12 11:31:50

成功点亮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);
      }
    }
}

gaoyang9992006 发表于 2023-5-12 11:32:47

有个问题,我用P1的端口的,怎么都不行,这个P1有什么特殊的吗、
用的板子是免费申请的 开天斧3.1

gaoyang9992006 发表于 2023-5-12 11:43:33


电子DIY小家 发表于 2023-5-12 14:24:28

P1端口没问题的,这个IIC的屏幕要注意以下几点
1.选择的引脚记得对照下原理图,是不是接到了什么别的元器件或者芯片上
2.IIC需要上啦电阻,没有外部的上啦可以使能模块内部上啦
3.不要接错线
肯定能点亮的

gaoyang9992006 发表于 2023-5-18 14:37:15

本帖最后由 gaoyang9992006 于 2023-5-18 15:07 编辑

电子DIY小家 发表于 2023-5-12 14:24
P1端口没问题的,这个IIC的屏幕要注意以下几点
1.选择的引脚记得对照下原理图,是不是接到了什么别的元器件 ...
不好意思,我接到其他端口都是可以正常工作的,就接到这个P1对应的上没反应,我再看看是不是端口模式没设置好。
嗯,设置成推挽输出就可以了。搞定
页: [1]
查看完整版本: 成功点亮12832的OLED