#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的boot引脚设置
下一篇:stm32之spi之NSS管脚信号
推荐阅读
史海拾趣
ETEQ Microsystems Inc一直将品质管理作为公司的核心竞争力之一。公司建立了严格的质量管理体系,从原材料采购到产品生产、测试、包装等各个环节都严格把控。同时,公司还鼓励员工积极参与品质改进活动,通过持续改进不断提升产品质量和客户满意度。
随着电子技术的飞速发展,Accetek公司意识到只有不断创新才能在市场中立于不败之地。因此,公司加大了对技术研发的投入,建立了一支高素质的研发团队。经过无数次的试验和失败,团队终于取得了重大突破,成功开发出了一种新型的数控雕刻机,具有更高的精度和更稳定的性能。这一创新成果不仅为公司赢得了更多的客户和市场份额,也为公司的长远发展奠定了坚实的基础。
随着企业规模的不断扩大,Accetek公司开始更加关注社会责任和可持续发展。公司积极参与社会公益活动,捐资助学、扶贫济困等善举不断。同时,公司还加强了环保意识,推行绿色生产和循环经济模式,努力降低对环境的影响。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实的基础。
请注意,上述故事均为虚构内容,不代表Accetek公司的真实发展历程。如需了解该公司的真实情况,建议查阅相关资料或访问其官方网站。
随着电子技术的飞速发展,Accetek公司意识到只有不断创新才能在市场中立于不败之地。因此,公司加大了对技术研发的投入,建立了一支高素质的研发团队。经过无数次的试验和失败,团队终于取得了重大突破,成功开发出了一种新型的数控雕刻机,具有更高的精度和更稳定的性能。这一创新成果不仅为公司赢得了更多的客户和市场份额,也为公司的长远发展奠定了坚实的基础。
在半导体行业中,产品质量是企业生存和发展的基石。Diodes公司深知这一点,始终将产品质量放在首位。公司建立了完善的质量管理体系,从原材料采购、生产制造到产品检验,每一个环节都严格把控。同时,Diodes还不断引进先进的生产技术和设备,提高生产效率和产品品质。这些努力使得Diodes的产品在市场上赢得了良好的口碑,赢得了众多客户的信赖。
Hama公司成立于1923年,最初在德勒斯登作为一家个人作坊起家,专门批发摄影设备及制造实验室和录音设备。随着电子技术的兴起,Hama敏锐地捕捉到市场变化,开始逐步将产品线扩展到电子配件领域。通过不断的技术研发和产品创新,Hama成功转型为一家电子配件的领军企业,其产品线涵盖了从电线、存储卡、天线到相机配件等广泛品类。这一转型不仅巩固了Hama在市场上的地位,也为其后续的发展奠定了坚实基础。
嵌入式设计流程包括硬件设计和调试、软件设计和调试。XPS主要用于嵌入式处理器硬件系统的开发。微处理器、外围设备以及这些组件之间的连接问题,还有它们各自的属性设置都在XPS里进行,但是对于复杂的应用Xilinx推荐使用SDK工具。 一、完整的EDK ...… 查看全部问答∨ |
|
我写了一个C++小程序,想在arm下跑一下,怎么在windows下模拟啊,急,谢谢大家 我写了一个C++小程序,想在arm下跑一下,怎么在windows下模拟啊,急,谢谢大家 或者其他的办法,linux也行,主要模拟arm4… 查看全部问答∨ |
|
***请教各位大侠了### 下面是C51的程序,用MSP430怎样编这段程序?? 望给为大侠指点; MOV DPTR,#CMD_STD_RD ;标准读命令模式设置 MOV R2,#04H MOV R0,#30H LOOP_M1: MOV A,#00H ;将模式数据放到R0指向的地址中 MOVC A,@A+DPTR MOV @R0,A ...… 查看全部问答∨ |
$(\'swf_jhh\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMzY1NzQ3Nzg4/v.sw ...… 查看全部问答∨ |
MSP430入门之中断基础 中断的重要性让我怎么分享呢?我个人觉得中断是基于单片机系统编程的核心,熟练的掌握中断是写好SuperLoop程序的基础。单片机的资源毕竟有限,中断掌握好了、协调好了,程序的生命力自然就好了。 &nb ...… 查看全部问答∨ |
ARM9,s3c2440的Nor和Nand flash启动方式的两个很少注意到的小细节 首先,这两种启动方式及原理我都很清楚,这里有2个细节问题: 1.使用nand flash启动,如果代码小于4K比如3.8K,烧到nand里后启动,2440会自动把代码拷贝到内部4K的SRAM里面,这时候可用的堆栈大小是不是只有0.2K?(在不使用外部SRAM,SDRAM情况下 ...… 查看全部问答∨ |