| 
 
新手上路 
 
	积分22金钱22 注册时间2017-4-19在线时间4 小时 | 
 
2金钱 
| 最近想用STM8S103F3驱动MMA8452Q这个加速度计,可是我模拟的IIC读到的一直是FF,下面是我写的程序,希望可以收到大家的指点,小弟谢谢了! 
 
 
 
 
 [mw_shl_code=c,true].C文件
 
 
 #include "soft_i2c.h"
 #include "math.h"
 #include "gpio.h"
 u8     BUF[8];
 int    dis_data;
 float  x,y,z;
 //===============================================================================
 //功能:初始化IIC
 //输入:无
 //输出:无
 //返回:无
 //===============================================================================
 void Soft_I2C_Int(void)
 {
 Set_I2C_SCL_Out1;
 Set_I2C_SDA_Out1;
 //  Set_I2C_SCL_HIGHT;
 //  Set_I2C_SDA_HIGHT;
 }
 //===============================================================================
 //功能:模拟I2C的起始条件
 //名称: Soft_I2C_Start
 //输入:无
 //返回:无
 //说明: 标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
 //===============================================================================
 void Soft_I2C_Start(void)
 {
 Set_I2C_SDA_Out1;
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 Set_I2C_SDA_LOW;
 //标准的I2C协议I2C起始条件:SCL为高时,SDA由高变低
 delay_us(5);
 Set_I2C_SCL_LOW;//钳住I2C总线,准备发送或接收数据
 }
 //===============================================================================
 //名称: Soft_I2C_Stop
 //功能: 模拟I2C的停止条件
 //返回: 无
 //说明: 标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
 //===============================================================================
 void Soft_I2C_Stop(void)
 {
 Set_I2C_SDA_Out0;
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 Set_I2C_SDA_HIGHT;
 //标准的I2C协议I2C停止条件:SCL为高时,SDA由低变高
 delay_us(5);
 }
 //===============================================================================
 //名称: Soft_I2C_Ack
 //功能: 模拟I2C的应答
 //返回:无
 //===============================================================================
 void Soft_I2C_Ack(void)
 {
 Set_I2C_SDA_Out0;
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 Set_I2C_SCL_LOW;
 delay_us(5);
 }
 //===============================================================================
 //名称: Soft_I2C_NAck
 //功能: 模拟I2C的不应答
 //===============================================================================
 void Soft_I2C_NAck(void)
 {
 Set_I2C_SDA_Out1;
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 Set_I2C_SCL_LOW;
 delay_us(5);
 }
 //===============================================================================
 //名称: Soft_I2C_recvACK
 //功能: 接收应答信号
 //===============================================================================
 BitAction Soft_I2C_RecvAck(void)
 {
 BitAction CY;
 Set_I2C_SDA_In;
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 CY =(BitAction) Get_I2C_SDA;
 Set_I2C_SCL_LOW;
 delay_us(5);
 
 return CY;
 }
 //===============================================================================
 //名称: Soft_I2C_Send_Byte
 //功能: 模拟I2C主器件向从器件发送一个字节
 //形参: Byte
 //返回: 无
 //===============================================================================
 void Soft_I2C_Send_Byte(u8 Byte)
 {
 u8 bit,temp;
 for(bit=0;bit<8;bit++)
 {
 temp = Byte & 0x80;
 if(temp == 0)
 {
 Set_I2C_SDA_Out0;
 }
 else if(temp > 0)
 {
 Set_I2C_SDA_Out1;
 }
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 Set_I2C_SCL_LOW;
 delay_us(5);
 Byte<<= 1;
 }
 Soft_I2C_RecvAck();
 }
 //===============================================================================
 //名称: Soft_I2C_Read_Byte
 //功能: 模拟I2C主器件向从器件读取一个字节
 //形参: 无
 //返回: 一个字节
 //明: 主器件从从器件里读一个字节
 //===============================================================================
 u8 Soft_I2C_Recv_Byte(void)
 {
 u8 bit,dat=0;
 Set_I2C_SDA_In;
 for(bit=0;bit<8;bit++)
 {
 dat<<=1;   //把上一时刻的值左移一位
 Set_I2C_SCL_HIGHT;
 delay_us(5);
 dat |= Get_I2C_SDA;
 Set_I2C_SCL_LOW;
 delay_us(5);
 }
 return dat;
 }
 //============================================================
 //功能:单字节写入
 //输入:无
 //输出:无
 //返回:无
 //===============================================================================
 void Single_Write_MMA8452(unsigned char REG_Address,unsigned char REG_data)
 {
 Soft_I2C_Start();                    //起始信号
 Soft_I2C_Send_Byte(SlaveAddress);    //发送设备地址+写信号
 Soft_I2C_Send_Byte(REG_Address);     //内部寄存器地址
 Soft_I2C_Send_Byte(REG_data);        //内部寄存器数据
 Soft_I2C_Stop();                     //停止信号
 }
 //===============================================================================
 //功能:连续读出MMA8452内部加速度数据,地址范围0x01~0x06
 //输入:无
 //输出:无
 //返回:无
 //===============================================================================
 void Multiple_Read_MMA8452(void)
 {
 unsigned char i;
 Soft_I2C_Start();                          //起始信号
 Soft_I2C_Send_Byte(SlaveAddress);          //发送设备地址
 
 Soft_I2C_Send_Byte(0x01);                  //发送存储单元地址,从0x01开始
 Soft_I2C_Start();                          //起始信号
 Soft_I2C_Send_Byte(SlaveAddress+1);        //发送设备地址+读信号
 
 for (i=0; i<6; i++)                       //连续读取6个地址数据
 {
 BUF = Soft_I2C_Recv_Byte();          //BUF[0]存储0x32地址中的数据
 if (i == 5)
 {
 Soft_I2C_NAck();                      //最后一个数据需要回NACK
 }
 else
 {
 Soft_I2C_Ack();                       //回应ACK
 }
 }
 Soft_I2C_Stop();                           //停止信号
 delay_us(5);
 }
 //===============================================================================
 //功能:初始化IIC
 //输入:无
 //输出:无
 //返回:无
 //===============================================================================
 void Init_MMA8452(void)
 {
 Soft_I2C_Int();                  //
 Single_Write_MMA8452(0x2A,0x01); //
 Single_Write_MMA8452(0x2B,0x02); //
 }
 //====================X轴数据====================================================
 float Get_x(void)
 {
 dis_data = (BUF[0]<<8)|BUF[1];//
 dis_data >>= 4;                  //
 x = (float)dis_data;
 return x;
 }
 
 //====================Y轴数据====================================================
 float Get_y(void)
 {
 dis_data=(BUF[2]<<8)|BUF[3]; //
 dis_data>>=4;                 //
 y=(float)dis_data;
 return y;
 }
 //====================Z轴数据====================================================
 float Get_z(void)
 {
 dis_data=(BUF[4]<<8)|BUF[5];//
 dis_data>>=4;                //
 z=(float)dis_data;
 return z;
 }
 //===============================================================================
 //功能:us级别延时,必须大于0
 //输入:无
 //输出:无
 //返回:无
 //===============================================================================
 void delay_us(volatile unsigned short time)
 {
 do{
 asm("nop");
 asm("nop");
 asm("nop");
 asm("nop");
 asm("nop");
 asm("nop");
 }while(--time);
 }
 
 
 .h文件
 
 #ifndef SOFT_I2C_H
 #define SOFT_I2C_H
 #include "stm8s.h"
 #define I2C_PIN  GPIOB
 #define I2C_SCL  GPIO_PIN_4
 #define I2C_SDA  GPIO_PIN_5
 #define Set_I2C_SCL_HIGHT    GPIO_WriteHigh(I2C_PIN, I2C_SCL)
 #define Set_I2C_SCL_LOW      GPIO_WriteLow(I2C_PIN, I2C_SCL)
 #define Set_I2C_SDA_HIGHT    GPIO_WriteHigh(I2C_PIN, I2C_SDA)
 #define Set_I2C_SDA_LOW      GPIO_WriteLow(I2C_PIN, I2C_SDA)
 #define Get_I2C_SDA          GPIO_ReadInputPin(I2C_PIN, I2C_SDA)
 #define Set_I2C_SCL_Out1      GPIO_Init(I2C_PIN, I2C_SCL, GPIO_MODE_OUT_PP_HIGH_FAST)
 #define Set_I2C_SDA_Out1      GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_OUT_PP_HIGH_FAST)
 #define Set_I2C_SCL_Out0      GPIO_Init(I2C_PIN, I2C_SCL, GPIO_MODE_OUT_PP_LOW_FAST)
 #define Set_I2C_SDA_Out0      GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_OUT_PP_LOW_FAST)
 
 #define Set_I2C_SDA_In       GPIO_Init(I2C_PIN, I2C_SDA, GPIO_MODE_IN_FL_NO_IT)//PU换成FL
 
 #define        SlaveAddress         0x38
 
 void Soft_I2C_Int(void);
 void Soft_I2C_Start(void);
 void Soft_I2C_Stop(void);
 void Soft_I2C_Ack(void);
 void Soft_I2C_NAck(void);
 void Soft_I2C_Send_Byte(u8 Byte);
 u8 Soft_I2C_Recv_Byte(void);
 void Single_Write_MMA8452(unsigned char REG_Address,unsigned char REG_data);
 void delay_us(volatile unsigned short time);
 BitStatus Soft_I2C_RecvAck(void);
 void delay_init(unsigned char clk);
 void Init_MMA8452(void);
 void Multiple_Read_MMA8452(void);
 
 
 
 
 float Get_x(void);
 float Get_y(void);
 float Get_z(void);
 
 
 //void Multiple_Read_MMA8452(void)
 
 //void I2C_MMA8452_ReadByte(void)
 #endif[/mw_shl_code]
 
 | 
 |