单片机
返回首页

【菜鸟入门】stm32 之 iic

2020-03-04 来源:eefocus

纠结了两天,终于重新开始写了,这两天一直卡在硬件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< else IIC->ODR &= ~(1< }while(0)

#define SET_SCL(a)  do{

if(a) IIC->ODR |= 1< else  IIC->ODR &= ~(1< }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<#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

#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 {

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 {

str[i]=iic_recv_byte();

iic_send_ack(0);

}

str[i] = '';

}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 如何利用ESP8266制作一个简单的四轴飞行器

  • 非常简单的150W功放电路图

  • 一个简单的警笛电路图

  • 基于IC555的可变PWM振荡器电路

  • 一个简单的立体声平衡指示器电路

  • 电谐波图形均衡器示意图

    相关电子头条文章