stm32 基于标准库的iic地址扫描程序

stm32 基于标准库的iic地址扫描程序

适用于刚入门stm32的学习者

在用stm32 开发之前我一直使用的是arduino来控制iic的设备,iic设备最重要的一个参数就是iic地址,所以在开发iic通信相关的项目时,有一个iic地址的扫描程序就比较重要,使用 arduino ide 进行开发时,iic地址扫描程序在百度上有很多,所以直接复制下来就能扫描出来也不用去查芯片手册,但在用 keil 开发时,网上的资料就没看到有多少,于是我便自己写了一个 keil 5 上的iic地址扫描程序

代码

#include "delay.h"
#include "sys.h"
#include "usart.h" 
#include "myiic.h"

   	
 int main(void)
 { 


  u8 addr = 0;
	u8 ack;
	u8 read = 0;

	delay_init();	    	   
	uart_init(9600);	 
    IIC_Init();
		
	for(addr = 0 ; addr < 255 ;addr++){
		IIC_Start();
 	  IIC_Send_Byte(addr);   	//·¢ËÍдÃüÁî 	 
	  ack = IIC_Wait_Ack();
		if(ack == 0 && (read %2 ==0) ){
       printf("write addr = 0x%x\r\n",addr);
		   read++;
		}
		else if(ack ==0 && read %2 == 1){
		   printf("read addr = 0x%x\r\n",addr);	
			read++;
		}
  			IIC_Stop();
		}
	while(1);

}
<myiic.c>

#include "myiic.h"
#include "delay.h"

void IIC_Init(void)
{					     
 	RCC->APB2ENR|=1<<4;//ÏÈʹÄÜÍâÉèIO PORTCʱÖÓ 							 
	GPIOC->CRH&=0XFFF00FFF;//PC11/12 ÍÆÍìÊä³ö
	GPIOC->CRH|=0X00033000;	   
	GPIOC->ODR|=3<11;     //PC11,12 Êä³ö¸ß

}
//²úÉúIICÆðʼÐźÅ
void IIC_Start(void)
{
	SDA_OUT();     //sdaÏßÊä³ö
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//ǯסI2C×ÜÏߣ¬×¼±¸·¢ËÍ»ò½ÓÊÕÊý¾Ý 
}	  
//²úÉúIICÍ£Ö¹ÐźÅ
void IIC_Stop(void)
{
	SDA_OUT();//sdaÏßÊä³ö
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
	delay_us(4);							   	
}
//µÈ´ýÓ¦´ðÐźŵ½À´
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
//        0£¬½ÓÊÕÓ¦´ð³É¹¦
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDAÉèÖÃΪÊäÈë  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//ʱÖÓÊä³ö0 	   
	return 0;  
} 
//²úÉúACKÓ¦´ð
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//²»²úÉúACKÓ¦´ð		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}					 				     
//IIC·¢ËÍÒ»¸ö×Ö½Ú
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
//1£¬ÓÐÓ¦´ð
//0£¬ÎÞÓ¦´ð			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//À­µÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);   //¶ÔTEA5767ÕâÈý¸öÑÓʱ¶¼ÊDZØÐëµÄ
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    

u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDAÉèÖÃΪÊäÈë
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//·¢ËÍnACK
    else
        IIC_Ack(); //·¢ËÍACK   
    return receive;
}


<myiic.h>
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
#define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}
 
#define IIC_SCL    PCout(12) //SCL
#define IIC_SDA    PCout(11) //SDA	 
#define READ_SDA   PCin(11)  //ÊäÈëSDA 


void IIC_Init(void);                //³õʼ»¯IICµÄIO¿Ú				 
void IIC_Start(void);				//·¢ËÍIIC¿ªÊ¼ÐźÅ
void IIC_Stop(void);	  			//·¢ËÍIICÍ£Ö¹ÐźÅ
void IIC_Send_Byte(u8 txd);			//IIC·¢ËÍÒ»¸ö×Ö½Ú
u8 IIC_Read_Byte(unsigned char ack);//IIC¶ÁÈ¡Ò»¸ö×Ö½Ú
u8 IIC_Wait_Ack(void); 				//IICµÈ´ýACKÐźÅ
void IIC_Ack(void);					//IIC·¢ËÍACKÐźÅ
void IIC_NAck(void);				//IIC²»·¢ËÍACKÐźÅ

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

实验结果

实验结果

引用

stm32 工程是基于正点原子 mini stm32开发板,我在上面做了小小改动

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用STM32F103标准库进行I2C读写一个字节的示例代码: ```c #include "stm32f10x.h" #define I2C_SCL_PIN GPIO_Pin_6 #define I2C_SDA_PIN GPIO_Pin_7 #define I2C_PORT GPIOB #define I2C_SLAVE_ADDRESS 0xA0 void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; // Enable GPIOB clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Configure I2C pins: SCL and SDA GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(I2C_PORT, &GPIO_InitStructure); // Enable I2C clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // Configure I2C I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000; I2C_Init(I2C1, &I2C_InitStructure); // Enable I2C I2C_Cmd(I2C1, ENABLE); } void I2C_WriteByte(uint8_t data) { while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Generate START condition I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); // Send slave address and set write bit I2C_Send7bitAddress(I2C1, I2C_SLAVE_ADDRESS, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Send data byte I2C_SendData(I2C1, data); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Generate STOP condition I2C_GenerateSTOP(I2C1, ENABLE); } uint8_t I2C_ReadByte(void) { uint8_t data; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Generate START condition I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); // Send slave address and set read bit I2C_Send7bitAddress(I2C1, I2C_SLAVE_ADDRESS, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // Disable ACK I2C_AcknowledgeConfig(I2C1, DISABLE); // Generate STOP condition I2C_GenerateSTOP(I2C1, ENABLE); // Wait for data byte to be received while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); // Read data byte data = I2C_ReceiveData(I2C1); // Enable ACK I2C_AcknowledgeConfig(I2C1, ENABLE); return data; } int main(void) { uint8_t data; I2C_Configuration(); // Write data byte I2C_WriteByte(0x55); // Read data byte data = I2C_ReadByte(); while (1); } ``` 该示例代码假设硬件电路连接了STM32F103的I2C1和一个I2C从设备,从设备地址为0xA0。 首先,需要在STM32F103上配置I2C控制器和GPIO端口,具体函数为`I2C_Configuration()`。 然后,可以调用`I2C_WriteByte()`函数写入一个字节,或者调用`I2C_ReadByte()`函数读取一个字节。其中,写入操作包括生成启动条件、发送从设备地址和数据、生成停止条件;读取操作包括生成启动条件、发送从设备地址和读取请求、接收数据、生成停止条件。请注意,读取操作需要在接收数据前先禁止ACK,收到数据后再启用ACK。 在主函数中,示例代码写入0x55,然后读取一个字节并存储在变量`data`中。最后进入死循环。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值