糾結了兩天,終于重新開始寫了,這兩天一直卡在硬件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] = '\0';
}
~~~
就這多,關于iic協議的解析請看我的百度博客:[http://hi.baidu.com/home/](http://hi.baidu.com/home/)ie_code
非常好的分析:[http://blog.gkong.com/zjcsharp_113287.ashx](http://blog.gkong.com/zjcsharp_113287.ashx)
[http://www.openedv.com/posts/list/18461.htm](http://www.openedv.com/posts/list/18461.htm)
藍橋杯-嵌入式交流群
147520657
- 前言
- 【菜鳥入門】stm32的第一個程序--LED
- 【菜鳥入門】stm32 之 掃描按鍵
- 【菜鳥入門】stm32 之 中斷按鍵
- 【菜鳥入門】stm32 之 USART
- 【菜鳥入門】stm32 之 iic
- 【菜鳥入門】stm32 之 eeprom
- 【菜鳥入門】stm32 之 pwm
- 【菜鳥入門】stm32 之 ADC 模數轉換
- 【菜鳥入門】stm32 之 實時時鐘
- 【菜鳥入門】stm32 之 DMA
- 【菜鳥入門】stm32 之 DAC
- 【STM庫應用】stm32 之 USART
- 中斷源去抖辦法
- stm32 啟動代碼應用技巧
- 【STM庫應用】stm32 之 IIC應用
- 【STM庫應用】stm32 之 中斷按鍵初始化(注意事項)
- 關于結構體初始化
- 【STM庫應用】stm32 之 TIM (詳解一 通用定時器)
- 【STM庫應用】stm32 之 TIM (詳解二 脈沖寬度、周期測量)
- 【stm32庫應用】SD驅動移植(基于SDIO外設)
- SD卡fat文件系統移植
- stm32 DMA初始化選項研究
- stm32 靈活靜態存儲控制器(FSMC)(NORFLASH\PSRAM)
- 【stm32+uC/OS-II】ucosii移植簡單詳細步驟
- STM32 加入調試信息來調試代碼
- NRF24L01 無線通信模塊使用