0.96寸OLED屏幕开发(基于STM32F407HAL库)

#0.96寸OLED屏幕开发(基于STM32F407HAL库)
0.96寸OLED用途广泛,但是款式和种类比较多,有4脚,7脚,14脚的OLED。
本次开发的是7脚OLED是由库函数移植到HAL 库的https://www.cnblogs.com/ningmeng484/p/10406590.html
这是原博主@小牧同学写的基于STM32F103的库函数源码,有需要的可以去参考
链接:https://pan.baidu.com/s/1iyl2CTNvIxW7vXMSW3ClYg
提取码:syxx
百度云这个是我自己的HAL库移植后的代码,需要的也可以拿下去参考,有问题欢迎私聊~
主函数代码如下:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "delay.h"
#include "oledfont.h" 
#include "bmp.h"
//	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);
//	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);

#define OLED_MODE 				0
#define SIZE 							16
#define XLevelL						0x00
#define XLevelH						0x10
#define Max_Column				128
#define Max_Row						64
#define	Brightness				0xFF 
#define X_WIDTH 					128
#define Y_WIDTH 					64	    

#define OLED_CMD  0				//写命令
#define OLED_DATA 1				//写数据

#define OLED_SCLK_Clr() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET)//CLK
#define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET)

#define OLED_SDIN_Clr() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET)//DIN
#define OLED_SDIN_Set() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET)

#define OLED_RST_Clr() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET)//RES
#define OLED_RST_Set() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET)

#define OLED_DC_Clr() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET)//DC
#define OLED_DC_Set() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET)


/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#if OLED_MODE==1
/**
  * @brief 向SSD1106写入一个字节
    * @param dat:要写入的数据/命令  cmd:数据/命令标志 0,表示命令;1,表示数据
    * @retval None
  */
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
    DATAOUT(dat);        
    if(cmd)
      OLED_DC_Set();
    else 
        OLED_DC_Clr();           
    OLED_CS_Clr();
    OLED_WR_Clr();     
    OLED_WR_Set();
    OLED_CS_Set();      
    OLED_DC_Set();     
}                 
#else

/**
  * @brief 向SSD1106写入一个字节
    * @param dat:要写入的数据/命令 cmd:数据/命令标志 0,表示命令;1,表示数据;
    * @retval None
  */
	
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{    
    uint8_t i;              
    if(cmd)
      OLED_DC_Set();
    else 
      OLED_DC_Clr();          
    //OLED_CS_Clr();
    for(i=0;i<8;i++)
    {              
        OLED_SCLK_Clr();
        if(dat&0x80)
           OLED_SDIN_Set();
        else 
           OLED_SDIN_Clr();
        OLED_SCLK_Set();
        dat<<=1;   
    }                           
    //OLED_CS_Set();
    OLED_DC_Set();         
} 
#endif
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
    OLED_WR_Byte(0xb0+y,OLED_CMD);
    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
    OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
}   

/**
  * @brief 开启OLED显示
    * @param None
    * @retval None
  */ 
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
}

/**
  * @brief 关闭OLED显示    
    * @param None
    * @retval None
  */   
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
}        

/**
  * @brief 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样
    * @param None
    * @retval None
  */
void OLED_Clear(void)  
{  
    uint8_t i,n;            
    for(i=0;i<8;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); 
    }                                                                         //更新显示
}

/**
  * @brief 在指定位置显示一个字符,包括部分字符
    * @param x:0~127   y:0~63   mode:0,反白显示  1,正常显示     size:选择字体 16/12 
    * @retval None
  */
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr)
{          
    unsigned char c=0,i=0;    
    c=chr-' ';                                                        //得到偏移后的值            
    if(x>Max_Column-1)
    {
        x=0;
        y=y+2;
    }
    if(SIZE==16)
    {
        OLED_Set_Pos(x,y);    
        for(i=0;i<8;i++)
        OLED_WR_Byte(D8X16[c*16+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<8;i++)
        OLED_WR_Byte(D8X16[c*16+i+8],OLED_DATA);
    }
    else 
    {    
        OLED_Set_Pos(x,y+1);
        for(i=0;i<6;i++)
        {
            OLED_WR_Byte(D6X8[c][i],OLED_DATA);
        }
    }
}

/**
  * @brief m^n函数
    * @param None
    * @retval None
  */
uint32_t oled_pow(uint8_t m,uint8_t n)
{
    uint32_t result=1;     
    while(n--)result*=m;    
    return result;
}        

/**
  * @brief 显示2个数字
    * @param x,y :起点坐标
    *                 len :数字的位数,即显示几位有效数字
  *                 size:字体大小
  *                 mode:模式    0,填充模式;1,叠加模式
  *        num:数值(0~4294967295);
    * @retval None
  */           
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size)
{             
    uint8_t t,temp;
    uint8_t 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+(size/2)*t,y,' ');
                continue;
            }else enshow=1; 
              
        }
         OLED_ShowChar(x+(size/2)*t,y,temp+'0'); 
    }
} 

/**
  * @brief 显示一个字符号串
    * @param 
    * @retval None
  */
void OLED_ShowString(uint8_t x,uint8_t y,char *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++;
    }
}

/**
  * @brief 显示汉字
    * @param 
    * @retval None
  */
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{                      
    uint8_t t,adder=0;
    OLED_Set_Pos(x,y);	
    for(t=0;t<32;t++)
        {
                OLED_WR_Byte(SHOW[2*no][t],OLED_DATA);
                adder+=1;
     }    
        OLED_Set_Pos(x,y+1);    
    for(t=0;t<32;t++)
            {    
                OLED_WR_Byte(SHOW[2*no+1][t],OLED_DATA);
                adder+=1;
      }                    
}

/**
  * @brief 显示显示BMP图片
    * @param 显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7
    * @retval None
  */
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_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
        {      
            OLED_WR_Byte(BMP[j++],OLED_DATA);            
        }
    }
} 
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	OLED_Clear();
	OLED_DrawBMP(0,0,126,8,BMP);
  while (1)
  {
    /* USER CODE END WHILE */
		

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB12 PB13 PB14 PB15 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	  OLED_RST_Set();
    delay_ms(100);
    OLED_RST_Clr();
    delay_ms(100);
    OLED_RST_Set(); 
	
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
	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(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
	
	OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ 
	OLED_Clear();
	OLED_Set_Pos(0,0); 	
	
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: hal stm32f407是指使用HAL库编写的适用于STM32F407系列单片机的驱动程序。而"oled iic 0.96"是指一款0.96OLED显示屏,使用I2C通信协议进行数据传输。 为了在STM32F407上驱动这个OLED显示屏,我们可以使用HAL库提供的函数来配置STM32F407的I2C外设,并通过I2C总线来和OLED进行通信。首先,我们需要通过初始化函数来配置STM32F407的GPIO和I2C外设,使其适应OLED的工作要求。然后,我们可以使用HAL库提供的I2C读写函数来向OLED发送命令或数据。 通常,OLED显示屏驱动需要以下步骤: 1. 创建一个I2C_HandleTypeDef结构体,并通过HAL_I2C_Init函数对其进行初始化。 2. 通过HAL_GPIO_Init函数来初始化和配置I2C总线相关的GPIO引脚。 3. 使用HAL_I2C_Master_Transmit函数发送OLED的初始化命令序列,以配置OLED的工作模式和显示设置。 4. 在需要显示内容时,使用HAL_I2C_Master_Transmit函数发送显示数据到OLED,以在屏幕上显示对应的图像或文本。 需要注意的是,具体的初始化命令和数据传输格式可能因OLED显示屏的型号而有所差异,所以在具体应用时需要参考OLED显示屏的驱动手册来进行相关的配置。 总之,通过HAL库的支持,我们可以轻松地在STM32F407上驱动该款OLED显示屏,让它显示我们想要的图像或文本。 ### 回答2: HAL是指用于微控制器芯片的硬件抽象层,可以为芯片的底层硬件提供统一的接口和函数库。STM32F407是意法半导体公司开发的一款32位微控制器芯片,具有高性能和多种接口功能。而0.96是一种OLED显示屏,具有0.96的尺。 在STM32F407上,我们可以使用HAL库提供的函数来使用OLED显示屏。采用IIC(Inter-Integrated Circuit)接口来连接STM32F407OLED 0.96,IIC是一种串行通信协议,适用于短距离通信。这种连接方式可以实现双向通信,方便控制与数据传输。 使用HAL库,我们可以通过配置相应的GPIO管脚作为IIC接口的时钟线SCL(Serial Clock)和数据线SDA(Serial Data)来连接STM32F407OLED 0.96。然后通过使用HAL_I2C_Master_Transmit和HAL_I2C_Master_Receive函数来发送和接收数据。 在操作过程中,我们可以使用HAL库提供的函数来控制OLED显示屏的亮度、对比度、显示模式等设置。通过调用HAL_Delay函数可以实现延时操作,以控制显示的刷新频率和动画效果。 总之,使用HAL库,我们可以方便地在STM32F407上通过IIC接口驱动OLED 0.96显示屏,实现各种功能和效果,为嵌入式系统开发提供了便利。 ### 回答3: HAL是指STM32的硬件抽象层(Hardware Abstraction Layer),是ST公司为STM32微控制器提供的一组API函数库。通过使用HAL,开发人员可以更方便地操作STM32微控制器的各种外设。 STM32F407是一款高性能的ARM Cortex-M4微控制器,主频达到168MHz,拥有256KB的Flash存储器和SDRAM控制器,适用于各种工业控制、通信、嵌入式音频等应用。 OLED(Organic Light Emitting Diode)是一种有机发光二极管显示技术,具有高对比度、快速响应、低功耗等优点。它可用于制作小尺的、超薄的显示屏,广泛应用于手机、手表、电视等设备。 IIC(Inter-Integrated Circuit)是一种串行通信协议,也称为I2C(Inter-IC)总线。它是一种多主设备、多从设备的通信协议,可以连接多个外设与微控制器进行通信。 0.96指的是OLED显示屏的尺,即0.96。这个尺适用于一些小型的电子设备。 综上所述,"HAL STM32F407 OLED IIC 0.96"意味着使用STM32F407微控制器,通过HAL函数库驱动一个0.96OLED显示屏,使用IIC总线进行通信。这种硬件组合可以实现在STM32F407上驱动OLED屏幕显示各种信息,例如文本、图形等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值