I2C总线学习--实例代码

以三轴加速度传感器MMA7660为例:

#define MMA7660_SDA   GPIO_Pin_10  // PC10 //IIC数据线接口
#define MMA7660_SCL   GPIO_Pin_15  // PA15 //IIC时钟线接口
#define MMA7660_INT   GPIO_Pin_14  // PA14

1
/* 2 *========================================================= 3 * 函数功能:IIC总线初始化信号 4 * 参数:无 5 * 函数返回值:无 6 * SDA --- 7 * |________ 8 * SCL ---------- 9 * |____ 10 *========================================================= 11 */ 12 void I2C_Start(void) 13 { 14 MMA7660_SCL_H; 15 MMA7660_SDA_H; 16 Delayus(1); 17 MMA7660_SDA_L; 18 Delayus(1); 19 } 20 21 /* 22 *========================================================= 23 * 函数功能:IIC总线停止信号 24 * 参数:无 25 * 函数返回值:无 26 * SDA --------- 27 * ______| 28 * SCL --------- 29 * |___ 30 *========================================================= 31 */ 32 void I2C_Stop(void) 33 { 34 MMA7660_SCL_H; 35 MMA7660_SDA_L; 36 Delayus(1); 37 MMA7660_SDA_H; 38 Delayus(1); 39 } 40 /* 41 *========================================================= 42 * 函数功能:接收由从机向主机发起的ACK信号。 43 * 参数: ACKBIT 44 * 45 * 函数返回值:MMA_ERROR/MMA_OK 46 *========================================================= 47 */ 48 unsigned char I2C_SlaveAck(void) 49 { 50 unsigned char ts=0; 51 MMA7660_SCL_L; 52 MMA7660_SDA_H; 53 54 MMA_SDA_IOIN(); //SDA设为输入 55 Delayus(1); 56 MMA7660_SCL_H; 57 58 while(MMA7660_SDA_D!=0) 59 { 60 ts++; 61 if(ts>200) 62 { 63 MMA_SDA_IOOUT(); //SDA设为输出 64 MMA7660_SCL_L; 65 return MMA_ERROR; //返回错误 66 } 67 } 68 MMA7660_SCL_L; 69 MMA_SDA_IOOUT(); //SDA设为输出 70 //MMA7660_SDA_H; 71 Delayus(1); 72 return MMA_OK; //返回错误 73 } 74 75 /* 76 *========================================================= 77 * 函数功能:IIC写一个字节数据 78 * 参数: a:需要写入的一个字节数据 79 * 函数返回值:无 80 *========================================================= 81 */ 82 void I2C_WriteByte(unsigned char a) 83 { 84 unsigned char i; 85 for(i=0; i<8; i++) 86 { 87 MMA7660_SCL_L; 88 if((a&0x80)!=0) MMA7660_SDA_H; 89 else MMA7660_SDA_L; 90 a <<= 1; 91 Delayus(1); 92 MMA7660_SCL_H; 93 Delayus(1); 94 } 95 MMA7660_SCL_L; 96 if(I2C_SlaveAck()==MMA_ERROR) //等待从机的ACK信号。 97 { 98 return ; 99 } 100 } 101 102 /* 103 *========================================================= 104 * 函数功能:IIC读一个字节数据 105 * 参数:无 106 * 函数返回值:返回读出的一个字节数据 107 *========================================================= 108 */ 109 unsigned char I2C_ReadByte(void) 110 { 111 unsigned char a =0; 112 unsigned char i; 113 MMA_SDA_IOIN(); //SDA设为输入 114 for(i=0; i<8; i++) 115 { 116 a <<= 1; 117 MMA7660_SCL_H; 118 Delayus(1); 119 if(MMA7660_SDA_D==1) a |= 0x01; 120 Delayus(1); 121 MMA7660_SCL_L; 122 Delayus(2); 123 } 124 return a; 125 } 126 127 /* 128 ********************************************************** 129 * 130 * MMA7660相关函数 131 * 132 ********************************************************** 133 */ 134 /* 135 *========================================================= 136 * 函数功能:写MAA7660寄存器 137 * 参数: 138 * Regs_Addr - 寄存器地址 139 * Regs_Data - 寄存器值 140 * 函数返回值: 141 *========================================================= 142 */ 143 void MMA7660_WriteReg(unsigned char Regs_Addr,unsigned char Regs_Data) 144 { 145 I2C_Start(); 146 I2C_WriteByte(MMA7660_DEV_WRITE); //先写Slave地址,并配置成写模式 147 I2C_WriteByte(Regs_Addr); //写寄存器地址 148 I2C_WriteByte(Regs_Data); //写寄存器内容 149 I2C_Stop(); //结束本段IIC进程 150 } 151 152 /* 153 *========================================================= 154 * 函数功能:读MAA7660单字节 155 * 参数 156 * Regs_Addr - 寄存器地址 157 * 函数返回值:寄存器值 158 *========================================================= 159 */ 160 unsigned char MMA7660_ReadReg(unsigned char Regs_Addr) 161 { 162 unsigned char ret; 163 164 I2C_Start(); 165 166 I2C_WriteByte(MMA7660_DEV_WRITE); //先写Slave地址,并配置成写模式 167 I2C_WriteByte(Regs_Addr); //写寄存器地址 168 169 I2C_Start(); 170 I2C_WriteByte(MMA7660_DEV_READ); //写Slave地址,并配置成读模式 171 ret=I2C_ReadByte(); //从传感器中读出数据 172 I2C_SlaveAck(); 173 I2C_Stop(); //结束本段IIC进程 174 175 return ret; 176 177 }

 

你可能感兴趣的:(学习)