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

2019-07-20 21:03发布

测试了一下,延时使用的是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; }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
12条回答
ggkuku
2019-07-21 13:32
回复【3楼】ggkuku:
---------------------------------
我用的还是模拟的啊,还没有调试官方的模块。由于407的频率比较高,所以就比较快,我说的3m是不考了额外开销的速度,这个速度是通过延时算出来的,我测试了一下,iic大部分时间开销是在延时上,用0.25Us的延时,是4m的最高速率,考虑到延时函数进出的耗时,就算3m了。

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

一周热门 更多>