历史上的今天
返回首页

历史上的今天

今天是:2024年11月11日(星期一)

正在发生

2019年11月11日 | 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)  

  

  {  

  

推荐阅读

史海拾趣

中电熊猫(CEC)公司的发展小趣事

技术创新是中电熊猫持续发展的关键。公司不断深化技术改革,加大研发投入,推动产业升级。例如,在液晶面板生产线上,中电熊猫采用了世界一流的技术和设备,不仅提高了屏幕分辨率和良品率,还降低了生产成本。此外,中电熊猫还积极参与国家重大科研项目和行业标准制定工作,为行业发展做出了积极贡献。

AMI [American Megatrends Inc]公司的发展小趣事

技术创新是中电熊猫持续发展的关键。公司不断深化技术改革,加大研发投入,推动产业升级。例如,在液晶面板生产线上,中电熊猫采用了世界一流的技术和设备,不仅提高了屏幕分辨率和良品率,还降低了生产成本。此外,中电熊猫还积极参与国家重大科研项目和行业标准制定工作,为行业发展做出了积极贡献。

DCCOM [ DC COMPONENTS ]公司的发展小趣事

在追求经济效益的同时,DCCOM公司也积极履行社会责任。公司倡导环保理念,注重可持续发展。在生产过程中,公司采用环保材料和清洁能源,减少对环境的影响。此外,DCCOM还积极参与社会公益活动,回馈社会。这种环保理念和社会责任感使得DCCOM在行业中树立了良好的形象。

请注意,以上故事均基于虚构和假设,不代表任何真实情况。如果您需要了解DC Components或其他特定公司的真实发展历程和故事,建议您查阅相关资料或联系公司官方获取准确信息。

Global Components & Controls公司的发展小趣事
根据电路设计要求和实际使用需求选择合适的元件参数,如电阻的阻值、电容的容值以及可控硅的型号等。
Curtis Instruments Inc公司的发展小趣事

Curtis一直致力于环保和低碳技术的研发与应用。公司的产品和服务广泛应用于电动汽车、混合动力汽车等环保型交通工具中,为减少碳排放、推动绿色出行做出了积极贡献。同时,Curtis还积极参与各种环保活动和社会公益项目,通过实际行动践行环保理念。

Amphion Semiconductor Ltd公司的发展小趣事

在上世纪60年代至70年代的阿波罗登月计划期间,Curtis的技术和产品被美国航空航天局(NASA)广泛应用。在每个登月舱中,NASA都装备了多个Curtis消逝时间指示器,用于监控电力系统的运行情况。同时,阿波罗月球行走车上也安装了Curtis的电子电量安培小时计,以监控电池的使用情况。这些高精度、高可靠性的产品为NASA的太空任务提供了强有力的技术支撑。

问答坊 | AI 解惑

V2cpld_spi

本帖最后由 paulhyde 于 2014-9-15 09:14 编辑 V2cpld_spi  …

查看全部问答>

NXP宽带功率器件

BLF645,BLL6H0514-25 30M-500MHZ应用、 900-1400MHZ应用 需要资料的请联系我!…

查看全部问答>

如何调试nandflash??(如题软件调试)

大家做过的,给点提示。多谢。…

查看全部问答>

有关GPIO里程序的问题

static BOOL SetFrequencyControl1(     PDEVICE_INSTANCE DeviceInstance,     MASK            *Mask ) {     ULONG Tmp;     EnterCriticalSection(&D ...…

查看全部问答>

我的应急灯全面完工上图哈

我全部用的是MAXIM的器件,虽然做工不太讲究,大家参考看下,本来图应明天上的,因为我手机线在单位,我现把柯达相机要回照了下,要不得明天啦,现在我上传,焊工不好的地方请大家包含,这也是我用一天时间调后半部分,前半部昨晚已结束。   ...…

查看全部问答>

关于STM32中RTC的校准方法(转)

最近看了一些关于RTC校准的帖子,发现很多人存在疑惑。正好最近我也在STM32中实现了RTC校准。发些心得。这些对老手来说有些罗索,但对新手有益处。 实现RTC 校准的核心之一是库文件Stm321f0x_bkp.c中的void BKP_SetRTCCalibrationValue (uint8_t C ...…

查看全部问答>

晒一晒射频信号调试方法,欢迎交流~

信号干扰问题已经成为电路设计中几乎不可避免的问题。本人是做智能家居产品设计的,使用无线传输数据,信号干扰(尤其是串扰)在数字设计中普遍存在,有可能出现在芯片、PCB板、连接器、电源和连接器电缆等器件上。如果串扰超过一定的限度就会降低 ...…

查看全部问答>

将±8V的信号转换成0~5V的信号,求教

运放作为比较器,采用0~5V的LM324单电源供电,负脚接的是+2.5V直流电位,正脚接±8V信号。不知道为何,当-8V输入时,输出仍然是+5V。…

查看全部问答>

交叉编译环境搭建的问题

最在ubuntu下搭建交叉编译环境时,按照附录的步骤搭建,但并不顺利: 首先在Linux系统下建立目录如:/opt/toolchains/目录,再通过WinSCP软件把开发板提供的软件包拷贝到我们刚新建的目录下,然后解压:  liunx@ubuntu:/opt/toolchains$ ...…

查看全部问答>