STM8 I/O口模拟I2C
来源:互联网 发布:熟丝桃子圈微博全数据 编辑:程序博客网 时间:2024/06/05 17:08
STM8I/O口模拟I2C所读数据不正确STM8 I/O口模拟I2C#define I2C_ERR 0#define I2C_CRR 1#define I2CDataIn 1#define I2CDataOut 0#define I2C_PORT (GPIOC)#define I2CSCL (GPIO_PIN_7)#define I2CSDA (GPIO_PIN_6)//***************************************************************// I2C Data input/output// 0-Output, 1-Input//***************************************************************void I2CDataInOut(bool InOut){if(InOut) { GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT); }else { GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST); }}//***************************************************************// Send start condition// ensure data is high then issue a start condition// see also i2c_Start() macro//***************************************************************void I2C_Start (void){GPIO_WriteHigh(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);}//***************************************************************// Send stop condition// data low-high while clock high//***************************************************************void I2C_Stop (void){GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSDA);}//***************************************************************//ROUTINE NAME : I2C_Ack//INPUT/OUTPUT : None.//DESCRIPTION : Acknoledge generation from now.//COMMENTS : Transfer sequence = DATA, ACK.//***************************************************************void I2C_Rack(void){GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSCL);_delay_5us(5);}//***************************************************************//ROUTINE NAME : I2C_nAck//INPUT/OUTPUT : None.//DESCRIPTION : Non acknoledge generation from now.//COMMENTS : Transfer sequence = DATA, NACK.//***************************************************************void I2C_nAck (void){GPIO_WriteHigh(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSCL);_delay_5us(5);}//***************************************************************// Send a byte to the slave 写一个数据没有应答// return I2C_ERR OR I2C_CRR//***************************************************************bool SendByte(UCHAR I2cData){UCHAR i;bool I2CStatus;for(i=0; i<8; i++) { GPIO_WriteLow(I2C_PORT, I2CSCL); _delay_5us(5); if(I2cData & 0x80) {GPIO_WriteHigh(I2C_PORT, I2CSDA);} else {GPIO_WriteLow(I2C_PORT, I2CSDA);} GPIO_WriteHigh(I2C_PORT, I2CSCL); _delay_5us(5); I2cData <<= 1; } GPIO_WriteLow(I2C_PORT, I2CSCL); GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答 I2CDataInOut(I2CDataIn); GPIO_WriteHigh(I2C_PORT, I2CSCL); _delay_5us(5); if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0) { I2CStatus = I2C_CRR; } else { I2CStatus = I2C_ERR; } I2CDataInOut(I2CDataOut); return I2CStatus;}//***************************************************************//ROUTINE NAME : I2Cm_RxData//INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte.//DESCRIPTION : Receive a data byte.//COMMENTS : Transfer sequence = DATA, ACK, EV7...//***************************************************************UCHAR RcvByte(void){ UCHAR i; UCHAR ReadByte=0; GPIO_WriteHigh(I2C_PORT, I2CSDA);I2CDataInOut(I2CDataIn);_delay_5us(10);for(i=0; i<8; i++) { ReadByte <<= 1; GPIO_WriteLow(I2C_PORT, I2CSCL); _delay_5us(5); GPIO_WriteHigh(I2C_PORT, I2CSCL); _delay_5us(5); if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1) {ReadByte |= 0x01;} _delay_5us(5); } GPIO_WriteLow(I2C_PORT, I2CSCL);I2CDataInOut(I2CDataOut);_delay_5us(10); return ReadByte;}/******************************************************* 读N个数据,参数:? wrDAdr: write device-address 写器件地址?? wordAdr: word address 读数据的寄存器地址?? rdDAdr: read device-address 读器件地址 *pRdDat: p->read data 读数据指针 num: number 需要读数据的个数*******************************************************/bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num){bool I2CAck;UCHAR i=0;UCHAR rdDAdr;rdDAdr = wrDAdr+1; //读器件地址为写地址加1I2C_Start(); /*启动I2C*/_delay_5us(5);I2CAck = SendByte(wrDAdr); /*发写器件地址*/if(!I2CAck) { return I2C_ERR; }I2CAck = SendByte(wordAdr); /*发寄存器地址*/if(!I2CAck) { return I2C_ERR; }I2C_Start(); /*重启I2C*/ I2CAck = SendByte(rdDAdr); /*发读器件地址*/if(!I2CAck) { return I2C_ERR; }_delay_5us(5);for(i=0;i<num-1;i++) { *(pRdDat+i) = RcvByte(); I2C_Rack(); }if(i==num-1) { *(pRdDat+i) = RcvByte(); I2C_nAck(); }I2C_Stop();return I2C_CRR;}/*******************************************************写N个数据,前N-1个要应答,最后一个不要应答wrDAdr: write device-address 写器件地址?? wordAdr: word address 写数据的寄存器地址? *pWrDat: p->write data 写数据指针 num: number 需要写入的数据个数*******************************************************/bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num){bool I2CAck;unsigned char i;I2C_Start(); /*启动I2C*/_delay_5us(5);I2CAck = SendByte(wrDAdr); /*发写器件地址*/if(!I2CAck) { return I2C_ERR; }I2CAck = SendByte(wordAdr); /*发要写的寄存器地址*/if(!I2CAck) { return I2C_ERR; }for(i=0;i<num-1;i++) { I2CAck = SendByte(*(pWrDat+i)); if(!I2CAck) {return I2C_ERR;} }if(i==num-1) { I2CAck = SendByte(*(pWrDat+num-1)); if(!I2CAck) {return I2C_ERR;} }I2C_Stop();return I2CAck;}
以上代码不知为何读出数据不正确,用示波器看我发送的器件地址,寄存器地址这些都对,器件输出的数据是0xFF,程序中读出返回的数据是0x00,弄了一天没对相当郁闷,同志们指点下
终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了
- STM8 I/O口模拟I2C
- STM8 I/O口模拟I2C
- I/O口模拟I2C驱动代码
- 51单片机I/O模拟I2C 程序
- STM8 I口模拟串口通信
- STM8 模拟I2C驱动0.91寸OLED屏
- i/o 模拟IIC
- Android Things:外设I/O接口-I2C
- STM8 I2C的学习
- STM8 I2C从机
- I/O 模拟串口通信
- STM32F1使用I/0模拟I2C接口
- 用51单片机普通I/O口检测模拟值
- 用普通 I/O 口模拟标准 UART 串行口
- STM8单片机的触角——I/O口的应用 非原创但是 讲的很不错 拿来给大家 学习!
- STM8 模拟串口程序
- 通用的I/O模拟串口程序
- 通过I/O方式模拟串口接收
- httpd配置:实例及说明
- linux设备驱动程序学习(9) 与硬件通信
- 调用C或C++的DLL出现“方法的类型签名与 Interop 不兼容”
- 如何彻底卸载vc6.0
- SQL 创建登陆名,用户,角色
- STM8 I/O口模拟I2C
- 如何判断DataGridView中为空的单元
- 如何使用yum工具从iso镜像文件上安装
- think in java 笔记二 第五章
- 函数指针
- 判断数据网络是否可用
- 如何在绑定后的DataGridView中新增行。
- Life in the Fast I/O Lane
- XML中预定义的实体引用