A stm32 I2C found on the Internet is a relatively easy-to-understand entry routine.

I bought a core board, I think I have my own STM32 board, so I have a full I2C by the way (because the above is 24C02, hehe, hee hee, more kind), at the beginning, I wrote one according to the routine in the reference book Read and write the program, but directly download the program to the board and the serial port has no data output (I use the serial port to send out the read data), then I debugged it in FLASH, walked step by step, and found that the program stopped. while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){;} , and then look for various possible reasons. Finally, if it doesn’t work, I looked at Baidu and found an important message: some IIC devices need to delay when reading and writing! I feel that this may be the reason. After all, 24C02 is an entry-level chip for I2C, so I added a delay function to the program, downloaded it to the board, and it worked! Thanks to all the predecessors on the Internet!
The source code is posted below:
#include <stm32f10x.h>
#include "I2C.h"
#include <stm32f10x_gpio.h>
#include <stm32f10x_i2c.h>

void I2C_GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void I2C1_Init()
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0xA0;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStructure);
}

void I2C_Write(u8 addr, u8 data)
{
I2C_AcknowledgeConfig(I2C1,ENABLE); //Enable response
I2C_GenerateSTART(I2C1,ENABLE); //Send a start bit
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;}//等待EV5
I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter); //Send slave address
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;} //等待EV6
I2C_SendData(I2C1,addr); //Send the address of the data to be written
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //等待EV8
I2C_SendData(I2C1,data); //Send the data to be written
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //等待EV8
I2C_GenerateSTOP(I2C1,ENABLE); //Send stop bit
}

u8 I2C_Read(u8 nAddr)
{
I2C_AcknowledgeConfig(I2C1,ENABLE); //Enable response
I2C_GenerateSTART(I2C1,ENABLE); //Send a start bit
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //等待EV5
I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter); //Send a pseudo-write command
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;}//等待EV6
I2C_SendData(I2C1,nAddr);//Send read address
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //等待EV8

I2C_GenerateSTART(I2C1,ENABLE); //Send a start bit
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //等待EV5
I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Receiver); //Send a read command
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){;} //等待EV6
I2C_AcknowledgeConfig(I2C1,DISABLE); //response enable close
I2C_GenerateSTOP(I2C1,ENABLE); //Send a stop bit
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){;} //等待EV7
return I2C_ReceiveData(I2C1); //Return the data read
}

#include<stm32f10x_lib.h>
#include"usart.h"

void usart_gpio_config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);

}

void usart_init()
{
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_Cmd(USART1,ENABLE);
}

void usart_putchar(u8 ch)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}

#include <stm32f10x.h>
#include "delay.h"
static u8 fac_us=0;//us delay multiplier
static u16 fac_ms=0;//ms delay multiplier
//Initialize the delay function
//SYSTICK clock is fixed at 1/8 of HCLK clock
//SYSCLK: system clock
void delay_init(u8 SYSCLK)
{
SysTick->CTRL&=0xfffffffb;//bit2 clear, select external clock HCLK/8
fac_us=SYSCLK/8;
fac_ms = (u16) fac_us * 1000;
}
//Delay nms
//Pay attention to the range of nms
//SysTick->LOAD is a 24-bit register, so the maximum delay is:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK unit is Hz, nms unit is ms
//Under 72M conditions, nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//Time load (SysTick->LOAD is 24bit)
SysTick->VAL =0x00; //clear the counter
SysTick->CTRL=0x01; //start countdown
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//Waiting for the time to arrive
SysTick->CTRL=0x00; //Close the counter
SysTick->VAL =0X00; //Clear the counter
}
//Delay nus
//nus is the number of us to be delayed.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //time loading
SysTick->VAL=0x00; //Clear the counter
SysTick->CTRL=0x01; //start countdown
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//Waiting for the time to arrive
SysTick->CTRL=0x00; //Close the counter
SysTick->VAL =0X00; //Clear the counter
}

#include <stm32f10x.h>
#include "I2C.h"
#include "Usart.h"
#include "delay.h"

int main ()
{
SystemInit();
delay_init(72);
I2C_GPIO_Config();
I2C1_Init();
usart_gpio_config();
usart_init();
I2C_Write(0x10,0x30);
delay_ms(10);

while(1)
{
usart_putchar(I2C_Read(0x10));
delay_ms(1000);
}
}
Because I just want to experiment, I just write a piece of data, and then read the written data through the serial port, nothing more.













Guess you like

Origin blog.csdn.net/ludaoyi88/article/details/50858994