STM8 I/O口模拟I2C
2019-11-11 来源:eefocus
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; //读器件地址为写地址加1
I2C_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 { *(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 { 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)),太郁闷了
- 采埃孚与SiliconAuto推出自动驾驶实时I/O接口芯片
- 采埃孚和SiliconAuto联合推出用于ADAS计算的I/O芯片
- 恩智浦i.MX 952应用处理器动态局部调光机制解析
- 恩智浦发布全新i.MX 93W,融合边缘计算与安全无线连接,加速物理AI部署
- 新品发布 | AP 推出可编程串行I/O模块(PSIO),数字音频测试再升级!
- 基于KickStart软件的MOSFET脉冲I-V特性表征
- I/O完成关键突破,我国算力核心部件攻克国产化“最后1%”
- 油耗仅3L超日系!吉利上半年将发布i-HEV智能双擎,并推4-5款新车
- 基于KickStart软件的MOSFET脉冲I-V特性表征方案
- 东芝推出适用于工业设备过流检测的高速响应、I/O全范围双通道比较器(CMOS)
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策




