测试了一下,延时使用的是0.25us,加上其他开销,差不多能到3Mbit/S。
iic协议的上线是3.4Mbit/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;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
---------------------------------
正要使用F407的IIC,不理解的是,楼主为什么要用IO口模拟,不直接用IIC接口呢,难道F407的IIC接口有问题?
多谢!
一周热门 更多>