请问哪位高手用过STM32模拟IIC和MPR121通信的程序
时间:10-02
整理:3721RD
点击:
最好能提供源码,小第我初学STM32,很多地方不懂,还请大家多指教,谢谢!
模拟IIC的话,基本代码都一样的,不过我用别的单片机可能延时有所不同,所以如果出问题,那里可能会出错。把GPIO口改一下就ok了吧。
以下是陀螺仪的,没有其他例子了。
- //刚开始记着将SCL 和SDA引脚定义为输出,并且将SDA输入使能:
- //如:GPIOB->PIDR ^=1<<27;DDRH3=1;DDRH4=1;
- #include "common.h"
- #include "include.h"
- //#include "iic.h"
- #define uchar unsigned char
- int dis_datax,dis_datay,dis_dataz;
- int IIC_Receive[6];
- uchar IIC_ERROR; /*应答标志位*/
- #define SCL_out PTC10_OUT //定义IIC时钟线输出高低IO2
- #define SDA_out PTC11_OUT //定义IIC数据线输出高低IO3
- #define SCL_in PTC10_IN //定义IIC时钟线输入
- #define SDA_in PTC11_IN //定义IIC数据线输入
- #define SCL_dir DDRC10 //定义时钟线方向寄存器
- #define SDA_dir DDRC11 //定义数据线方向寄存器
- #define READ 0xD2 //定义L3G4200DIIC地址
- void Delay1us(u8 x)
- {
- u16 i;
- for(i=0;i<64*x;i++);
- }
- /***************************************************
- IIC通信
- 注意 !总线频率为80MHZ,如需应用与不同频率,请
- 更改延时函数,增减至合适的NOP数量。器件地址为SDO接高的地址
- SDO默认为高。
- ****************************************************/
-
- void IIC_START()
- {
- SDA_out=1; /*发送起始条件的数据信号*/
- Delay1us(1);
- SCL_out=1;
- Delay1us(5); /*起始条件建立时间大于4.7us,延时*/
- SDA_out=0; /*发送起始信号*/
- Delay1us(5); /* 起始条件锁定时间大于4μs*/
- SCL_out=0; /*钳住IIC总线,准备发送或接收数据 */
- Delay1us(2);
- }
- void IIC_STOP()
- {
- SDA_out=0; /*发送结束条件的数据信号*/
- Delay1us(1); /*发送结束条件的时钟信号*/
- SCL_out=1; /*结束条件建立时间大于4us*/
- Delay1us(5);
-
- SDA_out=1; /*发送IIC总线结束信号*/
- Delay1us(4);
- }
- void IIC_Send_ack()
- {
- SDA_out=1;
- Delay1us(1);
- SCL_out=1;
- Delay1us(5);
- SCL_out=0;
- Delay1us(2);
- }
- void IIC_Check_ack()
- {
- Delay1us(3);
- SCL_out=0;
- Delay1us(3);
- SDA_dir=0;
- SDA_in=1;
- Delay1us(3);
- SCL_out=1;
- Delay1us(5);
- if(SDA_in==1)
- IIC_ERROR=1;
- else
- IIC_ERROR=0;
- SCL_out=0;
- Delay1us(3);
- SDA_dir=1;
- }
- //**************通过IIC总线发送1字节数据***************//
- void IIC_Send1byte(uchar data)
- {
- unsigned int i=8;
- uchar m=data;
- uchar temp;
- for(i=8;i>0;i--)
- {
- temp=m&0x80;
- if(temp==0x80)
- SDA_out=1;
- else
- SDA_out=0;
- Delay1us(5);
- SCL_out=1;
- Delay1us(5);
- SCL_out=0;
- m=m<<1;
- }
- }
- //***************通过IIC总线接受1字节数据******************//
- uchar IIC_Receive1byte()
- {
- int i=8;
- uchar j=0;
- SDA_dir=0;
- SDA_in=1;
- for(i=8;i>0;i--)
- {
- SDA_in=1;
- Delay1us(3);
- SCL_out=1;
- Delay1us(5);
- if(SDA_in==1)
- j=j|0x01;
- else
- j=j;
- SCL_out=0;
-
- if(i!=1)
- {
- j=j<<1;
- }
- }
- SDA_dir=1;
- return j;
- }
- // *****通过IIC总线向某一寄存器写入一个字节数据********
- void IIC_write(uchar add,uchar mem,uchar data) // 写数据(器件地址,寄存器地址,数据)
- {
- IIC_START();
- IIC_Send1byte(add);
- IIC_Check_ack();
- IIC_Send1byte(mem);
- IIC_Check_ack();
- IIC_Send1byte(data);
- IIC_Check_ack();
- IIC_STOP();
- }
- //***************L3G4200D读取*******************//
- void L3G4200D_Init()
- {
- IIC_write(READ,0X20, 0x8F);
- IIC_write(READ,0X21, 0x00);
- IIC_write(READ,0X22, 0x08);
- IIC_write(READ,0X23, 0x36 );
- IIC_write(READ,0X24, 0x00);
- }
- int IIC_Read(uchar add,uchar mem) // 读数据(器件地址,寄存器地址)
- {
- int data;
- IIC_START();
- IIC_Send1byte(add);
- IIC_Check_ack();
- IIC_Send1byte(mem);
- IIC_Check_ack();
- IIC_START();
- IIC_Send1byte(add+1);
- IIC_Check_ack();
- data=IIC_Receive1byte();
- IIC_Send_ack();
- IIC_STOP();
- return data;
- }
- void GET_AngleSpeed()
- {
-
- IIC_Receive[0]=IIC_Read(READ,0X28); // x
- IIC_Receive[1]=IIC_Read(READ,0X29); //
- dis_datax=(IIC_Receive[1]<<8)+IIC_Receive[0];
-
- IIC_Receive[2]=IIC_Read(READ,0X2A); // Y
- IIC_Receive[3]=IIC_Read(READ,0X2B); //数据合成
- dis_datay=(IIC_Receive[3]<<8)+IIC_Receive[2]; //因为经过了自检,初始后波形更好,但是不在0位
-
- IIC_Receive[4]=IIC_Read(READ,0X2C); // Z
- IIC_Receive[5]=IIC_Read(READ,0X2D); //
- dis_dataz=(IIC_Receive[5]<<8)+IIC_Receive[4]; //
- }