你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G431RBTx 基本模块 I2C M24C02

[复制链接]
STMCU小助手 发布时间:2023-3-1 22:25
前言
G4板载了一块M24C02(eeprom)和一块MCP4017(可编程电阻),省赛中多考M24C02,本篇文章讲述如何用软件I2驱动M24C02。

I2C
1.原理图以及配置元素

64da61c3d2aa44a6aa50374704c3a4a9.png

分析:由图可知,PB6为I2C的SCL线,PB7为I2C的SDA线


2.CubeMx的配置步骤

7d8fae2a54fa46778a8db036b5ea243e.png

大赛是提供了I2C的驱动的这里我们只需要把两个引脚设置输出模式就行了,不再需要其他步骤。


3.生成工程

df9c9ee33c51466b961adb15ab6b37c4.png

42b467d97f8c426a90d16a293d7e1232.png

将红框中的两个文件复制黏贴到工程文件夹中的bsp文件夹中并改名为i2c.c和i2c.h。

db2a005175c14c4096e7a1717791eea7.png

在bsp文件中新建i2cc.c和i2c.h文件
打开工程将两个文件添加到工程中去

f8cdfa8b06ba4b4ebd3232cc87a1d4a3.png

至此工程就建立完毕了

4.测试代码
i2c.h:
  1. #ifndef __I2C_H
  2. #define __I2C_H

  3. #include "main.h"

  4. void I2CStart(void);
  5. void I2CStop(void);
  6. unsigned char I2CWaitAck(void);
  7. void I2CSendAck(void);
  8. void I2CSendNotAck(void);
  9. void I2CSendByte(unsigned char cSendByte);
  10. unsigned char I2CReceiveByte(void);
  11. void I2CInit(void);

  12. /*******下方为自己添加的函数声明**************/
  13. unsigned char eeprom_read(unsigned char addr);
  14. void eeprom_write(unsigned char addr, unsigned char dat);

  15. #endif

复制代码

i2c.c:
  1. #include "i2c.h"

  2. #define DELAY_TIME        20


  3. /**
  4.   * @brief SDA线输入模式配置
  5.   * @param None
  6.   * @retval None
  7.   */
  8. void SDA_Input_Mode()
  9. {
  10.     GPIO_InitTypeDef GPIO_InitStructure = {0};

  11.     GPIO_InitStructure.Pin = GPIO_PIN_7;
  12.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  13.     GPIO_InitStructure.Pull = GPIO_PULLUP;
  14.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  15.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  16. }

  17. /**
  18.   * @brief SDA线输出模式配置
  19.   * @param None
  20.   * @retval None
  21.   */
  22. void SDA_Output_Mode()
  23. {
  24.     GPIO_InitTypeDef GPIO_InitStructure = {0};

  25.     GPIO_InitStructure.Pin = GPIO_PIN_7;
  26.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  27.     GPIO_InitStructure.Pull = GPIO_NOPULL;
  28.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  29.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  30. }

  31. /**
  32.   * @brief SDA线输出一个位
  33.   * @param val 输出的数据
  34.   * @retval None
  35.   */
  36. void SDA_Output( uint16_t val )
  37. {
  38.     if ( val )
  39.     {
  40.         GPIOB->BSRR |= GPIO_PIN_7;
  41.     }
  42.     else
  43.     {
  44.         GPIOB->BRR |= GPIO_PIN_7;
  45.     }
  46. }

  47. /**
  48.   * @brief SCL线输出一个位
  49.   * @param val 输出的数据
  50.   * @retval None
  51.   */
  52. void SCL_Output( uint16_t val )
  53. {
  54.     if ( val )
  55.     {
  56.         GPIOB->BSRR |= GPIO_PIN_6;
  57.     }
  58.     else
  59.     {
  60.         GPIOB->BRR |= GPIO_PIN_6;
  61.     }
  62. }

  63. /**
  64.   * @brief SDA输入一位
  65.   * @param None
  66.   * @retval GPIO读入一位
  67.   */
  68. uint8_t SDA_Input(void)
  69. {
  70.         if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
  71.                 return 1;
  72.         }else{
  73.                 return 0;
  74.         }
  75. }


  76. /**
  77.   * @brief I2C的短暂延时
  78.   * @param None
  79.   * @retval None
  80.   */
  81. static void delay1(unsigned int n)
  82. {
  83.     uint32_t i;
  84.     for ( i = 0; i < n; ++i);
  85. }

  86. /**
  87.   * @brief I2C起始信号
  88.   * @param None
  89.   * @retval None
  90.   */
  91. void I2CStart(void)
  92. {
  93.     SDA_Output(1);
  94.     delay1(DELAY_TIME);
  95.     SCL_Output(1);
  96.     delay1(DELAY_TIME);
  97.     SDA_Output(0);
  98.     delay1(DELAY_TIME);
  99.     SCL_Output(0);
  100.     delay1(DELAY_TIME);
  101. }

  102. /**
  103.   * @brief I2C结束信号
  104.   * @param None
  105.   * @retval None
  106.   */
  107. void I2CStop(void)
  108. {
  109.     SCL_Output(0);
  110.     delay1(DELAY_TIME);
  111.     SDA_Output(0);
  112.     delay1(DELAY_TIME);
  113.     SCL_Output(1);
  114.     delay1(DELAY_TIME);
  115.     SDA_Output(1);
  116.     delay1(DELAY_TIME);

  117. }

  118. /**
  119.   * @brief I2C等待确认信号
  120.   * @param None
  121.   * @retval None
  122.   */
  123. unsigned char I2CWaitAck(void)
  124. {
  125.     unsigned short cErrTime = 5;
  126.     SDA_Input_Mode();
  127.     delay1(DELAY_TIME);
  128.     SCL_Output(1);
  129.     delay1(DELAY_TIME);
  130.     while(SDA_Input())
  131.     {
  132.         cErrTime--;
  133.         delay1(DELAY_TIME);
  134.         if (0 == cErrTime)
  135.         {
  136.             SDA_Output_Mode();
  137.             I2CStop();
  138.             return ERROR;
  139.         }
  140.     }
  141.     SDA_Output_Mode();
  142.     SCL_Output(0);
  143.     delay1(DELAY_TIME);
  144.     return SUCCESS;
  145. }

  146. /**
  147.   * @brief I2C发送确认信号
  148.   * @param None
  149.   * @retval None
  150.   */
  151. void I2CSendAck(void)
  152. {
  153.     SDA_Output(0);
  154.     delay1(DELAY_TIME);
  155.     delay1(DELAY_TIME);
  156.     SCL_Output(1);
  157.     delay1(DELAY_TIME);
  158.     SCL_Output(0);
  159.     delay1(DELAY_TIME);

  160. }

  161. /**
  162.   * @brief I2C发送非确认信号
  163.   * @param None
  164.   * @retval None
  165.   */
  166. void I2CSendNotAck(void)
  167. {
  168.     SDA_Output(1);
  169.     delay1(DELAY_TIME);
  170.     delay1(DELAY_TIME);
  171.     SCL_Output(1);
  172.     delay1(DELAY_TIME);
  173.     SCL_Output(0);
  174.     delay1(DELAY_TIME);

  175. }

  176. /**
  177.   * @brief I2C发送一个字节
  178.   * @param cSendByte 需要发送的字节
  179.   * @retval None
  180.   */
  181. void I2CSendByte(unsigned char cSendByte)
  182. {
  183.     unsigned char  i = 8;
  184.     while (i--)
  185.     {
  186.         SCL_Output(0);
  187.         delay1(DELAY_TIME);
  188.         SDA_Output(cSendByte & 0x80);
  189.         delay1(DELAY_TIME);
  190.         cSendByte += cSendByte;
  191.         delay1(DELAY_TIME);
  192.         SCL_Output(1);
  193.         delay1(DELAY_TIME);
  194.     }
  195.     SCL_Output(0);
  196.     delay1(DELAY_TIME);
  197. }

  198. /**
  199.   * @brief I2C接收一个字节
  200.   * @param None
  201.   * @retval 接收到的字节
  202.   */
  203. unsigned char I2CReceiveByte(void)
  204. {
  205.     unsigned char i = 8;
  206.     unsigned char cR_Byte = 0;
  207.     SDA_Input_Mode();
  208.     while (i--)
  209.     {
  210.         cR_Byte += cR_Byte;
  211.         SCL_Output(0);
  212.         delay1(DELAY_TIME);
  213.         delay1(DELAY_TIME);
  214.         SCL_Output(1);
  215.         delay1(DELAY_TIME);
  216.         cR_Byte |=  SDA_Input();
  217.     }
  218.     SCL_Output(0);
  219.     delay1(DELAY_TIME);
  220.     SDA_Output_Mode();
  221.     return cR_Byte;
  222. }

  223. //
  224. void I2CInit(void)
  225. {
  226.                 GPIO_InitTypeDef GPIO_InitStructure = {0};

  227.     GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_6;
  228.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  229.     GPIO_InitStructure.Pull = GPIO_PULLUP;
  230.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  231.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  232. }

  233. /**************以上是大赛提供的驱动**************************/


  234. /***********以下是自己写的对24C02的读写操作******************/

  235. unsigned char eeprom_read(unsigned char addr)
  236. {
  237.         unsigned char dat;
  238.         
  239.         I2CStart();
  240.         I2CSendByte(0xa0);
  241.         I2CWaitAck();
  242.         I2CSendByte(addr);
  243.         I2CWaitAck();
  244.         I2CStop();
  245.         
  246.         I2CStart();
  247.         I2CSendByte(0xa1);
  248.         I2CWaitAck();
  249.         dat = I2CReceiveByte();
  250.         I2CWaitAck();
  251.         I2CStop();
  252.         
  253.         return dat;
  254. }


  255. void eeprom_write(unsigned char addr, unsigned char dat)
  256. {
  257.         I2CStart();
  258.         I2CSendByte(0xa0);
  259.         I2CWaitAck();
  260.         I2CSendByte(addr);
  261.         I2CWaitAck();
  262.         I2CSendByte(dat);
  263.         I2CWaitAck();
  264.         I2CStop();
  265. }

复制代码

main.c:
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.c
  5.   * @brief          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>© Copyright (c) 2023 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "adc.h"
  23. #include "tim.h"
  24. #include "gpio.h"

  25. /* Private includes ----------------------------------------------------------*/
  26. /* USER CODE BEGIN Includes */
  27. #include "lcd.h"
  28. #include "badc.h"
  29. #include "stdio.h"
  30. #include "i2c.h"
  31. #include "interrupt.h"
  32. /* USER CODE END Includes */

  33. /* Private typedef -----------------------------------------------------------*/
  34. /* USER CODE BEGIN PTD */

  35. /* USER CODE END PTD */

  36. /* Private define ------------------------------------------------------------*/
  37. /* USER CODE BEGIN PD */
  38. /* USER CODE END PD */

  39. /* Private macro -------------------------------------------------------------*/
  40. /* USER CODE BEGIN PM */

  41. /* USER CODE END PM */

  42. /* Private variables ---------------------------------------------------------*/

  43. /* USER CODE BEGIN PV */
  44. extern struct keys key[4];
  45. unsigned char adc1_L, adc1_H;
  46. /* USER CODE END PV */

  47. /* Private function prototypes -----------------------------------------------*/
  48. void SystemClock_Config(void);
  49. /* USER CODE BEGIN PFP */

  50. /* USER CODE END PFP */

  51. /* Private user code ---------------------------------------------------------*/
  52. /* USER CODE BEGIN 0 */

  53. /* USER CODE END 0 */

  54. /**
  55.   * @brief  The application entry point.
  56.   * @retval int
  57.   */
  58. int main(void)
  59. {
  60.   /* USER CODE BEGIN 1 */

  61.   /* USER CODE END 1 */

  62.   /* MCU Configuration--------------------------------------------------------*/

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

  65.   /* USER CODE BEGIN Init */

  66.   /* USER CODE END Init */

  67.   /* Configure the system clock */
  68.   SystemClock_Config();

  69.   /* USER CODE BEGIN SysInit */

  70.   /* USER CODE END SysInit */

  71.   /* Initialize all configured peripherals */
  72.   MX_GPIO_Init();
  73.   MX_TIM3_Init();
  74.   MX_TIM16_Init();
  75.   MX_TIM17_Init();
  76.   MX_ADC1_Init();
  77.   MX_ADC2_Init();
  78.   /* USER CODE BEGIN 2 */
  79.         LCD_Init();
  80.         LCD_Clear(Black);
  81.         LCD_SetBackColor(Black);
  82.         LCD_SetTextColor(White);
  83.         HAL_TIM_Base_Start_IT(&htim3);
  84.   /* USER CODE END 2 */

  85.   /* Infinite loop */
  86.   /* USER CODE BEGIN WHILE */
  87.   while (1)
  88.   {
  89.     /* USER CODE END WHILE */

  90.     /* USER CODE BEGIN 3 */
  91.                 char text[30];
  92.                 unsigned int adc1, adc2;
  93.                 adc1 = getADC(&hadc1);
  94.                 sprintf(text, "    V1:%.2f", adc1 * 3.3 / 4096);
  95.                 LCD_DisplayStringLine(Line4, (unsigned char *)text);
  96.                 adc2 = getADC(&hadc2);
  97.                 sprintf(text, "    V2:%.2f", adc2 * 3.3 / 4096);
  98.                 LCD_DisplayStringLine(Line5, (unsigned char *)text);
  99.                 if(key[0].single_flag) //短按写入
  100.                 {
  101.                         adc1_L = adc1 & 0xff;
  102.                         adc1_H = adc1 >> 8;
  103.                         eeprom_write(1, adc1_L);
  104.                         HAL_Delay(10);
  105.                         eeprom_write(2, adc1_H);
  106.                         key[0].single_flag = 0;
  107.                 }
  108.                 if(key[0].long_flag) //长按读出
  109.                 {
  110.                         char text[30];
  111.                         unsigned int eep_temp = (eeprom_read(2) << 8) + eeprom_read(1);
  112.                         sprintf(text, "    ADC_eep=%.2f", eep_temp * 3.3 / 4096);
  113.                         LCD_DisplayStringLine(Line8, (unsigned char *)text);
  114.                         key[0].long_flag = 0;        
  115.                 }
  116.   }
  117.   /* USER CODE END 3 */
  118. }

  119. /**
  120.   * @brief System Clock Configuration
  121.   * @retval None
  122.   */
  123. void SystemClock_Config(void)
  124. {
  125.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  126.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  127.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  128.   /** Configure the main internal regulator output voltage
  129.   */
  130.   HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  131.   /** Initializes the RCC Oscillators according to the specified parameters
  132.   * in the RCC_OscInitTypeDef structure.
  133.   */
  134.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  135.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  136.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  137.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  138.   RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  139.   RCC_OscInitStruct.PLL.PLLN = 20;
  140.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  141.   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  142.   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  143.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  144.   {
  145.     Error_Handler();
  146.   }
  147.   /** Initializes the CPU, AHB and APB buses clocks
  148.   */
  149.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  150.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  151.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  152.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  153.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  154.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  155.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  156.   {
  157.     Error_Handler();
  158.   }
  159.   /** Initializes the peripherals clocks
  160.   */
  161.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
  162.   PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
  163.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  164.   {
  165.     Error_Handler();
  166.   }
  167. }

  168. /* USER CODE BEGIN 4 */

  169. /* USER CODE END 4 */

  170. /**
  171.   * @brief  This function is executed in case of error occurrence.
  172.   * @retval None
  173.   */
  174. void Error_Handler(void)
  175. {
  176.   /* USER CODE BEGIN Error_Handler_Debug */
  177.   /* User can add his own implementation to report the HAL error return state */
  178.   __disable_irq();
  179.   while (1)
  180.   {
  181.   }
  182.   /* USER CODE END Error_Handler_Debug */
  183. }

  184. #ifdef  USE_FULL_ASSERT
  185. /**
  186.   * @brief  Reports the name of the source file and the source line number
  187.   *         where the assert_param error has occurred.
  188.   * @param  file: pointer to the source file name
  189.   * @param  line: assert_param error line source number
  190.   * @retval None
  191.   */
  192. void assert_failed(uint8_t *file, uint32_t line)
  193. {
  194.   /* USER CODE BEGIN 6 */
  195.   /* User can add his own implementation to report the file name and line number,
  196.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  197.   /* USER CODE END 6 */
  198. }
  199. #endif /* USE_FULL_ASSERT */

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

复制代码

————————————————
版权声明:火花页.


收藏 评论0 发布时间:2023-3-1 22:25

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版