【菜鸟入门】stm32 之 iic

来源:互联网 发布:草图大师 mac 编辑:程序博客网 时间:2024/06/11 05:23

纠结了两天,终于重新开始写了,这两天一直卡在硬件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 INPUT0x8#define OUTPUT 0x3/* Config GPIOx */#define IICGPIOB#define SCL_BIT6#define SDA_BIT7/*Set & Get GPIOx Value*/#define SET_SDA(a)do{\if(a)IIC->ODR |= 1<<SDA_BIT;\elseIIC->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_OUTdo{ \IIC->CRL &= ~((unsigned int)0xf<<(4*SDA_BIT));\IIC->CRL |= (unsigned int)OUTPUT<<(4*SDA_BIT);\}while(0)#define SDA_INdo{\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_HSET_SDA(1)#define SDA_LSET_SDA(0)#define SCL_HSET_SCL(1)#define SCL_LSET_SCL(0)#define DELAYdelay_us(10)#define SLAVE_ADDR0xA0#define IIC_READ0x01#define IIC_WRITE0x00extern 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 GPIOBIIC->CRL &= ~((unsigned int)0xf<<(4*SCL_BIT));IIC->CRL |= (unsigned int)OUTPUT<<(4*SCL_BIT);//config sclIIC->CRL &= ~((unsigned int)0xf<<(4*SDA_BIT));IIC->CRL |= (unsigned int)OUTPUT<<(4*SDA_BIT);//config sdareturn 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] = '\0';}


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

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

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

蓝桥杯-嵌入式交流群
 147520657


原创粉丝点击