【菜鸟入门】stm32 之 iic

纠结了两天,终于重新开始写了,这两天一直卡在硬件iic上,由于硬件iic是比较难啃的一块骨头,问题一大堆,明明感觉配置好,测试时,一会出这个问题,一会出那个问题,哎,说多了都是泪。。。。

最后木有办法了,总不能吊死在一棵树上吧,然后就写了个模拟的iic的,由于对iic研究和应用的比较多(我们实验室的设备都是iic通信的,所有设备的驱动都是我来写的),所以在搞这个的时候得心应手,一个小时就把所有的搞定了,有花了1个小时把eeprom(at24c02)调通;

我大致测了下,我的板子上的eeprom电路类似这个:

所以我要做的是就是把PB6配置称时钟线SCL,PB7配置成数据线SDA

这里我们再配置输出的时候,要把管脚配置成 General purpose output push-pull模式,具体原因看datasheet关于管脚配置的那章口头,说的很清楚;

先给大家看看我的头文件里面的定义

#ifndef __IIC_H__
#define __IIC_H__
#define INPUT	0x8
#define OUTPUT 0x3

/* Config GPIOx */
#define IIC				GPIOB
#define SCL_BIT		6
#define SDA_BIT		7

/*Set & Get GPIOx Value*/
#define SET_SDA(a)	do{
										if(a)	IIC->ODR |= 1<<SDA_BIT;
										else	IIC->ODR &= ~(1<<SDA_BIT);
										}while(0)
#define SET_SCL(a)  do{
										if(a) IIC->ODR |= 1<<SCL_BIT;
										else  IIC->ODR &= ~(1<<SCL_BIT);
										}while(0)

#define SDA_OUT			do{ 
										IIC->CRL &= ~((unsigned int)0xf<<(4*SDA_BIT));
										IIC->CRL |= (unsigned int)OUTPUT<<(4*SDA_BIT);
										}while(0)
#define SDA_IN			do{
										IIC->CRL &=  ~((unsigned int)0xf<<(4*SDA_BIT));
										IIC->CRL |= (unsigned int)INPUT<<(4*SDA_BIT);
										}while(0)
#define SDA_VAL			(IIC->IDR&(1<<SDA_BIT))
#define SDA_H			SET_SDA(1)
#define SDA_L			SET_SDA(0)
#define SCL_H			SET_SCL(1)
#define SCL_L			SET_SCL(0)
#define DELAY			delay_us(10)	

#define SLAVE_ADDR	0xA0
#define IIC_READ		0x01
#define IIC_WRITE		0x00

extern int iic_init(void);
extern void iic_start(void);
extern void iic_stop(void);
extern void iic_send_ack(unsigned char ack);
extern unsigned char iic_recv_ack(void);
extern void iic_send(unsigned char bit);
extern unsigned char iic_send_byte(unsigned char dat);
extern unsigned char iic_recv(void);
extern unsigned char iic_recv_byte(void);
extern int iic_send_str(char str[],int len);
extern void iic_recv_str(char str[],int len);

#endif

下面是iic的应用函数

#include <stm32f10x.h>
#include "init.h"
#include "iic.h"
/*
	SCL   PB6     
	SDA   PB7	
 */

int iic_init()
{
	RCC->APB2ENR |= 1<<3;	//Set Clock for GPIOB
	IIC->CRL &= ~((unsigned int)0xf<<(4*SCL_BIT));
	IIC->CRL |= (unsigned int)OUTPUT<<(4*SCL_BIT);		//config scl
	IIC->CRL &= ~((unsigned int)0xf<<(4*SDA_BIT));
	IIC->CRL |= (unsigned int)OUTPUT<<(4*SDA_BIT);		//config sda
	return 1;
}

void delay5us()
{
  DELAY;
}

/* iic start */
void iic_start()
{
    SDA_OUT;
    SCL_H;
    SDA_H;DELAY;
    SDA_L;DELAY;
    SCL_L;
}
/* iic stop */
void iic_stop()
{
    SDA_OUT;
		SCL_L;SDA_L;
    SCL_H;DELAY;
    SDA_H;DELAY;
}
/* 
 * iic send ack
 * ack (0:ACK 1:NAK)
 */
void iic_send_ack(unsigned char ack)
{
    SDA_OUT;SCL_L;
    if(ack == 0x00) SDA_L;
    if(ack == 0x01) SDA_H;
    DELAY;
    SCL_H;DELAY;
    SCL_L;DELAY;
}
/* receive ack */
unsigned char iic_recv_ack()
{
    u32 val = 0;
    SDA_IN;
    SCL_H;DELAY;
    val = SDA_VAL;
    SCL_L;DELAY;
    return (val!=0 ? 1:0);
}

/* send one bit*/
void iic_send(unsigned char bit)
{
    SCL_L;
    if(bit == 0x01) SDA_H;
    else            SDA_L;
    DELAY;
    SCL_H;DELAY;
    SCL_L;DELAY;
}
/* send one byte */
unsigned char iic_send_byte(unsigned char dat)
{
		unsigned char i = 0;
    SDA_OUT;
    for(i=0; i<8; i++)
    {
      if(dat & 0x80)	iic_send(0x01);
      else 	        iic_send(0x00);
      dat <<= 1;
    }
    return 1;
}
/* iic receive bit */
unsigned char iic_recv()
{
    u32 bit = 0;
    SCL_L;
    SCL_H;DELAY;
    bit = SDA_VAL; 
    SCL_L;DELAY;
    
    return (bit!=0 ? 1:0);
}
/* iic receive byte */
unsigned char iic_recv_byte()
{
    unsigned char i;
    unsigned char dat = 0;
    SDA_IN;
    for (i=0; i<8; i++)
    {   
      dat <<= 1;
      dat |= iic_recv();
        
    }
    return dat;
}
int iic_send_str(char str[],int len)
{
	int i=0;
	for(i=0; i<len; i++)
	{
		iic_send_byte(str[i]);
		if(iic_recv_ack())
			return i;
	}
	return len;
}
void iic_recv_str(char str[],int len)
{
	int i=0;
	for(i=0; i<len; i++)
	{
		str[i]=iic_recv_byte();
		iic_send_ack(0);
	}
	str[i] = "";
}

就这多,关于iic协议的解析请看我的百度博客:http://hi.baidu.com/home/ie_code

非常好的分析:http://blog.gkong.com/zjcsharp_113287.ashx

http://www.openedv.com/posts/list/18461.htm

蓝桥杯-嵌入式交流群

147520657

文章导航