STM32 OLED屏的使用


 

 

//-----------------OLED端口預定義----------------

#define OLED_SCL_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_0)   //CLK SCL   置0
#define OLED_SCL_Set() GPIO_SetBits(GPIOA,GPIO_Pin_0)

#define OLED_SDA_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_1)   //MOSI SDA   置0
#define OLED_SDA_Set() GPIO_SetBits(GPIOA,GPIO_Pin_1)

#define OLED_RES_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_2)   //RES 復位   置0        
#define OLED_RES_Set() GPIO_SetBits(GPIOA,GPIO_Pin_2)

#define OLED_DC_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_3)    //DC 數據/命令選擇  置0
#define OLED_DC_Set() GPIO_SetBits(GPIOA,GPIO_Pin_3)

#define OLED_CS_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)     //CS  片選  置0
#define OLED_CS_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)

//使用STM32 的PA0、PA1、PA2、PA3、PA4的IO口

//OLED模塊只支持向模塊寫數據不能讀數據,所以只需要寫SPI發送 MOSI SDA即可

#define OLED_CMD 0 //寫命令
#define OLED_DATA 1 //寫數據

 

//***  自定義的 24*24 ASICII字庫  ******************************************************

 const unsigned char asc2_2412[ ][36]={   

{0x00,0x00,0x80,0xC0,0x60,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,

0x00,0x01,0xFF,0xFE,0x00,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x18,0x0E,0x07,0x01,0x00},// "0"  0 
{0x00,0x00,0x80,0x80,0x80,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x00,0x00},// "1"   1
{0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0x03,0x03,0x00,0x80,0x40,0x20,

0x38,0x1F,0x07,0x00,0x00,0x00,0x1C,0x1A,0x19,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00},//"2"   2

{0x00,0x00,0x00,0x00,0x80,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7C,0x43,0x40,0x47,

0x7F,0xF8,0x80,0x00,0x00,0x10,0x18,0x1F,0x10,0x00,0x00,0x00,0x00,0x13,0x1F,0x1C,0x10}, //"A" 4
{0x20,0xE0,0xE0,0x20,0x20,0x20,0x20,0x60,0xC0,0x80,0x00,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10,0x10,

0x18,0x2F,0xE7,0x80,0x00,0x10,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x18,0x0F,0x07,0x00},//"B"   5 
{0x00,0x00,0x80,0xC0,0x40,0x20,0x20,0x20,0x20,0x60,0xE0,0x00,0x00,0xFC,0xFF,0x01,0x00,0x00,0x00,

0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x07,0x0E,0x18,0x10,0x10,0x10,0x08,0x04,0x03,0x00},//"C"  6

                                                              }

//****  自定義的漢字庫Hzk [ ][32]  *****************************

//字庫代碼用取模軟件  PCtoLCD等生成字母、漢字、圖片等生成。

const unsigned char Hzk [ ][32] = {

{0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,0x01,0x00,0x00,

0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00}, //"你"   0
{0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,0x40,0x22,0x15,

0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00}, //"好"    1 

                                                     }

//***************************************************************************************************

//*** OLED的初始化 *****************************************************************************
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能A端口時鍾
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                            //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                           //速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);                                                      //初始化GPIOA
GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_15);
                                                                                                                       //初始IO置1
OLED_RES_Clr();                                //復位拉低
delay_ms(200);                                     //延時
OLED_RES_Set();                                //復位結束拉高

OLED_WR_Byte(0xAE,OLED_CMD);  //亮屏滅屏指令 OFF/ON: AE/AF)
OLED_WR_Byte(0x00,OLED_CMD);  //設起始列地址指令,用8位中低4位
OLED_WR_Byte(0x10,OLED_CMD);  //設起始列地址指令,用8位中高4位
OLED_WR_Byte(0x40,OLED_CMD);  //設起始行地址指令 

OLED_WR_Byte(0x81,OLED_CMD);  // 81對比度設置指令,接着發送一個值來設置
OLED_WR_Byte(0xCF,OLED_CMD);  // 屏幕對比度值(0X00--0XFF),FF最大
OLED_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(0xA8,OLED_CMD);  //設置驅動路數指令 (1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);   // 默認0X3F(1/64) duty
OLED_WR_Byte(0xD3,OLED_CMD);  //設置顯示偏移指令 (0x00~0x3F)
OLED_WR_Byte(0x00,OLED_CMD);  //-00 不偏移
OLED_WR_Byte(0xd5,OLED_CMD);  //設置時鍾分頻因子,震盪頻率指令
OLED_WR_Byte(0x80,OLED_CMD);  //[3:0],分頻因子;[7:4],震盪頻率t Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,OLED_CMD);  //設置預充電周期指令,下面跟值
OLED_WR_Byte(0xF1,OLED_CMD);  //預充15時鍾/放電1時鍾 [3:0],PHASE 1;[7:4],PHASE 2;
OLED_WR_Byte(0xDA,OLED_CMD);  //設置COM硬件引腳配置 下面跟值
OLED_WR_Byte(0x12,OLED_CMD);  //[5:4]配置
OLED_WR_Byte(0xDB,OLED_CMD);  //設置VCOMH 電壓倍率指令,下面跟值
OLED_WR_Byte(0x40,OLED_CMD);  //40 Deselect Level,[6:4] 000,0.65*vcc;001,011,0.83*vcc;
OLED_WR_Byte(0x20,OLED_CMD);  //設置內存地址模式 (0x00/0x01/0x02) 下面跟值
OLED_WR_Byte(0x02,OLED_CMD);  //[1:0],00/列地址模式,01/行地址模式,10/頁地址模式,默認10;
OLED_WR_Byte(0x8D,OLED_CMD);  //電荷泵的指令,下面跟值
OLED_WR_Byte(0x14,OLED_CMD);  //bit2,開啟/關閉(0為關閉,1為開啟)(0x10) disable
OLED_WR_Byte(0xA4,OLED_CMD);  //全局顯示開啟,bit0: 1/開啟,0/關閉;(白屏/黑屏) (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD); //設置正常顯示方式;bit0:0/A6,全屏黑底藍字;反相顯示bit0:1/A7,黑字藍底
OLED_Clear();
OLED_WR_Byte(0xAF,OLED_CMD);// 亮屏
}

 

//*****  寫字節函數  ****************************************************************************

void OLED_WR_Byte(u8 dat,u8 cmd)     // 數據/命令標志, 0表示命令,1表示數據
{
u8 i;
if(cmd)                                                      //如果cmd=1,是命令
     OLED_DC_Set();                                 //DC置1
else
     OLED_DC_Clr();                                  //cmd=0,是數據DC置0
OLED_CS_Clr();                                       //CS置0 芯片使能
for(i=0;i<8;i++)                                          //8位數據循環移位 
      {
       OLED_SCL_Clr();                              //SCL置0
       if(dat&0x80)                                       //數據和0x80與,判斷數據最高位是否=1 
            OLED_SDA_Set();                       //最高位=1,MOSI SDA輸出1
       else
            OLED_SDA_Clr();                        //最高位=0,MOSI SDA 輸出0
       OLED_SCL_Set(); //CLK置1
       dat<<=1;                                           //最高移位移走,次高位頂上
       }
OLED_CS_Set();                                     //發送完畢,片選置1 失能
OLED_DC_Set();                                     //命令數據選擇重置1
}

 

//***  更新OLED顯存 (1屏126*64點)  ************************************************
void OLED_Refresh(void)
{
  u8 i,n;
  for(i=0;i<8;i++) //i為屏映射數組的行/頁,上下共8頁,每行/頁8位*128位/列
{
  OLED_WR_Byte(0xb0+i,OLED_CMD);                      //設置行起始地址,實際用該字節低3位 0-8頁就夠了
  OLED_WR_Byte(0x00,OLED_CMD);                         //設置低8位,實際用該字節低4位 列起始地址
  OLED_WR_Byte(0x10,OLED_CMD);                         //設置高8位,實際用該字節高4位 0-127列就夠了
   for(n=0;n<128;n++)                                                     //n為屏映射數組的列,左右共128列,1行1列是8位
   // for(n=0;n<130;n++)                                                  //屏邊框亮條可修改此值
  OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);   //OLED_DATA預定義為1/數據
}                                                       //用i頁n列取屏映射數組GRAM內對應的數據,該數據刷OLED對應的點
}                                                       //OLED收到數據刷新屏幕對應點后,按設置的刷新模式(頁地址模式),
                                                        //OLED行不動列地址自動加1,等待再次接收數據。
 

//*** 清屏函數 ****************************************************************************************************
void OLED_Clear(void)
{
  u8 i,n;
  for(i=0;i<8;i++)
      {
       for(n=0;n<128;n++)
             {
              OLED_GRAM[n][i]=0;           //清除所有數據數組
              }
       }
 OLED_Refresh();                              //空數組刷新顯示
 }

//***  畫點  *********************************************************
//x:0~127  y:0~63  t:1填充 /0清空
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
  u8 i,m,n;
  i=y/8;           //輸入的Y坐標要除以8,以定位到要改變的那個點的相應字節,因為是以字節形式來寫入的
  m=y%8;                                                          // 該點在該字節中的位置                
  n=1<<m;                                                         //屏坐標和數組是上下相反,要把該點y坐標左移寫入n
  if(t)

       {OLED_GRAM[x][i]|=n;}                            //t=1,就把該點寫1 
  else
     {
       OLED_GRAM[x][i]=~OLED_GRAM[x][i];
       OLED_GRAM[x][i]|=n;
       OLED_GRAM[x][i]=~OLED_GRAM[x][i];
     }
 }

 

//*** 在指定位置顯示一個字符,包括部分字符 ***********************************************
//x:0~127
//y:0~63
//size1:選擇字體 6x8/6x12/8x16/12x24
//mode:0,反色顯示;1,正常顯示
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode)
{
u8 i,m,temp,size2,chr1;
u8 x0=x,y0=y;
if(size1==8)size2=6;
else size2=(size1/8+((size1%8)?1:0))*(size1/2);   //得到字體一個字符對應點陣集所占的字節數
chr1=chr-' ';                                                            //計算偏移后的值
for(i=0;i<size2;i++)
{
if(size1==8)
     {temp=asc2_0806[chr1][i];} //調用0806字體
else if(size1==12)
    {temp=asc2_1206[chr1][i];} //調用1206字體
else if(size1==16)
    {temp=asc2_1608[chr1][i];} //調用1608字體
else if(size1==24)
    {temp=asc2_2412[chr1][i];} //調用2412字體
else return;
for(m=0;m<8;m++)
   {
    if(temp&0x01)OLED_DrawPoint(x,y,mode);
    else OLED_DrawPoint(x,y,!mode);
    temp>>=1;
    y++;
   }
x++;
if((size1!=8)&&((x-x0)==size1/2))
    { x=x0;y0=y0+8;}
      y=y0;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM