STM32—IIC详解入门(oled屏显示字)

目录

一、IIC协议

二、IIC构成

三、IIC特点      

四、IIC传输数据过程的三种信号

起始信号

终止信号

应答信号

五、IIC发送/接收一个字节数据

六、OLED屏

七、用到的函数

八、配置

九、main代码详细注释(oled显示字)


一、IIC协议

        IIC全称Inter-Integrated Circuit (集成电路总线),由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双工同步通信方式

二、IIC构成

        IIC串行总线有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。两条线都接上拉电阻,以确保总线空闲时刻为高电平,其中时钟信号是由主控器件产生。IIC总线支持多设备连接,允许多主机存在,对于并联在一条总线上的每个IIC设备都有唯一的地址(即靠地址来区分每一个IIC设备)。

三、IIC特点      

        简单性和有效性:由于接口直接在组件之上,因此IIC总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件

        多主控(multimastering):其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。

四、IIC传输数据过程的三种信号

          分别为:起始信号、终止信号和应答信号。

起始信号

        时序图

终止信号

        时序图

应答信号

        主机每发送一个字节(8个bit),就在第9个时钟脉冲期间释放数据线(SDA),由从机反馈一个应答信号。应答信号(SDA)为低电平时,规定为有效应答位(ACK,简称应答位),表示从机成功地接收了该字节。应答信号(SDA)为高电平时,规定为非应答位(NACK),一般表示从机接收该字节没有成功。

             时序图

五、IIC发送/接收一个字节数据

六、OLED屏

        OLED显示屏是一个128列*64行的点阵,垂直方向由8个PAGE控制,每个PAGE控制8个点阵,8个点阵8个位。

        一个PAGE由8位二进制组成 低位在上,高位在下。

 例如:写入数据0xaa(aa转成8位二进制后,位为1的点阵亮灯)

        1.选择PAGE(在垂直方向的哪个位置显示):

        命令为0xBx(例如0xB2 则选择的是在page2处显示)

  共8个PAGE,每个PAGE8位,所以垂直方向8*8=64位。

        2.选择列(在水平方向的哪个位置显示):

         命令为0x1x1(x1高4位),0x0x2(x2低4位),x1、x2合起来构成8位二进制控制列位置。

例如:0x10、0x01构成0000 0001 则选择的是第一列

        3.三种地址模式

模式选择(2行代码顺序不能颠倒)

    Oled_Write_Cmd(0x20);    //进入寻址方式选择
    Oled_Write_Cmd(0x02);    //02是页寻址、00是水平寻址、01是垂直寻址模式

                1.页地址模式(PAGE 与所在的所以的COL列构成一页)

                 2.水平地址模式

                 3.垂直地址模式

七、用到的函数

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c,

uint16_t DevAddress,

uint16_t MemAddress,

uint16_t MemAddSize,

uint8_t *pData,

uint16_t Size,

uint32_t Timeout)
 

参数一:I2C_HandleTypeDef *hi2c,I2C设备句柄

参数二:uint16_t DevAddress,IIC设备地址

参数三:uint16_t MemAddress,目标器件的目标寄存器地址

参数四:uint16_t MemAddSize,目标器件内部寄存器地址数据长度

参数五:uint8_t *pData,待写的数据首地址

参数六:uint16_t Size,待写的数据长度

参数七:uint32_t Timeout,超时时间

返回值:HAL_StatusTypeDef,HAL状态(OK,busy,ERROR,TIMEOUT)

例如

写入命令

void Oled_Write_Cmd(uint8_t dataCmd)

{

        HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, &dataCmd, 1, 0xff);

}

写入数据

void Oled_Write_Data(uint8_t dataData)
{
    HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT,&dataData, 1, 0xff);
}

八、配置

        1.RCC

 

         2.SYS

         3.I2C1

        4.接线

        查看芯片SCL与SDA引脚在哪,然后与oled屏上对应的SCL与SDA连接。

九、main代码详细注释(oled显示字)

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "gpio.h"

/* 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 */

void Oled_Write_Cmd(uint8_t dataCmd)//写入命令===================================
{
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT,&dataCmd, 1, 0xff);
	//&hi2c1句柄,  0x78IIC设备地址,  0x00写入命令  
	//I2C_MEMADD_SIZE_8BIT 后库提供的宏定义内部内存地址大小8位
	//&dataCmd待写数据首地址,  1待写的数据长度,  0xff超时时间

}   

void Oled_Write_Data(uint8_t dataData)//写入数据
{
	HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT,&dataData, 1, 0xff);
	//0x40写入数据
}

void Oled_Init()//OLED初始化
{
	Oled_Write_Cmd(0xAE);//--display off
	Oled_Write_Cmd(0x00);//---set low column address
	Oled_Write_Cmd(0x10);//---set high column address
	Oled_Write_Cmd(0x40);//--set start line address
	Oled_Write_Cmd(0xB0);//--set page address
	Oled_Write_Cmd(0x81); // contract control
	Oled_Write_Cmd(0xFF);//--128
	Oled_Write_Cmd(0xA1);//set segment remap
	Oled_Write_Cmd(0xA6);//--normal / reverse
	Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
	Oled_Write_Cmd(0x3F);//--1/32 duty
	Oled_Write_Cmd(0xC8);//Com scan direction
	Oled_Write_Cmd(0xD3);//-set display offset
	Oled_Write_Cmd(0x00);//
	Oled_Write_Cmd(0xD5);//set osc division
	Oled_Write_Cmd(0x80);//
	Oled_Write_Cmd(0xD8);//set area color mode off
	Oled_Write_Cmd(0x05);//
	Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
	Oled_Write_Cmd(0xF1);//
	Oled_Write_Cmd(0xDA);//set com pin configuartion
	Oled_Write_Cmd(0x12);//
	Oled_Write_Cmd(0xDB);//set Vcomh
	Oled_Write_Cmd(0x30);//
	Oled_Write_Cmd(0x8D);//set charge pump enable
	Oled_Write_Cmd(0x14);//
	Oled_Write_Cmd(0xAF);//--turn on oled panel
}

void Oled_Screen_Clear(void)//清屏
{
	int i,j;//选择char会导致雪花 因为-128—127导致j<128越界
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);  //选择PAGE的位置
		Oled_Write_Cmd(0x00); //选择列的位值低四位
		Oled_Write_Cmd(0x10);//高四位
		for(j = 0;j < 128; j++){//
			Oled_Write_Data(0);  //写入字符0
		}
	}
}

//上字的点阵
char s1[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00};
char s2[16] = {0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00};

/* USER CODE END PV */

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

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* 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();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
	
	int i;//==========================================================================
	Oled_Screen_Clear();//清屏
	Oled_Init();//oled初始化
	
	Oled_Write_Cmd(0x20);//选择寻址方式
	Oled_Write_Cmd(0x02);//02是页寻址、00是水平寻址、01是垂直寻址模式
	
	Oled_Write_Cmd(0xB0);//选择一个PAGE0选择第0页
	Oled_Write_Cmd(0x00);//低四位
	Oled_Write_Cmd(0x10);//高四位
	
	//显示字
	for(i=0;i<16;i++){
		Oled_Write_Data(s1[i]);
	}
	
	Oled_Write_Cmd(0xB1);//选择一个PAGE1选择第1页
	Oled_Write_Cmd(0x00);//低四位
	Oled_Write_Cmd(0x10);//高四位
	
	for(i=0;i<16;i++){
		Oled_Write_Data(s2[i]);
	}

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  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};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses 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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

/* 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 */
  __disable_irq();
  while (1)
  {
  }
  /* 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,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wlkq~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值