打印
[通用ARM系列]

hc32f10x的I2C的使用

[复制链接]
3064|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
734774645|  楼主 | 2025-2-27 11:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
系统时钟配置 (SYS_Configuration)
void SYS_Configuration(void)
{
    FLASH_SetLatency(FLASH_Latency_2);  // 设置 Flash 等待周期为 2
       
    RCC_HSEConfig(RCC_HSE_ON);  // 开启外部高速晶振 (HSE)
    while(RCC_WaitForHSEStartUp() != SUCCESS ){}  // 等待 HSE 稳定

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

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

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


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

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


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

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


I2C 配置 (I2C_Configuration)
void I2C_Configuration(void)
{
    I2C_InitTypeDef I2C_InitStructure;

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

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

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


NVIC 配置 (NVIC_Configuration)

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

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

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

使用特权

评论回复
沙发
734774645|  楼主 | 2025-2-27 11:02 | 只看该作者
最后逐一调用
int main()
{
    RCC_Configuration();  // 配置时钟
    SYS_Configuration();  // 配置系统时钟
    GPIO_Configuration();  // 配置 GPIO
    I2C_Configuration();  // 配置 I2C
    NVIC_Configuration();  // 配置 NVIC

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

    while (1) {}
}


功能:初始化系统并启动 I2C 传输。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

210

主题

3534

帖子

15

粉丝