STM8L152模拟IIC程序
更新时间:2023-03-08 06:25:11 阅读量: 综合文库 文档下载
- stm8l152中文手册推荐度:
- 相关推荐
STM8L152模拟IIC程序
//初始化IIC接口
void AT24CXX_Init(void) {
IIC_Init(); }
//在AT24CXX指定地址读出一个数据 //ReadAddr:开始读数的地址 //返回值 :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr) {
u8 temp=0; IIC_Start();
if(EE_TYPE>AT24C16) {
IIC_Send_Byte(0XA0); //发送写命令 IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr>>8);//发送高地址 IIC_Wait_Ack();
}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%6); //发送低地址 IIC_Wait_Ack(); IIC_Start();
IIC_Send_Byte(0XA1); //进入接收模式 IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件 return temp; }
//在AT24CXX指定地址写入一个数据 //WriteAddr :写入数据的目的地址 //DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{ IIC_Start();
if(EE_TYPE>AT24C16) {
IIC_Send_Byte(0XA0); //发送写命令 IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr>>8);//发送高地址 }else {
IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据 }
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%6); //发送低地址
IIC_Wait_Ack(); IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack(); IIC_Stop();//产生一个停止条件 delay_us(20000); }
//在AT24CXX里面的指定地址开始写入长度为Len的数据 //该函数用于写入16bit或者32bit的数据. //WriteAddr :开始写入的地址 //DataToWrite:数据数组首地址
//Len :要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len) { u8 t;
for(t=0;t AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff); } } //在AT24CXX里面的指定地址开始读出长度为Len的数据 //该函数用于读出16bit或者32bit的数据. //ReadAddr :开始读出的地址 //返回值 :数据 //Len :要读出数据的长度2,4 u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len) { u8 t; u32 temp=0; for(t=0;t temp<<=8; temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1); } return temp; } //检查AT24CXX是否正常 //这里用了24XX的最后一个地址(255)来存储标志字. //如果用其他24C系列,这个地址要修改 //返回1:检测失败 //返回0:检测成功 u8 AT24CXX_Check(void) { u8 temp; temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX if(temp==0X55)return 0; else//排除第一次初始化的情况 { AT24CXX_WriteOneByte(255,0X55); temp=AT24CXX_ReadOneByte(255); if(temp==0X55)return 0; } return 1; } //在AT24CXX里面的指定地址开始读出指定个数的数据 //ReadAddr :开始读出的地址 对24c02为0~255 //pBuffer :数据数组首地址 //NumToRead:要读出数据的个数 void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead) { while(NumToRead) { *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++); NumToRead--; } } //在AT24CXX里面的指定地址开始写入指定个数的数据 //WriteAddr :开始写入的地址 对24c02为0~255 //pBuffer :数据数组首地址 //NumToWrite:要写入数据的个数 void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite) { while(NumToWrite--) { AT24CXX_WriteOneByte(WriteAddr,*pBuffer); WriteAddr++; pBuffer++; } } 本篇仍然是模拟IIC,基本思路仍然是STM32的模拟IIC思路。具体内容还是参考STM32使用模拟IIC操作EEPROM。 示例代码如下: stm8_iic.h文件内容如下: #ifndef _stm8_iic_h_ #define _stm8_iic_h_ #include \ extern unsigned char BQ25890x_write_reg(unsigned char *buffer,unsigned char addr,unsigned char num); extern unsigned char BQ25890x_read_reg(unsigned char *buffer,unsigned char addr,unsigned char num); #define IICSPEED 100000 #define BQ25890_I2C_ADDR (0x6A) #endif stm8_iic.c内容如下: #define SlaveAddress (BQ25890_I2C_ADDR) #define IIC_SDA_GPIO_Pin GPIO_Pin_0 #define IIC_SCL_GPIO_Pin GPIO_Pin_1 #define IIC_GPIOx GPIOC void Delay(void) { nop(); nop(); nop(); nop(); nop(); nop(); } //使用软件模拟IIC //PC0--SDA PC1---SCL //初始化 void BQ25890H_init(void) { GPIO_Init(IIC_GPIOx, IIC_SDA_GPIO_Pin, GPIO_Mode_Out_PP_High_Fast); GPIO_Init(IIC_GPIOx, IIC_SCL_GPIO_Pin, GPIO_Mode_Out_PP_High_Fast); } //读取数据 unsigned char SDA_READ(void) { //return GPIO_ReadInputPin(IIC_GPIOx, IIC_SDA_GPIO_Pin); return GPIO_ReadInputDataBit(IIC_GPIOx, IIC_SDA_GPIO_Pin); } //产生起始信号 void IIC_Start(void) { GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_Low_Slow);//set SDA pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow);//set SCL pin as output low Delay(); } //产生停止信号 void IIC_Stop(void) { GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_Low_Slow);//set SDA pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as output high Delay(); } //等待响应信号 //0--接收应答成功 1-接收应答失败 unsigned char IIC_Wait_Ack(void) { unsigned char ucErrTime = 0; GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_In_PU_No_IT); //set sda as input with pull up while(SDA_READ()) { ucErrTime++; if(ucErrTime > 250) { IIC_Stop(); return 1; } } GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow); //set SCL pin as output low Delay(); return 0; } //产生ACK信号 void IIC_Ack(void) { GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output low Delay(); //延时 GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_Low_Slow);//set SDA pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow); //set SCL pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow); //set SCL pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as output high Delay(); } //No ACK void IIC_NAck(void) { GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow); //set SCL pin as output low Delay(); GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); //延时 GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow);//set SCL pin as output low Delay(); //延时 } //IIC发送一个字节 void IIC_Send_Byte(unsigned char txd) { unsigned char i; GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow); //set SCL pin as output low Delay(); for(i = 0; i < 8; i++) { if(txd & 0x80) { GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow);//set SDA pin as outputhigh } else { GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_Low_Slow);//set SDA pin as output low } txd <<= 1; GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow); //set SCL pin as output low Delay(); } } //读取一个字节 unsigned char IIC_Read_Byte(unsigned char ack) { unsigned char i, res = 0; GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_In_PU_No_IT); //set sda as input with pull up for(i = 0; i < 8; ++i ){ GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow);//set SCL pin as output high Delay(); GPIO_Init(GPIOC,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Slow);//set SCL pin as output high Delay(); res <<= 1; if(SDA_READ()){ res ++; } } return res; } //写数据 unsigned char BQ25890x_write_reg(unsigned char *pBuffer,unsigned char WriteAddr,unsigned char NumToWrite) { unsigned char u_wait_err = 0; IIC_Start(); IIC_Send_Byte(SlaveAddress << 1);//slave addr u_wait_err |= IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr); //register addr u_wait_err |= IIC_Wait_Ack(); while(NumToWrite--) { IIC_Send_Byte(*pBuffer); u_wait_err |= IIC_Wait_Ack(); pBuffer++; } IIC_Stop(); if(u_wait_err == 0) return 0; return 1; } // unsigned char BQ25890x_read_reg(unsigned char *pBuffer,unsigned char WriteAddr,unsigned char NumToRead) { unsigned char u_wait_err = 0; IIC_Start(); IIC_Send_Byte(SlaveAddress<<1); // SlaveAddress 0x7e u_wait_err |= IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr); // address u_wait_err |= IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte((SlaveAddress<<1)+1); // SlaveAddress 0x7e u_wait_err |= IIC_Wait_Ack(); while(--NumToRead) { *pBuffer = IIC_Read_Byte(1); IIC_Ack(); pBuffer++; } *pBuffer = IIC_Read_Byte(1); IIC_NAck(); IIC_Stop(); if(u_wait_err == 0) return 0; return 1; } 好了,这就是这部分的内容了。 #include \#include \ #include \ #define AT24C32_SETSDAIN GPIO_Init(AT24C32_SDA_PORT, GPIO_MODE_IN_FL_NO_IT) #define AT24C32_SETSDAOUT GPIO_Init(AT24C32_SDA_PORT, GPIO_MODE_OUT_OD_LOW_SLOW) #define I2C_SLAW 0xA0 /*器件地址选择及写标志*/ #define I2C_SLAR 0xA1 /*器件地址选择及读标志*/ GPIO_PIN_6, GPIO_PIN_6, void nops(void) { // asm(\// asm(\ uint16_t i = 0; for (; i < 5; i++); } // 总线复位 void I2C_Reset(void) { AT24C32_SCL_HIGH; AT24C32_SDA_HIGH; } // I2C操作严重错误 void I2C_Error(void) { //复位I2C总线 I2C_Reset(); //进入死循环 while (1) { } } // 发送起始条件 void I2C_Start_A(void) /*起始条件*/ { AT24C32_SCL_HIGH; nops(); AT24C32_SDA_LOW; nops(); AT24C32_SCL_LOW; nops(); } // 停止条件 void I2C_Stop_A(void) { AT24C32_SDA_LOW; nops(); AT24C32_SCL_HIGH; nops(); AT24C32_SDA_HIGH; nops(); AT24C32_SCL_LOW; nops(); } // 产生一个时钟信号 uint8_t I2C_GenerateClock(void) { uint8_t bData = 0; uint16_t t = 0; AT24C32_SCL_HIGH; nops(); for (t = 0; t < 6; t++); if (AT24C32_READSDA) { bData = 1; } AT24C32_SCL_LOW; nops(); return bData; } // 应答位 void I2C_Ack(uint8_t bAckYes) { if (bAckYes) { AT24C32_SDA_LOW; } else { AT24C32_SDA_HIGH; } I2C_GenerateClock(); AT24C32_SDA_HIGH; } // 发送数据子程序, ucData为要求发送的数据 uint8_t I2C_Send(uint8_t ucData) { uint8_t i; for (i = 0; i < 8; i++) { if (ucData & 0x80) { AT24C32_SDA_HIGH; } else { AT24C32_SDA_LOW; } ucData <<= 1; I2C_GenerateClock(); } AT24C32_SDA_HIGH; return (!I2C_GenerateClock()); } // 读一个字节的数据,并返回该字节值 uint8_t I2C_Read(void) { uint8_t ucData = 0; uint8_t i; for (i = 0; i < 8; i++) { ucData <<= 1; if (I2C_GenerateClock()) { ucData |= 1; } } return ucData; } // 设置下一步操作的地址(一字节地址) uint8_t I2C_SetAddress(uint16_t u16Addr) { // 发送启动信号 I2C_Start_A(); // 发送访问地址 return (I2C_Send(I2C_SLAW) && I2C_Send(u16Addr)); } // 设置下一步操作的地址(两字节地址) uint8_t I2C_SetAddress16(uint16_t u16Addr) { // 发送启动信号 I2C_Start_A(); // 发送从器件地址 // 发送访问地址 return (I2C_Send(I2C_SLAW) && I2C_Send(u16Addr >> 8) && I2C_Send(u16Addr & 0xff)); } // 向8位地址的器件( 如:24C02 )写数据 bAddressIs16bit = 0 // 向16位地址的器件( 如:24C32 )写数据 bAddressIs16bit = 1 void Write_Byte_24c32(uint8_t *pDat, uint16_t u16Addr, uint8_t ucNbyte, uint8_t bAddressIs16bit) { uint8_t bWriteError = FALSE; //写数据出错标志位 uint8_t i; uint8_t ucDataBuf = 0; uint32_t Cnt = 0; for (i = 0; i < ucNbyte; i++) { if (bAddressIs16bit) { if (I2C_SetAddress16(u16Addr + i) == 0) { bWriteError = TRUE; break; } } else { if (I2C_SetAddress(u16Addr + i) == 0) { bWriteError = TRUE; break; } } ucDataBuf = *(pDat + i); if (I2C_Send(ucDataBuf) == 0) { bWriteError = TRUE; break; } I2C_Stop_A(); ucDataBuf = 12; do { I2C_Start_A(); } while ((++Cnt < 500000) && I2C_Send(I2C_SLAW) == 0); //如果50mS内还没有响应,则进入保护性报警状态 if (Cnt == 500000) { bWriteError = TRUE; break; } I2C_Stop_A(); } if (bWriteError) { I2C_Error(); } } // 从8位地址的器件( 如:24C02 )读数据 bAddressIs16bit = 0 // 从16位地址的器件( 如:24C32 )读数据 bAddressIs16bit = 1 void Read_nByte_24c32(uint8_t *pDat, uint16_t u16Addr, uint8_t ucNbyte, uint8_t bAddressIs16bit) { uint8_t bReadError标志寄存器 = FALSE; //读EEPROM错误标志位 uint8_t i; uint8_t ucDataBuf = 0; if (bAddressIs16bit) { if (I2C_SetAddress16(u16Addr) == 0) { bReadError = TRUE; } } else { if (I2C_SetAddress(u16Addr) == 0) { bReadError = TRUE; } } if (bReadError) { I2C_Error(); } I2C_Start_A(); if (I2C_Send(I2C_SLAR) == 0) { bReadError = TRUE; } if (bReadError) { I2C_Error(); } for (i = 0; i < ucNbyte; i++) { ucDataBuf = I2C_Read(); *(pDat + i) = ucDataBuf; I2C_Ack(i != (ucNbyte - 1)); } I2C_Stop_A(); } uint8_t Read_Byte_24c32(uint16_t u16Addr) { uint8_t EepromDataBuf = 0xFF; //从16位地址的器件( 如:24C32 )读数据 bAddressIs16bit = 1 Read_nByte_24c32(&EepromDataBuf, u16Addr, 1, DEVICE_ADDR); return EepromDataBuf; } //修改EEPROM数据 void ModifData_24c32(uint16_t u16Addr, uint8_t *pDat, uint16_t uclen) { //向16位地址的器件( 如:24C32 )写数据 bAddressIs16bit = 1 Write_Byte_24c32(pDat, u16Addr, uclen, DEVICE_ADDR); } 1. STM8I/O口模拟I2C所读数据不正确 2. STM8 I/O口模拟I2C 3. 4. 5. #define I2C_ERR 0 6. 7. #define I2C_CRR 1 8. 9. #define I2CDataIn 1 10. 11. #define I2CDataOut 0 12. 13. #define I2C_PORT (GPIOC) 14. 15. #define I2CSCL (GPIO_PIN_7) 16. 17. #define I2CSDA (GPIO_PIN_6) 18. 19. 20. //*************************************************************** 21. 22. // I2C Data input/output 23. 24. // 0-Output, 1-Input 25. 26. //*************************************************************** 27. 28. void I2CDataInOut(bool InOut) 29. 30. { 31. 32. if(InOut) 33. 34. { 35. 36. GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT); 37. 38. } 39. 40. else 41. 42. { 43. 44. GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST); 45. 46. } 47. 48. } 49. 50. //*************************************************************** 51. 52. // Send start condition 53. 54. // ensure data is high then issue a start condition 55. 56. // see also i2c_Start() macro 57. 58. //*************************************************************** 59. 60. void I2C_Start (void) 61. 62. { 63. 64. GPIO_WriteHigh(I2C_PORT, I2CSDA); 65. 66. _delay_5us(5); 67. 68. GPIO_WriteHigh(I2C_PORT, I2CSCL); 69. 70. _delay_5us(5); 71. 72. GPIO_WriteLow(I2C_PORT, I2CSDA); 73. 74. _delay_5us(5); 75. 76. } 77. 78. //*************************************************************** 79. 80. // Send stop condition 81. 82. // data low-high while clock high 83. 84. //*************************************************************** 85. 86. void I2C_Stop (void) 87. 88. { 89. 90. GPIO_WriteLow(I2C_PORT, I2CSDA); 91. 92. _delay_5us(5); 93. 94. GPIO_WriteHigh(I2C_PORT, I2CSCL); 95. 96. _delay_5us(5); 97. 98. GPIO_WriteHigh(I2C_PORT, I2CSDA); 99. 100. } 101. 102. //*************************************************************** 103. 104. //ROUTINE NAME : I2C_Ack 105. 106. //INPUT/OUTPUT : None. 107. 108. //DESCRIPTION : Acknoledge generation from now. 109. 110. //COMMENTS : Transfer sequence = DATA, ACK. 111. 112. //*************************************************************** 113. 114. void I2C_Rack(void) 115. 116. { 117. 118. GPIO_WriteLow(I2C_PORT, I2CSDA); 119. 120. _delay_5us(5); 121. 122. GPIO_WriteHigh(I2C_PORT, I2CSCL); 123. 124. _delay_5us(5); 125. 126. GPIO_WriteLow(I2C_PORT, I2CSCL); 127. 128. _delay_5us(5); 129. 130. } 131. 132. 133. //*************************************************************** 134. 135. //ROUTINE NAME : I2C_nAck 136. 137. //INPUT/OUTPUT : None. 138. 139. //DESCRIPTION : Non acknoledge generation from now. 140. 141. //COMMENTS : Transfer sequence = DATA, NACK. 142. 143. //*************************************************************** 144. 145. void I2C_nAck (void) 146. 147. { 148. 149. GPIO_WriteHigh(I2C_PORT, I2CSDA); 150. 151. _delay_5us(5); 152. 153. GPIO_WriteHigh(I2C_PORT, I2CSCL); 154. 155. _delay_5us(5); 156. 157. GPIO_WriteLow(I2C_PORT, I2CSCL); 158. 159. _delay_5us(5); 160. 161. } 162. 163. //*************************************************************** 164. 165. // Send a byte to the slave 写一个数据没有应答 166. 167. // return I2C_ERR OR I2C_CRR 168. 169. //*************************************************************** 170. 171. bool SendByte(UCHAR I2cData) 172. 173. { 174. 175. UCHAR i; 176. 177. bool I2CStatus; 178. 179. 180. for(i=0; i<8; i++) 181. 182. { 183. 184. GPIO_WriteLow(I2C_PORT, I2CSCL); 185. 186. _delay_5us(5); 187. 188. if(I2cData & 0x80) 189. 190. {GPIO_WriteHigh(I2C_PORT, I2CSDA);} 191. 192. else 193. 194. {GPIO_WriteLow(I2C_PORT, I2CSDA);} 195. 196. GPIO_WriteHigh(I2C_PORT, I2CSCL); 197. 198. _delay_5us(5); 199. 200. I2cData <<= 1; 201. 202. } 203. 204. GPIO_WriteLow(I2C_PORT, I2CSCL); 205. 206. GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答 207. 208. 209. 210. I2CDataInOut(I2CDataIn); 211. 212. 213. GPIO_WriteHigh(I2C_PORT, I2CSCL); 214. 215. _delay_5us(5); 216. 217. if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0) 218. 219. { 220. 221. I2CStatus = I2C_CRR; 222. 223. } 224. 225. else 226. 227. { 228. 229. I2CStatus = I2C_ERR; 230. 231. } 232. 233. I2CDataInOut(I2CDataOut); 234. 235. return I2CStatus; 236. 237. } 238. 239. 240. //*************************************************************** 241. 242. //ROUTINE NAME : I2Cm_RxData 243. 244. //INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte . 245. 246. //DESCRIPTION : Receive a data byte. 247. 248. //COMMENTS : Transfer sequence = DATA, ACK, EV7... 249. 250. //*************************************************************** 251. 252. UCHAR RcvByte(void) 253. 254. { 255. 256. UCHAR i; 257. 258. UCHAR ReadByte=0; 259. 260. GPIO_WriteHigh(I2C_PORT, I2CSDA); 261. 262. 263. I2CDataInOut(I2CDataIn); 264. 265. _delay_5us(10); 266. 267. for(i=0; i<8; i++) 268. 269. { 270. 271. ReadByte <<= 1; 272. 273. GPIO_WriteLow(I2C_PORT, I2CSCL); 274. 275. _delay_5us(5); 276. 277. GPIO_WriteHigh(I2C_PORT, I2CSCL); 278. 279. _delay_5us(5); 280. 281. 282. if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1) 283. 284. {ReadByte |= 0x01;} 285. 286. _delay_5us(5); 287. 288. } 289. 290. GPIO_WriteLow(I2C_PORT, I2CSCL); 291. 292. I2CDataInOut(I2CDataOut); 293. 294. _delay_5us(10); 295. 296. return ReadByte; 297. 298. } 299. 300. 301. /******************************************************* 302. 303. 读N个数据,参数:? 304. 305. wrDAdr: write device-address 写器件地址?? 306. 307. wordAdr: word address 读数据的寄存器地址?? 308. 309. rdDAdr: read device-address 读器件地址 310. 311. *pRdDat: p->read data 读数据指针 312. 313. num: number 需要读数据的个数 314. 315. *******************************************************/ 316. 317. bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num) 318. 319. { 320. 321. bool I2CAck; 322. 323. UCHAR i=0; 324. 325. UCHAR rdDAdr; 326. 327. rdDAdr = wrDAdr+1; //读器件地址为写地址加1 328. 329. I2C_Start(); /*启动I2C*/ 330. 331. _delay_5us(5); 332. 333. I2CAck = SendByte(wrDAdr); /*发写器件地址*/ 334. 335. if(!I2CAck) 336. 337. { 338. 339. return I2C_ERR; 340. 341. } 342. 343. I2CAck = SendByte(wordAdr); /*发寄存器地址*/ 344. 345. if(!I2CAck) 346. 347. { 348. 349. return I2C_ERR; 350. 351. } 352. 353. 354. I2C_Start(); /*重启I2C*/ 355. 356. I2CAck = SendByte(rdDAdr); /*发读器件地址*/ 357. 358. if(!I2CAck) 359. 360. { 361. 362. return I2C_ERR; 363. 364. } 365. 366. _delay_5us(5); 367. 368. for(i=0;i 372. *(pRdDat+i) = RcvByte(); 373. 374. I2C_Rack(); 375. 376. } 377. 378. if(i==num-1) 379. 380. { 381. 382. *(pRdDat+i) = RcvByte(); 383. 384. I2C_nAck(); 385. 386. } 387. 388. I2C_Stop(); 389. 390. return I2C_CRR; 391. 392. } 393. 394. 395. /******************************************************* 396. 397. 写N个数据,前N-1个要应答,最后一个不要应答 398. 399. wrDAdr: write device-address 写器件地址?? 400. 401. wordAdr: word address 写数据的寄存器地址? 402. 403. *pWrDat: p->write data 写数据指针 404. 405. num: number 需要写入的数据个数 406. 407. *******************************************************/ 408. 409. bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num) 410. 411. { 412. 413. bool I2CAck; 414. 415. unsigned char i; 416. 417. 418. I2C_Start(); /*启动I2C*/ 419. 420. _delay_5us(5); 421. 422. I2CAck = SendByte(wrDAdr); /*发写器件地址*/ 423. 424. if(!I2CAck) 425. 426. { 427. 428. return I2C_ERR; 429. 430. } 431. 432. I2CAck = SendByte(wordAdr); /*发要写的寄存器地址*/ 433. 434. if(!I2CAck) 435. 436. { 437. 438. return I2C_ERR; 439. 440. } 441. 442. for(i=0;i 446. I2CAck = SendByte(*(pWrDat+i)); 447. 448. if(!I2CAck) 449. 450. {return I2C_ERR;} 451. 452. } 453. 454. if(i==num-1) 455. 456. { 457. 458. I2CAck = SendByte(*(pWrDat+num-1)); 459. 460. if(!I2CAck) 461. 462. {return I2C_ERR;} 463. 464. } 465. 466. I2C_Stop(); 467. 468. return I2CAck; 469. 470. } 以上代码不知为何读出数据不正确,用示波器看我发送的器件地址,寄存器地址这些都对,器件输出的数据是0xFF,程序中读出返回的数据是0x00,弄了一天没对相当郁闷,同志们指点下 终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了
正在阅读:
STM8L152模拟IIC程序03-08
2017比学赶超实施方案09-22
高中成语解释09-07
地球概论作业习题01-17
安全培训考试试卷——带答案(供参考)04-09
全乡综治信访稳定工作会议主持词12-28
TFT-LCD的接口种类05-26
课堂导入环节中存在的问题和不足03-23
- 计算机试题
- 【2012天津卷高考满分作文】鱼心人不知
- 教育心理学历年真题及答案--浙江教师资格考试
- 20180327-第六届“中金所杯”全国大学生金融知识大赛参考题库
- 洪林兴达煤矿2018年度水情水害预测预报
- 基本要道讲义
- 机电设备安装试运行异常现象分析与对策
- 《有机化学》复习资料-李月明
- 非常可乐非常MC2--非常可乐广告策划提案 - 图文
- 2011中考数学真题解析4 - 科学记数法(含答案)
- 企业人力资源管理师三级07- 09年真题及答案
- 基于单片机的光控自动窗帘控制系统设计说明书1 - 图文
- 20160802神华九江输煤皮带机安装方案001
- (共53套)新人教版一生物必修2(全册)教案汇总 word打印版
- 2014行政管理学总复习
- 中国银监会关于加强地方政府融资平台贷款风险监管的指导意见
- 民宿酒店核心竞争与研究
- 游园活动谜语大全2012
- 河南省天一大联考2016届高三英语5月阶段性测试试题(六)(A卷)
- 小型超市管理系统毕业论文详细设计4
- STM8L152
- 模拟
- 程序
- IIC
- 操作系统内存分配算法模拟实现
- 中国各乡镇、街道名录大全(吉林省)
- 高等教育自学考试合同法和民法试题大全
- 2018年市委书记在开发区工作会议上的讲话
- 高考化学常见题型解题技巧 - 化学平衡中的常见解题方法及思路(8)
- 国家人口计生委巡视组巡视工作规则
- 个股期权从业人员考试题库(含答案)
- 物理诗词俗语知识
- 2017年绿色建筑材料公司组织架构和部门职能
- 新部编人教版语文二年级下册全册教学设计(含全部课后反思)
- 哈大冬季施工措施
- 隧道下穿方案
- 三月桃花水教案
- 高二数学月考试卷(含答案) - 图文
- DM642技术参考手册2型
- 2007年二级建造师《法规知识》真题
- 基于PLC的变频恒压供水设计
- 信号与系统复习试题(含答案)
- “生命成长,责任担当”主题班会教案
- 2018年计划生育工作总结(共3篇)