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

STM32G431RBTx 基本模块 I2C M24C02

[复制链接]
STMCU小助手 发布时间:2023-3-1 22:25
前言G4板载了一块M24C02(eeprom)和一块MCP4017(可编程电阻),省赛中多考M24C02,本篇文章讲述如何用软件I2驱动M24C02。I2C1.原理图以及配置元素 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 手机版