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开发板,我在上面做了小小改动