stm32硬件I2C测试例程,亲测可⽤
对于stm32的硬件I2C确实有不尽⼈意的地⽅。但是还是可以实现的,毕竟使⽤stm32的硬件I2C确实⽐使⽤IO⼝来模拟简单的多。下⾯的程序代码是使⽤stm32F03ZET6的I2C1(PB6,PB7)和AT24C02的EEPROM来测试的。希望对于需要的朋友有帮助。
i2c.c
#include "iic.h"
#include "stm32f10x.h"
#include "usart.h"
u16 timeout=TIMEOUT;
/*i2c的初始化*/
void IIC1_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//GPIO的配置
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//IIC的配置
I2C_InitStruct.I2C_Ack=I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_ClockSpeed=10000;
I2C_InitStruct.I2C_DutyCycle=I2C_DutyCycle_2;
I2C_InitStruct.I2C_Mode=I2C_Mode_I2C;
I2C_InitStruct.I2C_OwnAddress1=0x55;
I2C_Init(I2C1,&I2C_InitStruct);
I2C_Cmd(I2C1,ENABLE);
}
/*写⼊⼀个字节*/
void IIC_WriteByte(u8 addr,u8 data)
{
I2C_EE_WaitEepromStandbyState();
I2C_GenerateSTART(I2C1,ENABLE);//发送起始信号
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))//检测 EV5事件
{
if((timeout--)==0)
printf("EV5 Fail");
} timeout=1000;
I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);//发送7位EEPROM的硬件地址
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//检测EV6事件
{
if((timeout--)==0)
printf("EV6 Fail");
} timeout=1000;
I2C_SendData(I2C1,addr);//发送操作的内存地址
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测EV8事件
{
printf("EV8 Fail");
} timeout=1000;
I2C_SendData(I2C1,data);//要写⼊的数据(⼀个字节)
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测EV8事件 {
configuredclockspeed是什么意思if((timeout--)==0)
printf("EV8 Fail");
} timeout=1000;
I2C_GenerateSTOP(I2C1,ENABLE);//发送结束信号
}
/*读取⼀个字节*/
u8 IIC_ReadByte(u8 addr)
{
u8 readtemp;
I2C_EE_WaitEepromStandbyState();//等待EEPROM释放总线
I2C_GenerateSTART(I2C1,ENABLE);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))//5
{
if((timeout--)==0)
printf("EV5 Fail");
} timeout=1000;
I2C_Send7bitAddress(I2C1,0xA1,I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//6 {
if((timeout--)==0)
printf("EV6 Fail");
} timeout=1000;
I2C_SendData(I2C1,addr);
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ) {
if((timeout--)==0)
printf("EV8 Fail");
} timeout=1000;
I2C_GenerateSTART(I2C1,ENABLE);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))
{
if((timeout--)==0)
printf("EV5 Fail");
} timeout=1000;
I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if((timeout--)==0)
printf("EV6 Fail");
} timeout=1000;
I2C_AcknowledgeConfig(I2C1,DISABLE);
/* 检测 EV7 事件 */
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS )
{
if((timeout--)==0)
printf("EV7 Fail");
/* 读取接收数据 */
readtemp = I2C_ReceiveData(I2C1);
/
* 停⽌信号 */
I2C_GenerateSTOP(I2C1,ENABLE);
return readtemp;
}
/*等待eeprom释放总线*/
void I2C_EE_WaitEepromStandbyState(void)
{
do
{
I2C_GenerateSTART(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)==ERROR);//检测EV5事件 I2C_Send7bitAddress(I2C1,0xA1,I2C_Direction_Transmitter);
}while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR)==ERROR);//
I2C_ClearFlag(I2C1, I2C_FLAG_AF);//清楚标志位
I2C_GenerateSTOP(I2C1, ENABLE); //结束信号
}
/* 向eeprom中写⼊n个数据*/
void I2C_WriteNumData(u8 addr,u8 *str, u8 numToWrite)
{
if((addr+numToWrite)>255)//避免写⼊的数据超过总的内存
{
printf("refuse to write\n");
printf("please enter less than %d char\n",(255-addr));
}
else
{
printf("allow to write\n");
while(numToWrite)
{
IIC_WriteByte(addr,*str);
addr++;
str++;
numToWrite--;
}
printf("write success\n");
}
}
void I2C_ReadNumData(u8 addr,u8 *str,u8 numToRead)
{
while(numToRead)
{
*str=IIC_ReadByte(addr);
addr++;
str++;
numToRead--;
}
}
usart.c
#include "usart.h"
#include "stm32f10x.h"
void USART1_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_InitStruct);
USART_InitStruct.USART_BaudRate=115200;
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
USART_InitStruct.USART_Parity=USART_Parity_No;
USART_InitStruct.USART_StopBits=USART_StopBits_1;
USART_InitStruct.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
USART_Cmd(USART1,ENABLE);
}
void USART1_SendByte(u8 data)
{
USART_SendData(USART1,data);
while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));
}
void USART1_SendStr(u8 *str)
{
unsigned int i=0;
for(i=0;*str!='\0';i++)
{
USART1_SendByte(*str);
str++;
}
while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
}
int fputc(int ch, FILE *f)
{
/
* 发送⼀个字节数据到串⼝ */
USART_SendData(USART1, (uint8_t) ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return (ch);
}
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "iic.h"
#include <stdio.h>
int main()
{
u8 a[10]={9,8,7,6,5,4,3,2,1,0}; u8 b[10]={0};
u8 i=0;
USART1_Init();
IIC1_Init();
I2C_WriteNumData(125,a,10);
I2C_ReadNumData(125,b,10); for(i=0;i<10;i++)
{
printf("%d\t",b[i]);
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论