STM32驱动PCF8563,使用模拟IIC

发布者:自在逍遥最新更新时间:2018-09-09 来源: eefocus关键字:STM32  驱动PCF8563  模拟IIC 手机看文章 扫描二维码
随时随地手机看文章

#ifndef PCF8563_CFG_H

#define PCF8563_CFG_H

//////////////////////////////////////////////////////////////////////////////////////

//------------使用包含的头文件

#include "i2c_task.h"

#ifdef USE_MCU_STM32

#include "delay_task.h"

#endif


//---寄存器定义

#define PCF8563_REG_STATUS1 0x00

#define PCF8563_REG_STATUS2 0x01

#define PCF8563_REG_SECOND 0x02

#define PCF8563_REG_MINUTE 0x03

#define PCF8563_REG_HOURS 0x04

#define PCF8563_REG_DAY 0x05

#define PCF8563_REG_WEEK 0x06

#define PCF8563_REG_MONTH 0x07

#define PCF8563_REG_YEAR 0x08

#define PCF8563_REG_MINUTE_ALARM 0x09

#define PCF8563_REG_HOURS_ALARM 0x0A

#define PCF8563_REG_DAY_ALARM 0x0B

#define PCF8563_REG_WEEK_ALARM 0x0C

#define PCF8563_REG_CLKOUT 0x0D

#define PCF8563_REG_TIMER_CTR 0x0E

#define PCF8563_REG_TIMER 0x0F


//---I2C设备地址

#define PCF8563_WRITE_ADDR 0xA2

#define PCF8563_READ_ADDR 0xA3


//---CLKOUT的输出

#define PCF8563_CLKOUT_32768HZ 0

#define PCF8563_CLKOUT_1024HZ 1

#define PCF8563_CLKOUT_32HZ 2

#define PCF8563_CLKOUT_1HZ 3


//---定义使用的端口

//---SCL

#define PCF8563_SCL_PORT GPIOB

#define PCF8563_SCL_BIT LL_GPIO_PIN_8


//---SDA

#define PCF8563_SDA_PORT GPIOB

#define PCF8563_SDA_BIT LL_GPIO_PIN_9


//---结构体定义

typedef struct _RTC_HandlerType RTC_HandlerType;

//---时钟结构体的定义

struct _RTC_HandlerType

{

UINT8_T second; //---秒

UINT8_T minute; //---分

UINT8_T hour; //---时

UINT8_T day; //---天

UINT8_T week; //---星期

UINT8_T month; //---月

UINT8_T year; //---年

UINT8_T century; //---世纪

};

//---结构体定义

typedef struct _PCF8563_HandlerType PCF8563_HandlerType;

//---指针结构体定义

typedef struct _PCF8563_HandlerType *pPCF8563_HandlerType;

//---PCF853的数据结构体

struct _PCF8563_HandlerType

{

RTC_HandlerType msgRTC; //---实时时钟

I2C_HandlerType msgI2C; //---使用的I2C

};


//---外部调用的接口函数

extern PCF8563_HandlerType g_PCF8563;

extern pPCF8563_HandlerType pPCF8563;



//---函数定义

UINT8_T PCF8563_Init( void );

UINT8_T PCF8563_WriteReg( UINT8_T reg, UINT8_T val );

UINT8_T PCF8563_ReadReg( UINT8_T reg , UINT8_T *pVal,UINT8_T length );

UINT8_T PCF8563_ClockOut( UINT8_T preVal );

UINT8_T PCF8563_ReadRTC(void);

UINT8_T PCF8563_WriteRTC(RTC_HandlerType rtc);

///////////////////////////////////////////////////////////////////////////////

#endif /* PCF8563_CFG_H */



#include "pcf8563_cfg.h"

 

//---全局变量定义

PCF8563_HandlerType g_PCF8563=

{

.msgRTC=

{

 .year=0,

 .month=0,

 .day=0,

 .hour=0,

 .minute=0,

 .second=0,

},

.msgI2C=

{

.msgI2Cx = NULL,

.msgSclPort = PCF8563_SCL_PORT,

.msgSdaPort = PCF8563_SDA_PORT,

.msgSclBit = PCF8563_SCL_BIT,

.msgSdaBit = PCF8563_SDA_BIT,

.msgModelIsHW = 0,

.msgPluseWidth = 0,

.msgDelay = NULL,

.msgAddr = PCF8563_WRITE_ADDR,

.msgClockSpeed = 0,

.msgTask = NULL,

},

};

 

//---全局指针变量

pPCF8563_HandlerType pPCF8563=&g_PCF8563;

 

///////////////////////////////////////////////////////////////////////////////

//////函   数:

//////功   能:

//////输入参数: 

//////输出参数: 

//////说   明:

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_Init(void)

{

return I2CTask_MSW_Init( &pPCF8563->msgI2C , DelayTask_us );

}

 

///////////////////////////////////////////////////////////////////////////////

//////函   数:

//////功   能:写寄存器

//////输入参数: 

//////输出参数: 

//////说   明:

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_WriteReg(UINT8_T reg,UINT8_T val)

{

UINT8_T _return = OK_0;

//---启动并发送地址

_return=I2CTask_MSW_START(&pPCF8563->msgI2C, 1);

if (_return != OK_0)

{

//---启动写数据失败

_return = ERROR_2;

goto GoToExit;

}

//---发送寄存器地址

I2CTask_MSW_SendByte(&pPCF8563->msgI2C, reg);

//---读取ACK

_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);

if (_return!= OK_0)

{

//---发送数据失败

_return = ERROR_3;

goto GoToExit;

}

//---发送寄存器地址

I2CTask_MSW_SendByte(&pPCF8563->msgI2C, val);

//---读取ACK

_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);

GoToExit:

//---发送停止信号

I2CTask_MSW_STOP(&pPCF8563->msgI2C);

return _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函   数:

//////功   能:读取寄存器

//////输入参数: 

//////输出参数: 

//////说   明:

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_ReadReg( UINT8_T reg , UINT8_T *pVal,UINT8_T length )

{

UINT8_T _return = OK_0,i=0;

//---启动写数据

_return = I2CTask_MSW_START(&pPCF8563->msgI2C, 1);

if (_return != OK_0)

{

//---启动写数据失败

_return = ERROR_2;

goto GoToExit;

}

//---发送寄存器地址

I2CTask_MSW_SendByte(&pPCF8563->msgI2C, reg);

//---读取ACK

_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);

if (_return != OK_0)

{

//---发送数据失败

_return = ERROR_3;

goto GoToExit;

}

//---发送停止信号

I2CTask_MSW_STOP(&pPCF8563->msgI2C);

//---启动读取数据

_return = I2CTask_MSW_START(&pPCF8563->msgI2C, 0);

if (_return != OK_0)

{

//---启动读数据失败

_return = ERROR_4;

goto GoToExit;

}

for (i = 0;i < length;i++)

{

//---读取数据

pVal[i] = I2CTask_MSW_ReadByte(&pPCF8563->msgI2C);

if (i == (length - 1))

{

_return = 1;

}

//---发送应答信号

I2CTask_MSW_SendACK(&pPCF8563->msgI2C, _return);

}

_return = OK_0;

GoToExit:

//---发送停止信号

I2CTask_MSW_STOP(&pPCF8563->msgI2C);

return _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函   数: UINT8_T PCF8563_HandlerType_ClockOut(UINT8_T preVal)

//////功   能: PCF8563输出时钟,输出分频

//////输入参数: 

//////输出参数: 

//////说   明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_ClockOut(UINT8_T preVal)

{

UINT8_T _return = OK_0;

UINT8_T temp = 0;

//---写寄存器

_return=PCF8563_WriteReg( PCF8563_REG_CLKOUT, ( preVal | 0x80 ) );

if (_return!= OK_0)

{

_return = ERROR_2;

goto GoToExit;

}

//---读取寄存器

_return = PCF8563_ReadReg(PCF8563_REG_CLKOUT, &temp,1);

if (_return!=OK_0)

{

_return = ERROR_3;

goto GoToExit;

}

//---数据的校验

if ((temp&0x7F)!=preVal)

{

_return = ERROR_1;

}

GoToExit:

return _return ;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函   数:

//////功   能:

//////输入参数: 

//////输出参数: 

//////说   明:

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_ReadRTC(void)

{

UINT8_T _return = OK_0;

UINT8_T temp[7];

//---读取时钟

_return = PCF8563_ReadReg(PCF8563_REG_SECOND, temp, 7);

//---解析数据

if (_return== OK_0)

{

//---将获取的数据填充到缓存区

pPCF8563->msgRTC.second = (temp[0] & 0x7F);

pPCF8563->msgRTC.minute = (temp[1] & 0x7F);

pPCF8563->msgRTC.hour = (temp[2] & 0x3F);

pPCF8563->msgRTC.day = (temp[3] & 0x3F);

pPCF8563->msgRTC.week = (temp[4] & 0x07);

pPCF8563->msgRTC.month = (temp[5] & 0x1F);

//---年份

pPCF8563->msgRTC.year = temp[6];

//---世纪

if (temp[5] & 0x80)

{

pPCF8563->msgRTC.century = 0x19;

}

else

{

pPCF8563->msgRTC.century = 0x20;

}

}

return _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T PCF8563_WriteRTC(RTC_HandlerType rtc)

{

UINT8_T _return = OK_0;

//---判断数据类型是不是BCD码

if ((rtc.century!=0x19)||(rtc.century!=0x20))

{

//===处理数据位BCD格式

rtc.second = DecToBcd(rtc.second);

rtc.minute = DecToBcd(rtc.minute);

rtc.hour = DecToBcd(rtc.hour);

rtc.day = DecToBcd(rtc.day);

rtc.week = DecToBcd(rtc.week);

rtc.month = DecToBcd(rtc.month);

rtc.year = DecToBcd(rtc.year);

rtc.century = DecToBcd(rtc.century);

}

//---世纪参数的处理

if (rtc.century == 0x20)

{

rtc.month &= 0x3F;

}

else

{

rtc.month |= 0x80;

}

//---写秒

_return = PCF8563_WriteReg(PCF8563_REG_SECOND, rtc.second);

if (_return!= OK_0)

{

_return = ERROR_2;

goto GoToExit;

}

//---写分

_return = PCF8563_WriteReg(PCF8563_REG_MINUTE, rtc.minute);

if (_return!= OK_0)

{

_return = ERROR_3;

goto GoToExit;

}

//---写时

_return = PCF8563_WriteReg(PCF8563_REG_HOURS, rtc.hour);

if (_return!= OK_0)

{

_return = ERROR_4;

goto GoToExit;

}

//---写天

_return = PCF8563_WriteReg(PCF8563_REG_DAY, rtc.day);

if (_return!= OK_0)

{

_return = ERROR_5;

goto GoToExit;

}

//---写星期

_return = PCF8563_WriteReg(PCF8563_REG_WEEK, rtc.week);

if (_return!= OK_0)

{

_return = ERROR_6;

goto GoToExit;

}

//---写月

_return = PCF8563_WriteReg(PCF8563_REG_MONTH, rtc.month);

if (_return!= OK_0)

{

_return = ERROR_7;

goto GoToExit;

}

//---写年

_return = PCF8563_WriteReg(PCF8563_REG_YEAR, rtc.year);

GoToExit:

return _return;

}

#ifndef I2C_CFG_H

#define I2C_CFG_H

 

///////////////////////////////////////////////////////////////////////////////

//////使用该函数,首先保证GPIO的时钟已经使能,函数内部已经将端口配置为开漏输出

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

#include "complier_lib.h"

#ifdef USE_MCU_STM32

#include "gpio_task.h"

#endif

 

//===消息体模式

//---SDA端口

#define I2C_SDA_OUT_0(name,index) GPIO_OUT_0( name,index )

#define I2C_SDA_OUT_1(name,index) GPIO_OUT_1( name,index )

#define I2C_SDA_STATE(name,index) GPIO_GET_STATE( name,index )

#define I2C_SDA_READ(name,index) GPIO_SET_READ( name,index )

#define I2C_SDA_WRITE(name,index) GPIO_SET_WRITE( name,index )

//---SCL端口

#define I2C_SCL_OUT_0(name,index) GPIO_OUT_0( name,index )

#define I2C_SCL_OUT_1(name,index) GPIO_OUT_1( name,index )

#define I2C_SCL_STATE(name,index) GPIO_GET_STATE( name,index )

#define I2C_SCL_READ(name,index) GPIO_SET_READ( name,index )

#define I2C_SCL_WRITE(name,index) GPIO_SET_WRITE( name,index )

 

 

//---结构体定义

typedef struct _I2C_HandlerType I2C_HandlerType;

typedef struct _I2C_HandlerType *pI2C_HandlerType;

//---消息体的I2C

struct _I2C_HandlerType

{

I2C_TypeDef *msgI2Cx; //---使用的I2C接口

GPIO_TypeDef *msgSclPort; //---SCL端口

GPIO_TypeDef *msgSdaPort; //---SDA端口

UINT32_T msgSclBit; //---SCL引脚

UINT32_T msgSdaBit; //---SDA引脚

UINT8_T msgModelIsHW; //---工作模式,默认是软件模拟---0,硬件模式---1

UINT8_T msgPluseWidth; //---脉冲宽度,软件模拟使用

void (*msgDelay)(UINT32_T delay); //---延时参数

UINT16_T msgAddr; //---设备的地址

UINT32_T msgClockSpeed; //---硬件I2C的时钟速度

UINT8_T (*msgTask)(I2C_HandlerType I2CxHandlerType,UINT16_T length,UINT8_T *pVal,UINT8_T msg); //---消息体处理函数

};

 

//---函数定义

UINT8_T I2C_HandlerType_Init(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_Init(I2C_HandlerType *I2CxHandlerType, void(*msgDelay)(UINT32_T delay));

UINT8_T I2C_MSW_DeInit(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_START(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_STOP(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_ACK(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_NACK(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_ReadACK(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_WaitACK(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_SendACK(I2C_HandlerType *I2CxHandlerType, UINT8_T isNACK);

UINT8_T I2C_MSW_SendByte(I2C_HandlerType *I2CxHandlerType, UINT8_T val);

UINT8_T I2C_MSW_SendBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum);

UINT8_T I2C_MSW_ReadByte(I2C_HandlerType *I2CxHandlerType);

UINT8_T I2C_MSW_ReadBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum);

UINT8_T I2C_MSW_SendCMD(I2C_HandlerType *I2CxHandlerType, UINT8_T cmd, UINT8_T isStart, UINT8_T isStop);

 

//////////////////////////////////////////////////////////////////////////////////////

#endif /*i2c_cfg_H */

#include "i2c_cfg.h"

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_HandlerType_Init(I2C_HandlerType *I2CxHandlerType)

{

/*

I2CxHandlerType->msgPluseWidth = 0;

I2CxHandlerType->msgDelay = NULL;

I2CxHandlerType->msgAddr = 0;

I2CxHandlerType->msgClockSpeed = 0;

I2CxHandlerType->msgTask = NULL;

*/

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_Init(I2C_HandlerType *I2CxHandlerType,void(*msgDelay)(UINT32_T delay))

{

#ifdef USE_MCU_STM32

//---使能GPIO的时钟

GPIOTask_Clock(I2CxHandlerType->msgSclPort,1);

GPIOTask_Clock(I2CxHandlerType->msgSdaPort,1);

//---SCL和SDA端口输出高电平

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

//---GPIO的结构体

LL_GPIO_InitTypeDef GPIO_InitStruct;

//---GPIO的初始化

GPIO_InitStruct.Pin = I2CxHandlerType->msgSclBit; //---对应的GPIO的引脚

GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; //---配置状态为输出模式

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; //---GPIO的速度

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; //---输出模式---开漏输出

GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; //---上拉

//---SCL的初始化

LL_GPIO_Init(I2CxHandlerType->msgSclPort, &GPIO_InitStruct);

//---SDA的初始化

GPIO_InitStruct.Pin = I2CxHandlerType->msgSdaBit;

LL_GPIO_Init(I2CxHandlerType->msgSdaPort, &GPIO_InitStruct);

#endif 

//---设置使用的延时函数

if (msgDelay!=NULL)

{

I2CxHandlerType->msgDelay = msgDelay;

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_DeInit(I2C_HandlerType *I2CxHandlerType)

{

//---端口设置为输入模式

I2C_SCL_READ(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

I2C_SDA_READ(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

//---SCL和SDA端口输出高电平

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

//---注销任务函数

if (I2CxHandlerType->msgTask!=NULL)

{

I2CxHandlerType->msgTask = NULL;

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_START(I2C_HandlerType *I2CxHandlerType)

{

//---发送起始条件的数据信号

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---发送起始信号;

I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//---判断I2C启动信号是否成功,读取SDA的状态信号,成功SDA---0;失败SDA---1

if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)!= OK_0)

{

return ERROR_1;

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_STOP(I2C_HandlerType *I2CxHandlerType)

{

//---发送停止条件的数据信号

I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---判断I2C启动信号是否成功,读取SDA的状态信号,成功SDA---1;失败SDA---0

if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)== OK_0)

{

return ERROR_1;

}

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_ACK(I2C_HandlerType *I2CxHandlerType)

{

I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_NACK(I2C_HandlerType *I2CxHandlerType)

{

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_ReadACK(I2C_HandlerType *I2CxHandlerType)

{

UINT8_T _return = OK_0;

//---读取应答信号

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//---延时等待

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---读取SDA的状态信号---ACK状态下SDA为低电平

if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)!= OK_0)

{

_return = ERROR_1;

}

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

return _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_WaitACK(I2C_HandlerType *I2CxHandlerType)

{

UINT8_T i = 0;

//---读取应答信号

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//---等待应答信号

for (i = 255; i > 0; i--)

{

//---读取SDA的状态

if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit))

{

break;

}

}

if (i==0)

{

I2C_MSW_STOP(I2CxHandlerType);

return ERROR_1;

}

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_SendACK(I2C_HandlerType *I2CxHandlerType,UINT8_T isNACK)

{

if (isNACK)

{

return I2C_MSW_NACK(I2CxHandlerType);

}

else

{

return I2C_MSW_ACK(I2CxHandlerType);

}

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_SendBit(I2C_HandlerType *I2CxHandlerType, UINT8_T bitVal)

{

if (bitVal&0x80)

{

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

}

else

{

I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

}

//---一个时钟脉冲

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_SendByte(I2C_HandlerType *I2CxHandlerType, UINT8_T val)

{

UINT8_T i = 0;

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//---发送1字节的数据

for (i=0;i<8;i++)

{

//---读取1Bit的数据

I2C_MSW_SendBit(I2CxHandlerType,val);

val <<= 1;

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_SendBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal,UINT8_T bitNum)

{

//---计算字节个数

UINT8_T byteCount = (bitNum / 8);

//---计算bit个数

UINT8_T bitCount = (bitNum % 8);

UINT8_T i = 0;

//---发送整数字节的个数

for (i=0;i

{

I2C_MSW_SendByte(I2CxHandlerType, pVal[i]);

}

//---数据左移---数据的发送,首先发送高位

pVal[byteCount] <<= (8 - bitCount);

//---发送指定个数的bit

for (i=0;i

{

I2C_MSW_SendBit(I2CxHandlerType, pVal[byteCount]);

pVal[byteCount] <<= 1;

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_ReadBit(I2C_HandlerType *I2CxHandlerType)

{

UINT8_T _return = OK_0;

//---时钟正脉冲

I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

//---读取数据位

if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit))

{

_return = ERROR_1;

}

//---时钟负脉冲

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

if (I2CxHandlerType->msgDelay != NULL)

{

I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);

}

return  _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_ReadByte(I2C_HandlerType *I2CxHandlerType)

{

UINT8_T i = 0;

UINT8_T _return = 0;

//---准备数据的读取

I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);

//---清时钟线,钳住I2C总线,准备发送或接收数据

I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);

//---发送1字节的数据

for (i = 0; i < 8; i++)

{

_return <<= 1;

_return|=I2C_MSW_ReadBit(I2CxHandlerType);

}

return _return;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_ReadBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum)

{

//---读取字节个数

UINT8_T byteCount = (bitNum / 8);

//---读取bit个数

UINT8_T bitCount = (bitNum % 8);

UINT8_T i = 0;

//---读取整数字节的个数

for (i = 0; i < byteCount; i++)

{

pVal[i]=I2C_MSW_ReadByte(I2CxHandlerType);

}

//---清零处理

pVal[byteCount] = 0x00;

//---读取指定个数的bit

for (i = 0; i < bitCount; i++)

{

pVal[byteCount] <<= 1;

pVal[byteCount]|=I2C_MSW_ReadBit(I2CxHandlerType);

}

return OK_0;

}

 

///////////////////////////////////////////////////////////////////////////////

//////函 数: 

//////功 能: 

//////输入参数: 

//////输出参数: 

//////说 明: 

//////////////////////////////////////////////////////////////////////////////

UINT8_T I2C_MSW_SendCMD(I2C_HandlerType *I2CxHandlerType, UINT8_T cmd, UINT8_T isStart, UINT8_T isStop)

{

UINT8_T _return = OK_0;

if (isStart)

{

//---发送启动启动信号

_return=I2C_MSW_START(I2CxHandlerType);

if (_return)

{

I2C_MSW_STOP(I2CxHandlerType);

return ERROR_1;

}

}

//---发送数据

_return = I2C_MSW_SendByte(I2CxHandlerType, cmd);

//---读取应答

_return = I2C_MSW_ReadACK(I2CxHandlerType);

//---停止条件的满足

if ((isStop)||(_return))

{

I2C_MSW_STOP(I2CxHandlerType);

}

return _return;

}


关键字:STM32  驱动PCF8563  模拟IIC 引用地址:STM32驱动PCF8563,使用模拟IIC

上一篇:STM32的boot引脚设置
下一篇:stm32之spi之NSS管脚信号

推荐阅读最新更新时间:2024-03-16 16:13

STM32中EXTI(外部中断)和NVIC(嵌套向量中断)的关系
NVIC是Cortex-M3核心的一部分,关于它的资料不在《STM32的技术参考手册》中,应查阅ARM公司的《Cortex-M3技术参考手册》 Cortex-M3的向量中断统一由NVIC管理 EXTI是ST公司在其STM32产品上扩展的外中断控制。它负责管理映射到GPIO引脚上的外中断和片内几个集成外设的中断(PVD,RTC alarm,USB wakeup,ethernet wakeup),以及软件中断。其输出最终被映射到NVIC的相应通道。因此,配置EXTI中断的过程必然包含对NVIC的配置,例如下面配置EXTI0的过程,就要首先配置EXTI控制器(使能相应的中断线,选择中断/事件模式,触发边沿极性),然后再配置NVIC控制器(
[单片机]
STM32 M0时钟配置
本文主要讲STM32 M0的时钟配置。 先来看看M0内核的时钟树(stm32f072) 图中可以看出,M0芯片的时钟源有4个,一个高速内部RC时钟源,频率为8M;一个高速外部时钟源,频率为8到32MHz;一个低速外部时钟源,频率一般为32.768kHz;一个低速内部时钟源,频率为40kHz; 一、HSI 芯片上电的时候默认启用内部RC震荡,即8MHz的内部时钟源,如果对时钟要求不是特尔高的时候,使用内部时钟也够了,省下一个外部晶振的钱。 下面首先说说使用内部时钟的配置,官方提供的demo默认的就是使用内部时钟的,我们先从时钟树分析,HSI(8MHz)启动,经过PLLSRC(锁相环时钟源选择寄存器),然后来到PREDIV(预分频
[单片机]
STM32基础学习】八种GPIO模式总结
八种IO模式再现 (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 解释速查 浮空输入_IN_FLOATING 浮空输入,通常用作KEY识别 带上拉输入_IPU IO内部上拉电阻输入,默认电平是高 带下拉输入_IPD IO内部下拉电阻输入,默认电平是低。 模拟输入_AIN
[单片机]
stm32读取电压HAL库版本
/* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint16_t adc_value = 0; double voltage = 0.0; char voltString = {0}; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /*
[单片机]
<font color='red'>stm32</font>读取电压HAL库版本
STM32 Cubemax(三)——时序读写完成称重传感器+HX711的使用
前言 因为在一个项目中使用到了称重传感器,在此记录一下其使用方法还有一些需要注意的地方。 首先介绍一下使用的传感器 HX711——一款专用于电子秤的A/D转换芯片 称重传感器(使用的这一款量程200KG) 一、接线 买到传感器后,可以看到后面尾巴引出了5条线 **其中黄线在单片机处理里面是不需要的,不需要接。 ** 如果大家买的是我上图的那一款HX711,那么可以直接按照上面的英文指示接线。 照着颜色接就完事了,RED接红线,BLK接黑线。 但还有几款HX711上面没有这个颜色提示,那也没有关系。 一般如下 接完了HX711和称重传感器,下一步就是接HX711和单片机 这里 DAT和CLK为自己
[单片机]
<font color='red'>STM32</font> Cubemax(三)——时序读写完成称重传感器+HX711的使用
stm32 ucos LED灯延时闪烁+按键闪烁+串口输出
#include main.h #include stdio.h USART_InitTypeDef USART_InitStructure; #define RCC_KEY1 RCC_APB2Periph_GPIOD #define GPIO__KEY1_Port GPIOD #define KEY1 GPIO_Pin_3 #define RCC_KEY@ RCC_APB2Periph_GPIOA #define GPIO_KEY2_Port GPIOA #define KEY2 GPIO_Pin_8 #define RCC_KEY3 RCC_APB2Periph_GPIOC #de
[单片机]
STM32-systick系统定时器
systick系统定时器 系统定时器存在内核中,是24位的定时器,只能向下递减,嵌套在NVIC中 counter 在时钟的驱动下 在reload的初值开始向下递减计时到0,产生中断置位标志然后又从reload值开始重新递减计数,循环 定时时间计算 t=reload*(1/clk) clk=72M时,t=72*(1/72m)=1us clk=72M时,t=72000*(1/72m)=1ms clk=72M时,t=72000000*(1/72m)=1s 1s=1000MS =1000 000US=1000 000 000NS sysTick属于内核中的外设,他的中断优先级和外设的中断优先级相比,哪个
[单片机]
STM32-systick系统定时器
STM32中的DMA的实际应用
DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧。下面用问答的形式表达我的思路。 DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 有多少个DMA资源? 有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。 数据从什么地方送到什么地方? 外设到SRAM(I2C/UART等获取数据并送入SRAM); SRAM的两个区域之间; 外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比); SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形)
[单片机]
<font color='red'>STM32</font>中的DMA的实际应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved