STM8 I/O口模拟I2C

2019-11-11来源: eefocus关键字:STM8  I  O口  模拟I2C

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);  

  

[1] [2]
关键字:STM8  I  O口  模拟I2C 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479609.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM8S_010_I2C读写EEPROM(硬件方式)
下一篇:[嵌入式开发模块]DS3231时钟芯片 驱动程序

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8L低功耗调试总结
STM8L低功耗调试资料准备功耗数据目标实现低功耗资料准备在调试STM单片机相关功能时,习惯性的进入到STM官方论坛进行资料下载。调试STM8功耗也不例外,找到STM8L的应用笔记,选择最热,先看看官方提供的STM8入门文档,入门资料可以选择中文或者英文(STM8L和STM8AL入门)。资料里面有一段话,对功耗调试相当重要:6.6 不使用的 I/O 和特性微控制器都是为多种应用设计的,通常一个应用不会使用 100 % 的微控制器资源。为了避免不必要的功率消耗 (对电池供电应用特别重要),同时提高 EMC 性能,闲置时钟、计数器或 I/O 都不应浮空。 I/O 应该外部强制 (上拉或者下拉到闲置 I/O 引脚),并且不使用的功能应
发表于 2019-11-14
STM8L低功耗调试总结
STM8的停机模式
首先,STM8有三种低功耗模式,即等待、活跃停机和停机。具体它们三者有什么区别自己看官方手册去吧,这里只讲停机模式的应用,其他的一笔带过!一、进入的方式:等待模式进入用的指令是WFI,而活跃停机和停机用的都是halt(),所不同的是,在执行halt指令之前,如果开启了AWU,则是活跃停机,反之则是停机。还有一点要说明的是,在停机模式下独立看门狗是不能养的,而只能养窗口看门狗。二、具体进入的步骤:1、首先,你声明一个标志位,名字自己取。这个标志位是用来判断系统是该处于运行模式还是处于停机模式的。我这里用fPowerOn_flag,如下:bool fPowerOn_flag = FALSE;有了这个标志位以后就写下面的部分了:int
发表于 2019-11-14
halt低功耗模式
1. stm8l152有5种低功耗模式,wait mode, low power run mode, low power wait mode, active-halt mode, halt mode.2. 在halt模式下,cpu和外设时钟停止,可以通过外部中断或者复位来唤醒。3. 本实验设计为:led灯亮,紧接着进入halt模式,有按键时,中断,快速唤醒,led灯灭。     PWR_FastWakeUpCmd(ENABLE);  //快速唤醒使能     //所有IO输出低电平    GPIO_Init(GPIOA
发表于 2019-11-14
STM8L051低功耗模式测试文档
STM8L051的五种低功耗模式wait ,low power run mode,low power wait mode,Ative-Halt mode,Halt mode。WAIT  mode  在等待模式,CPU的时钟是停止的,被选择的外设继续运行。WAIT mode 分为两种方式:WFE,WFI。WFE是等待事件发生,才从等待模式中唤醒。WFI是等待中断发生,才从等待模式中唤醒。low power run mode  在低功耗运行模式下,CPU和被选择的外设在工作,程序执行在LSI或者LSE下,从RAM中执行程序,Flash和EEPROM都要停止运行。电压被配置成Ultra Low Power
发表于 2019-11-14
stm8l 低功耗 halt_active模式
第一次尝试做低功耗,芯片stm8l,用的半halt模式1、关于唤醒,可以用外部中断和RTC(stm8l不同的模式用的唤醒方式均不同)2、关于省电,如果没达到理想的电流,一般都是gpio口问题,没用到的都悬浮输入或输出低都是可以的,用到的统一量一下电平,看看哪个状态不对
发表于 2019-11-14
STM8L EXITB一个端口两个中断的实现
void EXTI_Config(void){     EXTI_DeInit();       EXTI_SetPinSensitivity(EXTI_Pin_5,EXTI_Trigger_Falling);     ITC_SetSoftwarePriority(EXTI5_IRQn, ITC_PriorityLevel_1);    GPIO_Init(KEY_PORT, KEY_RT_PIN, GPIO_Mode_In_PU_IT);    EXTI_SetPinSensitivity(
发表于 2019-11-14
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved