ch32v203f8p6 使用i2c时卡死在while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET );

ch32v203f8p6 使用i2c时卡死在while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET );。

我使用的是官方给的例程,原本i2c两个端口一个拉高一个拉低,通过看其他帖子发现需要把i2c上拉,就自己焊了电阻连到vcc上,现在空闲时是sda(pb7)大概4v,scl(pb6)大概5v。(因为我供电是5v,在板子上也把5v和vcc用跳线帽连起来了)。请问这个是什么问题?

代码如下所示:

/********************************** (C) COPYRIGHT *******************************

 * File Name          : main.c

 * Author             : WCH

 * Version            : V1.0.0

 * Date               : 2021/06/06

 * 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

 *7-bit addressing mode, master/slave mode, transceiver routine:

 *I2C1_SCL(PB8)\I2C1_SDA(PB9).

 *This routine demonstrates that Master sends and Slave receives.

 *Note: The two boards download the Master and Slave programs respectively,

 *and power on at the same time.

 *    Hardware connection:PB8 -- PB8

 *                        PB9 -- PB9

 *

 */


#include "debug.h"


/* I2C Mode Definition */

#define HOST_MODE   0

#define SLAVE_MODE   1


/* I2C Communication Mode Selection */

#define I2C_MODE   HOST_MODE

//#define I2C_MODE   SLAVE_MODE


/* Global define */

#define Size   6

#define RXAdderss   0x02

#define TxAdderss   0x02


/* Global Variable */

u8 TxData[Size] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

u8 RxData[5][Size];


/*********************************************************************

 * @fn      IIC_Init

 *

 * @brief   Initializes the IIC peripheral.

 *

 * @return  none

 */

void IIC_Init(u32 bound, u16 address)

{

GPIO_InitTypeDef GPIO_InitStructure={0};

I2C_InitTypeDef I2C_InitTSturcture={0};


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE );

GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);

RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

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_7;

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_16_9;

I2C_InitTSturcture.I2C_OwnAddress1 = address;

I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;

I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init( I2C1, &I2C_InitTSturcture );


I2C_Cmd( I2C1, ENABLE );


#if (I2C_MODE == HOST_MODE)

I2C_AcknowledgeConfig( I2C1, ENABLE );


#endif

}


/*********************************************************************

 * @fn      main

 *

 * @brief   Main program.

 *

 * @return  none

 */

int main(void)

{

    u8 i = 0;

u8 j = 0;

u8 p = 0;

    SystemCoreClockUpdate();

    Delay_Init();

    USART_Printf_Init( 115200 );

    printf( "SystemClk:%d\r\n", SystemCoreClock );

    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );


#if (I2C_MODE == HOST_MODE)

    printf("IIC Host mode\r\n");

IIC_Init( 80000, TxAdderss);


for( j =0; j < 5; j++)

{

    while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET );

    printf("I2C_GetFlagStatus\r\n");

I2C_GenerateSTART( I2C1, ENABLE );

printf("I2C_GenerateSTART\r\n");

while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );

printf("I2C_EVENT_MASTER_MODE_SELECT\r\n");

I2C_Send7bitAddress( I2C1, 0x02, I2C_Direction_Transmitter );

printf("I2C_Send7bitAddress\r\n");

    while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );

    printf("I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED\r\n");

    for( i=0; i< 6;i++ )

    {

        if( I2C_GetFlagStatus( I2C1, I2C_FLAG_TXE ) !=  RESET )

        {

    Delay_Ms(100);

            I2C_SendData( I2C1, TxData[i] );

        }

    }


    while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

    I2C_GenerateSTOP( I2C1, ENABLE );

Delay_Ms(1000);

}


#elif (I2C_MODE == SLAVE_MODE)

printf("IIC Slave mode\r\n");

IIC_Init( 80000, RXAdderss);


for( p =0; p < 5; p++)

{

    i = 0;

while( !I2C_CheckEvent( I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ) );

    while( i < 6 )

    {

        if( I2C_GetFlagStatus( I2C1, I2C_FLAG_RXNE ) !=  RESET )

        {

            RxData[p][i] = I2C_ReceiveData( I2C1 );

            i++;

        }

    }

        I2C1->CTLR1 &= I2C1->CTLR1;

    }

    printf( "RxData:\r\n" );

for(p=0; p<5; p++)

   {

        for( i = 0; i < 6; i++ )

{

           printf( "%02x ", RxData[p][i] );

}

   printf( "\r\n ");

}

 

 

#endif


while(1);

}


测试板是在淘宝网微嵌电子买的,原理图:image.png


您好,PB6、PB7引脚是IIC1的默认引脚,不需要开启重映射功能,可将下图圈出部分去掉试一下。此外注意一下PB6、PB7引脚是和PA13、PA14共用同一个引脚的,注意不要同时使用。注意一下工程文件的配置,ld文件中FLASH、RAM的大小配置以及启动文件的选择。后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通。

image.png


原问题已经解决了,感谢!不过又出现了一些新问题。(也给您在邮件发了一份)

测试条件:两个ch32v203f8p6,一个做master,一个做slave。

测试的时候发现,master在发送完一轮数据,完成I2C_GenerateSTOP( I2C1, ENABLE );这个语句之后,我本来是想重新开启一轮发送数据的,也就是说又进入while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET );这一句了。这个时候又出现了无法通过这一句代码的状况。我用电压表测了一下,现在sda和scl都处于低电平,只有我把slave和master断开i2c的连接,电平才恢复正常。这是什么问题?

代码如下:

/********************************** (C) COPYRIGHT *******************************

 * File Name          : main.c

 * Author             : WCH

 * Version            : V1.0.0

 * Date               : 2021/06/06

 * 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

 *7-bit addressing mode, master/slave mode, transceiver routine:

 *I2C1_SCL(PB8)\I2C1_SDA(PB9).

 *This routine demonstrates that Master sends and Slave receives.

 *Note: The two boards download the Master and Slave programs respectively,

 *and power on at the same time.

 *    Hardware connection:PB8 -- PB8

 *                        PB9 -- PB9

 *

 */


#include "debug.h"


/* I2C Mode Definition */

#define HOST_MODE   0

#define SLAVE_MODE   1


/* I2C Communication Mode Selection */

//#define I2C_MODE   HOST_MODE

#define I2C_MODE   SLAVE_MODE


/* Global define */

#define Size   6

#define RXAdderss   0x02

#define TxAdderss   0x02


/* Global Variable */

u8 TxData[Size] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

u8 RxData[5][Size];


/*********************************************************************

 * @fn      IIC_Init

 *

 * @brief   Initializes the IIC peripheral.

 *

 * @return  none

 */


void GPIO_Toggle_INIT(void)

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    Delay_Ms(10);

    GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);

}


void IIC_Init(u32 bound, u16 address)

{

GPIO_InitTypeDef GPIO_InitStructure={0};

I2C_InitTypeDef I2C_InitTSturcture={0};


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE );

// GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);

RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

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_7;

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_16_9;

I2C_InitTSturcture.I2C_OwnAddress1 = address;

I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;

I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init( I2C1, &I2C_InitTSturcture );


I2C_Cmd( I2C1, ENABLE );


#if (I2C_MODE == HOST_MODE)

I2C_AcknowledgeConfig( I2C1, ENABLE );


#endif

}


/*********************************************************************

 * @fn      main

 *

 * @brief   Main program.

 *

 * @return  none

 */

int main(void)

{

    u8 i = 0;

u8 j = 0;

u8 p = 0;

    SystemCoreClockUpdate();

    Delay_Init();

    USART_Printf_Init( 115200 );

    printf( "SystemClk:%d\r\n", SystemCoreClock );

    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );


#if (I2C_MODE == HOST_MODE)

    printf("IIC Host mode\r\n");

//    GPIO_Toggle_INIT();


    Delay_Ms(10);

IIC_Init( 80000, TxAdderss);


for( j =0; j < 5; j++)

{


    while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY ) != RESET );

    printf("I2C_GetFlagStatus\r\n");

I2C_GenerateSTART( I2C1, ENABLE );

printf("I2C_GenerateSTART\r\n");

while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT ) );

printf("I2C_EVENT_MASTER_MODE_SELECT\r\n");

Delay_Ms(10);

I2C_Send7bitAddress( I2C1, 0x02, I2C_Direction_Transmitter );

printf("I2C_Send7bitAddress\r\n");

Delay_Ms(10);

    while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ){

        Delay_Ms(10);

    }

    printf("I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED\r\n");

    for( i=0; i< 6;i++ )

    {

        if( I2C_GetFlagStatus( I2C1, I2C_FLAG_TXE ) !=  RESET )

        {

    Delay_Ms(100);

            I2C_SendData( I2C1, TxData[i] );

            printf("I2C_SendData\r\n");

        }

    }


    while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );

    printf("I2C_EVENT_MASTER_BYTE_TRANSMITTED\r\n");

    I2C_GenerateSTOP( I2C1, ENABLE );

    printf("I2C_GenerateSTOP\r\n");

Delay_Ms(1000);

}


#elif (I2C_MODE == SLAVE_MODE)

printf("IIC Slave mode\r\n");

IIC_Init( 80000, RXAdderss);


for( p =0; p < 5; p++)

{

    i = 0;

while( !I2C_CheckEvent( I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ) );

printf("I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED\r\n");

    while( i < 6 )

    {

        if( I2C_GetFlagStatus( I2C1, I2C_FLAG_RXNE ) !=  RESET )

        {

            RxData[p][i] = I2C_ReceiveData( I2C1 );

            printf("I2C_ReceiveData\r\n");

            i++;

        }

    }

    while( !I2C_CheckEvent( I2C1, I2C_EVENT_SLAVE_STOP_DETECTED ) );

    printf("I2C_EVENT_SLAVE_STOP_DETECTED\r\n");

    I2C1->CTLR1 &= I2C1->CTLR1;

    printf("I2C1->CTLR1 &= I2C1->CTLR1;\r\n");

    }

    printf( "RxData:\r\n" );

for(p=0; p<5; p++)

   {

        for( i = 0; i < 6; i++ )

{

           printf( "%02x ", RxData[p][i] );

}

   printf( "\r\n ");

}

 

 

#endif


while(1);

}



您好,已邮件回复你,后续问题可继续通过邮箱沟通。


只有登录才能回复,可以选择微信账号登录