[通用ARM系列] hc32f10x的I2C的使用

[复制链接]
 楼主| 734774645 发表于 2025-2-27 11:00 | 显示全部楼层 |阅读模式
系统时钟配置 (SYS_Configuration)
  1. void SYS_Configuration(void)
  2. {
  3.     FLASH_SetLatency(FLASH_Latency_2);  // 设置 Flash 等待周期为 2
  4.        
  5.     RCC_HSEConfig(RCC_HSE_ON);  // 开启外部高速晶振 (HSE)
  6.     while(RCC_WaitForHSEStartUp() != SUCCESS ){}  // 等待 HSE 稳定

  7.     RCC_HCLKConfig(RCC_SYSCLK_Div1);  // HCLK = SYSCLK
  8.     RCC_PCLK2Config(RCC_HCLK_Div1);   // PCLK2 = HCLK
  9.     RCC_PCLK1Config(RCC_HCLK_Div1);   // PCLK1 = HCLK
  10.                
  11.     RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_5);  // PLL 配置:HSE/2 * 5 = 20MHz
  12.     RCC_PLLCmd(ENABLE);  // 使能 PLL

  13.     while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}  // 等待 PLL 就绪
  14.                
  15.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  // 系统时钟切换到 PLL
  16.     while (RCC_GetSYSCLKSource() != 0x08) {}  // 等待系统时钟切换完成
  17. }
功能:配置系统时钟为 20MHz,使用外部高速晶振 (HSE) 和 PLL。

关键点:
RCC_PLLConfig:配置 PLL 输入为 HSE/2,倍频系数为 5,得到 20MHz 的系统时钟。
RCC_SYSCLKConfig:将系统时钟源切换为 PLL。


RCC 配置 (RCC_Configuration)
  1. void RCC_Configuration(void)
  2. {
  3.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);  // 使能 AFIO 和 GPIOB 时钟
  4.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);  // 使能 I2C1 时钟
  5. }
功能:使能外设时钟(AFIO、GPIOB 和 I2C1)。

关键点:
I2C1 挂载在 APB1 总线上,因此需要使能 RCC_APB1Periph_I2C1。


GPIO 配置 (GPIO_Configuration)
  1. void GPIO_Configuration(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.        
  5.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;  // 配置 PB6 (SCL) 和 PB7 (SDA)
  6.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 复用开漏模式
  7.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 速度 50MHz
  8.     GPIO_Init(GPIOB, &GPIO_InitStructure);  // 初始化 GPIOB
  9. }
功能:配置 PB6 和 PB7 为 I2C 的 SCL 和 SDA 引脚。

关键点:
I2C 引脚需要配置为复用开漏模式 (GPIO_Mode_AF_OD)。


I2C 配置 (I2C_Configuration)
  1. void I2C_Configuration(void)
  2. {
  3.     I2C_InitTypeDef I2C_InitStructure;

  4.     I2C_DeInit(I2C1);  // 复位 I2C1
  5.     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  // I2C 模式
  6.     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  // 占空比 2
  7.     I2C_InitStructure.I2C_OwnAddress1 = 0x01;  // 自身地址
  8.     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  // 使能 ACK
  9.     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  // 7 位地址模式
  10.     I2C_InitStructure.I2C_ClockSpeed = 100000;  // 时钟频率 100kHz
  11.     I2C_Init(I2C1, &I2C_InitStructure);  // 初始化 I2C1

  12.     I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);  // 使能事件和缓冲区中断
  13.     I2C_Cmd(I2C1, ENABLE);  // 使能 I2C1
  14. }
功能:配置 I2C1 为主设备,时钟频率为 100kHz。

关键点:
I2C_ITConfig:使能事件中断和缓冲区中断。
I2C_Cmd:使能 I2C1。


NVIC 配置 (NVIC_Configuration)

  1. void NVIC_Configuration(void)
  2. {
  3.     NVIC_InitTypeDef NVIC_InitStructure;
  4.   
  5.     NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;  // I2C1 事件中断
  6.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;  // 抢占优先级
  7.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;  // 子优先级
  8.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能中断
  9.     NVIC_Init(&NVIC_InitStructure);
  10. }
功能:配置 I2C1 事件中断的优先级并使能中断。

I2C 事件中断处理 (I2C1_EV_IRQHandler)
  1. void I2C1_EV_IRQHandler(void)
  2. {
  3.     switch(I2C_GetLastEvent(I2C1))
  4.     {
  5.         case I2C_EVENT_MASTER_MODE_SELECT:  // 主模式选择
  6.             SR1Register = I2C_SR1(I2C1);  // 读取状态寄存器 1
  7.             I2C_DR(I2C1) = 0x20;  // 发送从设备地址
  8.             break;
  9.         case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:  // 主发送模式选择
  10.             SR1Register = I2C_SR1(I2C1);  // 读取状态寄存器 1
  11.             SR2Register = I2C_SR2(I2C1);  // 读取状态寄存器 2
  12.             break;
  13.         case I2C_EVENT_MASTER_BYTE_TRANSMITTING:  // 字节传输中
  14.             if (i < 6)
  15.                 I2C_SendData(I2C1, Buffer_Tx[i++]);  // 发送数据
  16.             break;               
  17.         case I2C_EVENT_MASTER_BYTE_TRANSMITTED:  // 字节传输完成
  18.             I2C_GenerateSTOP(I2C1, ENABLE);  // 生成停止条件
  19.             i = 0;  // 重置索引
  20.             break;
  21.         default:
  22.             break;
  23.     }
  24. }
功能:处理 I2C 事件中断,根据事件类型执行相应的操作。

关键点:
I2C_EVENT_MASTER_MODE_SELECT:发送从设备地址。
I2C_EVENT_MASTER_BYTE_TRANSMITTING:发送数据。
I2C_EVENT_MASTER_BYTE_TRANSMITTED:生成停止条件。

 楼主| 734774645 发表于 2025-2-27 11:02 | 显示全部楼层
最后逐一调用
  1. int main()
  2. {
  3.     RCC_Configuration();  // 配置时钟
  4.     SYS_Configuration();  // 配置系统时钟
  5.     GPIO_Configuration();  // 配置 GPIO
  6.     I2C_Configuration();  // 配置 I2C
  7.     NVIC_Configuration();  // 配置 NVIC

  8.     I2C_GenerateSTART(I2C1, ENABLE);  // 生成起始条件

  9.     while (1) {}
  10. }


功能:初始化系统并启动 I2C 传输。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

210

主题

3585

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部