CH32v307V_R1 开发板使用CH32V307EVT 中的IIC例程I2C_EEPROM,用硬件IIC,一直报busy,测量示波器波形PB10和PB11都是低电平
代码如下
/*
* bsp_i2c.c
*
* Created on: May 13, 2024
* Author: mx
*/
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2024/03/05
* Description : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*
*@Note
I2C interface routine to operate EEPROM peripheral.
I2C1_SCL(PB10)\I2C1_SDA(PB11).
This example uses EEPROM for AT24Cxx series.
Steps:
READ EEPROM:Start + 0xA0 + 8bit Data Address + Start + 0xA1 + Read Data + Stop.
WRITE EERPOM:Start + 0xA0 + 8bit Data Address + Write Data + Stop.
*/
#include "bsp_i2c.h"
#include "debug.h"
#include "FreeRTOS.h"
#include "task.h"
/**********************************************************************
*@Note:
AT24Cxx
READ EEPROM:Start + 0xA0 + 8bit Data Address + Start + 0xA1 + Read Data + Stop.
WRITE EERPOM:Start + 0xA0 + 8bit Data Address + Write Data + Stop.
*******************************************************************************/
/* EERPOM DATA ADDRESS Length Definition */
#define Address_8bit 0
#define Address_16bit 1
/* EERPOM DATA ADDRESS Length Selection */
#define Address_Lenth Address_8bit
//#define Address_Lenth Address_16bit
/* Global define */
#define SIZE sizeof(TEXT_Buffer)
/* Global Variable */
const u8 TEXT_Buffer[] = {"CH32F10x I2C TEST"};
/**
* @brief IIC初始化
*
* @param bound 速率
* @param address 地址
*/
void IIC_Init(u32 bound, u16 address)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
I2C_InitTypeDef I2C_InitTSturcture = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_InitTSturcture.I2C_ClockSpeed = bound;
I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;
I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitTSturcture.I2C_OwnAddress1 = address;
I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;
I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C2, &I2C_InitTSturcture);
I2C_Cmd(I2C2, ENABLE);
}
u8 iic_err_count(void)
{
static u8 err_count = 0;
err_count++;
vTaskDelay(1);
if (err_count > 10)
{
err_count = 0;
return 1;
}
return 0;
}
/**
* @brief 读取数据
*
* @param addr 设备地址
* @param reg 寄存器地址
* @return u8
*/
u8 IIC_ReadBuffer(u8 addr, u8 reg, u8 *buf, size_t len)
{
static u8 ret = 1;
if (len == 0 || ret != 1)
{
if (ret == 0)
{
printf("len error\r\n");
ret = 2;
}
return 1;
}
if (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
{
printf("bus busy\r\n");
ret = 0;
return 1;
}
I2C_GenerateSTART(I2C2, ENABLE); // 开始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
{
if (iic_err_count())
{
printf("not com\r\n");
return 1;
}
}
I2C_Send7bitAddress(I2C2, addr<<1, I2C_Direction_Transmitter); // 发送设备地址
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if (iic_err_count())
{
printf("not com1\r\n");
return 1;
}
}
I2C_SendData(I2C2, (u8)(reg & 0x00FF)); // 发送要读取的寄存器地址
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if (iic_err_count())
{
printf("not com2\r\n");
return 1;
}
}
I2C_GenerateSTART(I2C2, ENABLE); // 开始信号
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
{
if (iic_err_count())
{
printf("not com3\r\n");
return 1;
}
}
I2C_Send7bitAddress(I2C2, addr<<1, I2C_Direction_Receiver); // 发送设备地址
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if (iic_err_count())
{
printf("not com4\r\n");
return 1;
}
}
for (size_t i = 0; i < len; i++)
{
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
{
I2C_AcknowledgeConfig(I2C2, DISABLE); // 关闭应答
}
buf[i] = I2C_ReceiveData(I2C2); // 读取数据
}
I2C_GenerateSTOP(I2C2, ENABLE); // 停止信号
return 0;
}