OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10364|回复: 6

IIC协议

[复制链接]

28

主题

306

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
1320
金钱
1320
注册时间
2012-6-3
在线时间
353 小时
发表于 2012-6-14 11:58:33 | 显示全部楼层 |阅读模式

各位帮忙看哈,我这个程序那里有问题,咋就是不通啊?
#include <stm32f10x_lib.h>
#include "24c02.h"
#include "delay.h"
#include "sys.h"

#define SCL_0 PCout(12)=0
#define SCL_1 PCout(12)=1

#define SDA_0 PCout(11)=0
#define SDA_1 PCout(11)=1

#define SDA_value PCin(11)

#define SCL_OUT() {GPIOC->CRH&=0xfff0ffff;GPIOC->CRH |=0x00030000;}//SCL线设为输出
#define SDA_OUT() {GPIOC->CRH&=0xffff0fff;GPIOC->CRH |=0x00003000;}//SDA线设为输出
#define SDA_IN()  {GPIOC->CRH&=0xffff0fff;GPIOC->CRH |=0x00008000;}//SDA线设为输入
 
void Init_24c02(void)//24c02接口初始化
{
   SCL_OUT();
   SDA_OUT();
   SCL_1;
   SDA_1;
   delay_ms(10); 
}

void start(void) //开始信号(由时序图看出,scl线为高电平,sda线由高到低跳变为开始信号)
{
  SDA_OUT();//SDA线设为输出
  SCL_OUT();//SCL线设为输出
  SDA_1;//sda=1
  delay_us(10);
  SCL_1;//scl=1
  delay_us(10);
  SDA_0;//sda=0,sda从高电平->低电平,起始信号
  //SCL_0;//scl=0,scl线处于被占用状态
  delay_us(10);
}

void stop(void)  //终止信号(由时序图看出,scl线为高电平,sda线由低到高跳变为停止信号)
{
  SDA_OUT();//SDA线设为输出
  SCL_OUT();//SCL线设为输出
  SDA_0;
  SCL_0;
  delay_us(10);
  SDA_1; //sda=1,sda从低电平->高电平,终止信号
  delay_us(10);
  SCL_1;
  delay_us(10);
}

void ack(void)  //应答信号
{
  u8 i=0;
  SCL_OUT();
  SDA_IN(); //SDA设为输入
  SCL_1;
  delay_us(10);
  while(( SDA_value==1)&&(i<250))i++;;//sda=0,已经应答;或者延时一段时间后,默认为已经应答
  SCL_0;   //应答后,拉低时钟线,使其处于被占用的状态
  delay_us(10);
}

void noack(void) //非应答信号(可以不写)
{
  SDA_OUT();//SDA设为输出
  SDA_1;
  delay_us(10);
  SCL_1;
  delay_us(10);
  SCL_0;  //scl有变化时,sda保持不变,即非应答
  delay_us(10);
}

void iicwr_byte(u8 dat)//写入一个字节
{  
   u8 i;
   SDA_OUT();//SDA线输出
   SCL_OUT();//SCL线输出
   SCL_0;  //只有在时钟线上的信号为低电平时,数据线上的高电平或低电平才允许变化
             //(时钟线为高电平时,才能进行读写;
             //也就是说读写数据时,必须将SCL拉高,然后送入或读出数据,完毕后,再将SCL拉低)
   delay_us(10);
   for(i=0;i<8;i++)
   {
    if(dat&0x80)//首先传输的是数据的最高位(MSB)
    {
      SDA_1;//sda=1;
    }
    else
    {
      SDA_0;//sda=0;
    }
    SCL_1;   //scl=1;(上升沿写入数据)时钟线为高电平时,才能进行读写
    delay_us(10);
    SCL_0;   //scl=0;(为下次上升沿的来临做准备)只有在时钟线上的信号为低电平时,据线上的高电平或低电平才允许变化
    delay_us(10);
    dat=dat<<1;//移位
    delay_us(10);
   }
    SDA_1;   //sda=1;  //数据线释放;
    delay_us(10);
}
u8 iicre_byte(void)   //读一个字节

   u8 i,dat;
   SDA_OUT();//SDA输出
   SCL_OUT();
   SCL_0;  //scl=0;
   delay_us(10);
   SDA_1;  //sda=1;  //数据线释放
   delay_us(10);
   for(i=0;i<8;i++)
   {
     SCL_1;//scl=1; //时钟线为高电平时,才能进行读写
     delay_us(10);
     dat=dat<<1;//判断8次,移位7次
     SDA_IN();//SDA输入
     if(SDA_value)
     {
       dat++;//自增,个位加1
     }
     SCL_0;//scl=0;数据才能改变
     delay_us(10);
   }
   return dat;
}

void write(u8 address,u8 dat)//写操作(需要地址和数据)
{
  //Init_24c02();    //初始化
  start();
  iicwr_byte(0xa0);//写器件地址(a是地址固定部分,0的前三位是选择位,第四位0为写;若第四位为1,则是读;)
  ack();
  iicwr_byte(address);//写器件内部存储器地址
  ack();
  iicwr_byte(dat);//数据
  ack();
  stop();
}

u8 read(u8 address)       //读操作(需要地址)
{
  u8 dat;
  //Init_24c02();    //初始化
  start();
  iicwr_byte(0xa0);//寻址(地址位1010000+0)//低位为0,即写
  ack();
  iicwr_byte(address);
  ack();
  start();//因为是读数据,所以需重复发起始信号
  iicwr_byte(0xa1);//寻址(地址位1010000+1)//低位为1,即读
  ack();
  dat=iicre_byte();//读出的给dat
  stop();
  return dat;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stm32f10x_lib.h"
#include "delay.h"
#include "usart.h"
#include "sys.h"
#include "24c02.h"

int main(void)
{
   Stm32_Clock_Init(9);  //时钟初始化
   delay_init(72);
   JTAG_Set(0x02);//关闭JTAG和SWD接口,使相关IO口,能作为普通IO口使用
   while(1)
   {
    RCC->APB2ENR |=(1<<4);//GPIOC口时钟打开
    RCC->APB2ENR |=(1<<3);//GPIOB口时钟打开
    GPIOB->CRL =0x33333333;//GPIOA.0~GPIOA.7设为输出
    Init_24c02();//24c02接口初始化
    write(7,0x55);//向第7个地址写入数据0x55
    delay_ms(20);
    GPIOB->ODR=read(7);//读取地址7的数据
    delay_ms(20);
   }

}

 


 

 

 


 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-6-14 12:55:03 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

28

主题

306

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
1320
金钱
1320
注册时间
2012-6-3
在线时间
353 小时
 楼主| 发表于 2012-6-14 18:55:12 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我之前在其他单片机上,都是用的这个代码,都是通的啊!不知为啥,移植到stm32上,就是不通,不知什么原因?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-6-14 19:19:38 | 显示全部楼层
这个你自己分析了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

31

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
233
金钱
233
注册时间
2012-3-19
在线时间
2 小时
发表于 2012-6-15 23:50:46 | 显示全部楼层
回复【楼主位】艾科:
---------------------------------
楼主会不会是延时的问题啊?前不久我们移植一个代码的时候也是延时那里出了问题,调了好久呢
回复 支持 反对

使用道具 举报

28

主题

306

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
1320
金钱
1320
注册时间
2012-6-3
在线时间
353 小时
 楼主| 发表于 2012-6-16 13:29:02 | 显示全部楼层
回复【5楼】SCUT_fanyu:
---------------------------------
有这个可能,但是我想一般延时出问题的话,也就可能是延时短了的可能性比较大,我把延时加长了很多,还是不行啊!!
回复 支持 反对

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2012-6-25
在线时间
0 小时
发表于 2012-8-28 11:27:43 | 显示全部楼层
回复【6楼】艾科:
---------------------------------
你解决了吗?我的到STM32  102后 就是没有应答、、、、
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 13:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表