OpenEdv-开源电子网

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

发一个高速stm32f407模拟IIC程序(3Mbit/s)

[复制链接]

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2012-11-17
在线时间
0 小时
发表于 2012-11-28 11:20:24 | 显示全部楼层 |阅读模式
测试了一下,延时使用的是0.25us,加上其他开销,差不多能到3Mbit/S。
iic协议的上线是3.4
Mbit/S。
基本达到了iic协议的极限了,我测试过0.2us的延时,很不稳定。
所以我觉得速度应该不低于iic模块。

void delay_ns(unsigned char nns)   0.25us延时
{
ntime=nns;
SysTick_Config(42);//0.25us产生一次中断,并对ntime减1
while(ntime);
SysTick->CTRL=0x00;
}
==========================================================
#ifndef __I2C_H__
#define __I2C_H__
#include "delay.h"
#include "stm32f4xx_conf.h"
 


#define IIC_SDA0    GPIOA->BSRRH=GPIO_Pin_2   //sda=0
#define IIC_SDA1    GPIOA->BSRRL=GPIO_Pin_2   //sda=1
#define IIC_SCL0    GPIOA->BSRRH=GPIO_Pin_3
#define IIC_SCL1    GPIOA->BSRRL=GPIO_Pin_3

#define SDA_IN() GPIOA->MODER|=GPIO_Mode_IN<<4;  //sda输入
#define SDA_OUT()   GPIOA->MODER|=GPIO_Mode_OUT<<4;//sda输出



#define IN            1
#define OUT           0



#define  SetIicScl(x) do{if(x){IIC_SCL1;} \      
                         else {IIC_SCL0;}\
}while(0)

#define  SetIicSda(x) do{if(x){IIC_SDA1;} \
                         else {IIC_SDA0;}\
}while(0)

//设置SDA IO口方向

#define  SetIicSdaDir(x) do{if(x){SDA_IN();} \
                            else {SDA_OUT();}\
}while(0)


#define  SoftDelay(i)  delay_ns(i)
#define ReadIicSda()  ((GPIOA->IDR&GPIO_Pin_2)!=0)?1:0  //判断接收到的bit
/***********************************************************************
 * Name: IicWriteDevice
 * Note: Write data to device
 * Para: device -> device address, buf->subaddress + data
 * Return : how many bytes have been write
*/
unsigned char IicWriteDevice(unsigned char device,unsigned char *buf, unsigned char cnt);

/***********************************************************************
 * Name: IicReadDevice
 * Note: Read data from device
 * Para: device->device address, subaddr->subaddress, acnt->subaddress lengh
 *       buf->read out data space, bcnt->read out data lengh
 * Return : write subaddress lengh
*/
unsigned char IicReadDevice(unsigned char device, unsigned char *subaddr, unsigned char acnt, unsigned char *buf, unsigned char bcnt);

void IIC_Init(void);

#endif

========================================================================
//#include "iicconf.h"
#include "iic.h"
#include <stm32f4xx.h>
#include <stdio.h>
#include "stm32f4xx_conf.h"

/***********************************************************************
 * Name: ReadIicSda()
 * Note: Read SDA state;
 * Para: None
 * Return : SDA state
*/

void IIC_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;//GPIO初始化结构体
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//外设时钟使能
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 |GPIO_Pin_3;//对应GPIO引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//状态为输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//IO速度为100MHZ
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
IIC_SDA1;
IIC_SCL1;     
}


/***********************************************************************
 * Name: IicStart()
 * Note: Start I2C Bus, SDA change to low when SCL is hight
 * Para: None
 * Return : None
*/
void IicStart(void)
{

SetIicSda(1);
  SetIicScl(1);
SoftDelay(1);
SetIicSda(0);
SoftDelay(0);
SetIicScl(0);
}

/***********************************************************************
 * Name: IicStop()
 * Note: Stop I2C Bus, SCL change to hight when SDA is hight
 * Para: None
 * Return : None
*/
void IicStop(void)
{

SetIicScl(1);
SetIicSda(0);
SoftDelay(1);
SetIicSda(1);
}

/***********************************************************************
 * Name: IicWriteByte(dat)
 * Note: Write 8bite data and get ack;
 * Para: dat -> the data which will be send out
 * Return : ack -> ack signal
*/
unsigned char IicWriteByte(unsigned char dat)
{
    unsigned char i;
unsigned char ack;

for(i=0; i<8; i++)
{
   if(dat & 0x80)
{
   SetIicSda(1);
}
else
{
   SetIicSda(0);
}
SoftDelay(1);
SetIicScl(1);
SoftDelay(1);
dat <<= 1;
SetIicScl(0);
}

SetIicSdaDir(IN);
SoftDelay(1);
SetIicScl(1);
SoftDelay(1);
ack = ReadIicSda();
SetIicScl(0);
SetIicSdaDir(OUT);

return ack;
}

/***********************************************************************
 * Name: IicReadByte
 * Note: Read 8bite data and Send  ack;
 * Para: ack=0 -> Set ack, ack=1 -> Set noack
 * Return : read data
*/
unsigned char IicReadByte(unsigned char ack)
{
    unsigned char i;
unsigned char dat=0;

SetIicSdaDir(IN);

for(i=0; i<8; i++)
{
   dat <<= 1;
SetIicScl(1);
SoftDelay(1);
if(ReadIicSda())
{
   dat |= 1;
}
SetIicScl(0);
}

SetIicSdaDir(OUT);

SetIicSda(ack);   // ack = 0; ask, ack = 1,stop
SoftDelay(1);
SetIicScl(1);
SoftDelay(1);
SetIicScl(0);

return dat;
}

/***********************************************************************
 * Name: IicWriteDevice
 * Note: Write data to device
 * Para: device -> device address, buf->subaddress + data
 * Return : how many bytes have been write
*/
unsigned char IicWriteDevice(unsigned char device, unsigned char *buf, unsigned char cnt)
{
    unsigned char i;

    IicStart();
if(IicWriteByte(device))
{
   IicStop();
return 0;
}

for(i=0; i<cnt; i++)
{
   if(IicWriteByte(*buf++))
   {
       IicStop();
break;
   }
    }

IicStop();
return i;
}

/***********************************************************************
 * Name: IicReadDevice
 * Note: Read data from device
 * Para: device->device address, subaddr->subaddress, acnt->subaddress lengh
 *       buf->read out data space, bcnt->read out data lengh
 * Return : write subaddress lengh
*/
unsigned char IicReadDevice(unsigned char device, unsigned char *subaddr, unsigned char acnt, unsigned char *buf, unsigned char bcnt)
{
    unsigned char i;
unsigned char wlen;
    IicStart();
if(IicWriteByte(device))
{
   IicStop();
   return 0;
}
for (i=0; i<acnt; i++)
{
if(IicWriteByte(*subaddr++))
{
IicStop();
return i;
}
}
wlen = i;

IicStart();
IicWriteByte(device|0x01);
for(i=0; i<bcnt-1; i++)
{
   *buf++ =  IicReadByte(0); // read & send ACK
}
*buf = IicReadByte(1); // read & send noack

IicStop();

return wlen;
}

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

使用道具 举报

33

主题

489

帖子

6

精华

金牌会员

Rank: 6Rank: 6

积分
1565
金钱
1565
注册时间
2011-12-10
在线时间
4 小时
发表于 2012-11-28 12:53:49 | 显示全部楼层
回复 支持 反对

使用道具 举报

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2012-11-17
在线时间
0 小时
 楼主| 发表于 2012-11-28 13:56:52 | 显示全部楼层
回复【2楼】骤雨龙元:
---------------------------------
f407部分代码你应该很眼熟吧。iic的程序我改自51,这个写的很简洁,额外开销很小。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-11-28 14:31:52 | 显示全部楼层
楼主这IIC接的什么从设备?可以这么快?
另外407把103,IIC的蛋疼问题解决了?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2012-11-17
在线时间
0 小时
 楼主| 发表于 2012-11-28 14:48:27 | 显示全部楼层
回复【3楼】ggkuku:
---------------------------------
我用的还是模拟的啊,还没有调试官方的模块。由于407的频率比较高,所以就比较快,我说的3m是不考了额外开销的速度,这个速度是通过延时算出来的,我测试了一下,iic大部分时间开销是在延时上,用0.25Us的延时,是4m的最高速率,考虑到延时函数进出的耗时,就算3m了。

实际上,我是用他写一个iic数码管显示,算上地址信息,一次写六个字节,一秒钟最快大概能写15000次的样子,所以实际有意义的出传输速度大概是50*15k=750k。
回复 支持 反对

使用道具 举报

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2012-11-17
在线时间
0 小时
 楼主| 发表于 2012-11-28 14:51:44 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
iic数码管是什么芯片我看不见,做在数码管里面了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-11-28 23:07:31 | 显示全部楼层
靠,这年头数码管都带IIC接口了...
碉堡了...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2012-11-17
在线时间
0 小时
 楼主| 发表于 2012-11-29 14:42:44 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
我问了一下买家 他使用的芯片是定制的 所以比较快。我的数码管要拉很远 又不能无线通信 所以就用iic好接线
回复 支持 反对

使用道具 举报

8

主题

53

帖子

0

精华

初级会员

Rank: 2

积分
105
金钱
105
注册时间
2012-5-26
在线时间
0 小时
发表于 2013-5-23 13:38:02 | 显示全部楼层
MARK.
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2011-12-13
在线时间
26 小时
发表于 2013-11-9 15:24:48 | 显示全部楼层
mark
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2014-9-11
在线时间
0 小时
发表于 2014-9-11 16:38:39 | 显示全部楼层
你好,怎么程序运行的不对呢·?请指教·
回复 支持 反对

使用道具 举报

24

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2014-3-6
在线时间
23 小时
发表于 2014-9-13 11:40:54 | 显示全部楼层
回复【11楼】mzchrist:
---------------------------------
正要使用F407的IIC,不理解的是,楼主为什么要用IO口模拟,不直接用IIC接口呢,难道F407的IIC接口有问题?

多谢!
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2015-9-6
在线时间
4 小时
发表于 2016-7-28 11:23:40 | 显示全部楼层
MARK 谢谢分享
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 22:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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