CH32v307V_R1 開發(fā)板使用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 讀取數(shù)據(jù)
?*?
?* @param addr 設(shè)備地址
?* @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); // 發(fā)送設(shè)備地址
? ? 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));? // 發(fā)送要讀取的寄存器地址
? ? 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); // 發(fā)送設(shè)備地址
? ? 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); // 關(guān)閉應(yīng)答
? ? ? ? }
? ? ? ? buf[i] = I2C_ReceiveData(I2C2); // 讀取數(shù)據(jù)
? ? }
? ? I2C_GenerateSTOP(I2C2, ENABLE); // 停止信號
? ? return 0;
}