本帖最后由 用户3948101 于 2023-11-12 01:32 编辑

1.如果正在使用STM32,然后想使用MM32芯片,下载并安装MM32 Series Keil pack,安装完成后可以选择MM32芯片。
2.下载官例程
下载完成后解压就可以看到下面这三个文件夹。
explorer_QUwaB5CTf1.png

后随便打开一个工程,是不是感觉工程文件夹看着眼熟,跟正点原子例程的工程文件夹很像。


3.采用模拟iic的方式驱动0.91 oled定义GPIO
/* Files include */
  • #include "hal_conf.h"
  • //-----------------OLED¶Ë¿Ú¶¨Òå----------------

  • #define OLED_SCL_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_0)//SCL
  • #define OLED_SCL_Set() GPIO_SetBits(GPIOA,GPIO_Pin_0)

  • #define OLED_SDA_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//DIN
  • #define OLED_SDA_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)

  • #define OLED_CMD  0        //дÃüÁî
  • #define OLED_DATA 1        //дÊý¾Ý

  • void OLED_Refresh(void);
  • void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode);
  • void OLED_Init(void);
  • 复制代码
    驱动代码
    /* Files include */
  • #include <stdio.h>
  • #include "oled.h"
  • #include "oledfont.h"

  • u8 OLED_GRAM[144][4];

  • //延时
  • void IIC_delay(void)
  • {
  •         u8 t=3;
  •         while(t--);
  • }

  • //起始信号
  • void I2C_Start(void)
  • {
  •         OLED_SDA_Set();
  •         OLED_SCL_Set();
  •         IIC_delay();
  •         OLED_SDA_Clr();
  •         IIC_delay();
  •         OLED_SCL_Clr();
  •         IIC_delay();
  • }

  • //结束信号
  • 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++)
  •         {
  •                 if(dat&0x80)//将dat的8位从最高位依次写入
  •                 {
  •                         OLED_SDA_Set();
  •     }
  •                 else
  •                 {
  •                         OLED_SDA_Clr();
  •     }
  •                 IIC_delay();
  •                 OLED_SCL_Set();
  •                 IIC_delay();
  •                 OLED_SCL_Clr();//将时钟信号设置为低电平
  •                 dat<<=1;
  •   }
  • }

  • //发送一个字节
  • //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();
  • }

  • //更新显存到OLED        
  • void OLED_Refresh(void)
  • {
  •         u8 i,n;
  •         for(i=0;i<4;i++)
  •         {
  •                 OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
  •                 OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
  •                 OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
  •                 I2C_Start();
  •                 Send_Byte(0x78);
  •                 I2C_WaitAck();
  •                 Send_Byte(0x40);
  •                 I2C_WaitAck();
  •                 for(n=0;n<128;n++)
  •                 {
  •                         Send_Byte(OLED_GRAM[n][i]);
  •                         I2C_WaitAck();
  •                 }
  •                 I2C_Stop();
  •   }
  • }
  • //清屏函数
  • void OLED_Clear(void)
  • {
  •         u8 i,n;
  •         for(i=0;i<4;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;
  •         m=y%8;
  •         n=1<<m;
  •         if(t){OLED_GRAM[x][i]|=n;}
  •         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;
  •   }
  • }


  • //显示字符串
  • //x,y:起点坐标  
  • //size1:字体大小
  • //*chr:字符串起始地址
  • //mode:0,反色显示;1,正常显示
  • void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode)
  • {
  •         while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
  •         {
  •                 OLED_ShowChar(x,y,*chr,size1,mode);
  •                 if(size1==8)x+=6;
  •                 else x+=size1/2;
  •                 chr++;
  •   }
  • }

  • //OLED的初始化
  • void OLED_Init(void)
  • {
  •         GPIO_InitTypeDef  GPIO_InitStructure;
  •         RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);         //使能A端口时钟
  •         GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_3);
  •         GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_3);
  •         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4;         
  •          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
  •         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
  •          GPIO_Init(GPIOA, &GPIO_InitStructure);         
  •          GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_4);
  •         
  •         
  •         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*/
  • }
  • 复制代码
    main函数


    int main(void)
  • {
  •         OLED_Init();

  •         while(1)
  •         {
  •                 OLED_Refresh();
  •                 OLED_ShowString(20,0,"2023/11/11",16,1);
  •         }
  • }
  • 复制代码
    微信图片_20231112012301.jpg
    驱动效果如图
    代码在这
    oled.zip (2.9 MB, 下载次数: 0)
    全部回复 0
    暂无评论,快来抢沙发吧