本帖最后由 ghetto 于 2022-7-1 09:07 编辑
/*
* bsp_iic.c
*
* Created on: 2022-6-28
* Author: pc
*/
#include "bsp_iic.h"
#include "Usart.h"
#include "stdio.h"
I2C_SFRmap* I2C_Choose;
void I2C_GPIO_init(void)
{
GPIO_InitTypeDef I2C_GPIO_Init;
PCLK_CTL0_Peripheral_Clock_Enable(PCLK_CTL0_GPIOBCLKEN,TRUE);
I2C_GPIO_Init.m_Mode = GPIO_MODE_RMP;
I2C_GPIO_Init.m_OpenDrain = GPIO_POD_OD;
I2C_GPIO_Init.m_Pin = GPIO_PIN_MASK_4|GPIO_PIN_MASK_5;
I2C_GPIO_Init.m_PullUp = GPIO_PULLUP;
I2C_GPIO_Init.m_PullDown = GPIO_NOPULL;
I2C_GPIO_Init.m_Speed = GPIO_HIGH_SPEED;
GPIO_Configuration(GPIOB_SFR,&I2C_GPIO_Init);
// GPIOB_SFR->RMP[0] = 0x880000;
GPIO_Pin_RMP_Config(GPIOB_SFR,GPIO_Pin_Num_4,GPIO_RMP_AF8_I2C0);
GPIO_Pin_RMP_Config(GPIOB_SFR,GPIO_Pin_Num_5,GPIO_RMP_AF8_I2C0);
}
#define IIC_100K
void I2C_init_Master(I2C_SFRmap* I2Cx)
{
I2C_Reset(I2Cx);
I2C_InitTypeDef newStruct_I2C;
newStruct_I2C.m_Mode = I2C_MODE_I2C;
newStruct_I2C.m_ClockSource = I2C_CLK_HFCLK;
newStruct_I2C.m_BADR10 = I2C_BUFRADDRESS_7BIT;
newStruct_I2C.m_MasterSlave = I2C_MODE_SMBUSHOST; //
#ifdef IIC_100K
newStruct_I2C.m_BaudRateL = 80;
newStruct_I2C.m_BaudRateH = 80;
#elif defined IIC_400K
newStruct_I2C.m_BaudRateL = 115; //I2C锟斤拷锟斤拷锟绞低碉拷平时锟斤拷锟斤拷锟斤拷 锟斤拷锟街�锟斤拷锟斤拷小锟斤拷3
newStruct_I2C.m_BaudRateH = 115; //I2C锟斤拷锟斤拷锟绞高碉拷平时锟斤拷锟斤拷锟斤拷 锟斤拷锟街�锟斤拷锟斤拷小锟斤拷3
#elif defined IIC_1M
newStruct_I2C.m_BaudRateL = 20; //I2C锟斤拷锟斤拷锟绞低碉拷平时锟斤拷锟斤拷锟斤拷 锟斤拷锟街�锟斤拷锟斤拷小锟斤拷3
newStruct_I2C.m_BaudRateH = 20; //I2C锟斤拷锟斤拷锟绞高碉拷平时锟斤拷锟斤拷锟斤拷 锟斤拷锟街�锟斤拷锟斤拷小锟斤拷3
#endif
newStruct_I2C.m_AckEn = TRUE;
newStruct_I2C.m_AckData = I2C_ACKDATA_ACK;
I2C_Configuration(I2Cx, &newStruct_I2C);
//I2C_Cmd(I2Cx,TRUE);
I2C_Clear_INTERRUPT_Flag(I2Cx);
//I2C_MATCH_ADDRESS_Config(I2Cx,TRUE);
//I2C_ISIE_INT_Enable(I2Cx, TRUE);
//I2C_SCL_Enable(I2Cx,TRUE);
I2C_Cmd(I2Cx,TRUE);
}
void I2C_Byte_Write(uint16_t slave_addr,uint16_t reg_Addr,uint32_t I2C_data, FunctionalState NewState )
{
I2C_Choose=I2C0_SFR;
static uint8_t I2C_SLAVE_ADDRESS10BH=0;
static uint8_t I2C_SLAVE_ADDRESS10BL=0;
I2C_Generate_START(I2C_Choose,TRUE);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
I2C_SendData8(I2C_Choose,slave_addr);
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
while(I2C_Get_Ack_Fail_Flag(I2C_Choose));
I2C_SendData(I2C_Choose,reg_Addr);
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
if(NewState)
{
I2C_SendData(I2C_Choose,I2C_data);
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
}
/*停止位*/
I2C_Generate_STOP(I2C_Choose,TRUE);
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
I2C_Clear_Stop_Flag(I2C_Choose);
}
void I2C_Byte_read(uint16_t slave_addr,uint8_t *I2C_data )
{
I2C_Choose=I2C0_SFR;
static uint8_t I2C_SLAVE_ADDRESS10BH=0;
static uint8_t I2C_SLAVE_ADDRESS10BL=0;
I2C_Generate_START(I2C_Choose,TRUE);
while(!I2C_Get_Start_Flag(I2C_Choose));
I2C_SendData8(I2C_Choose,slave_addr|0x01);
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
while(I2C_Get_Ack_Fail_Flag(I2C_Choose));
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
while((I2C_Choose->SR &I2C_SR_RCBF)== 0);
*I2C_data = I2C_ReceiveData(I2C_Choose);
// I2C_Clear_INTERRUPT_Flag(I2C_Choose);
//while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
I2C_Ack_DATA_Config(I2C_Choose,I2C_ACKDATA_NO_ACK);
/* Stop bit */
I2C_Generate_STOP(I2C_Choose, TRUE);
/* Clear the ISIF bit of the I2C interrupt flag */
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
/* Wait for the stop to complete */
while (!I2C_Get_INTERRUPT_Flag(I2C_Choose)) ;
/* Clear the ISIF bit of the I2C interrupt flag */
I2C_Clear_INTERRUPT_Flag(I2C_Choose);
/* Clear the I2C stop flag PIF bit */
I2C_Clear_Stop_Flag(I2C_Choose);
}
/*
* bsp_iic.h
*
* Created on: 2022-6-28
* Author: pc
*/
#ifndef I2C_Master_Slave_H_
#define I2C_Master_Slave_H_
#include "system_init.h"
#define MODE_Master 1
#define MODE_Slave 0
#define IIC_MODE MODE_Master
#define IIC_10BIT_Address 0
//#define IIC_100K 100000
#define IIC_400K 400000
//#define IIC_1M 1000000
#define I2C_OK 1
#define I2C_FAIL 0
void I2C_GPIO_init(void);
void I2C_init_Slave(I2C_SFRmap* I2Cx,uint16_t I2C_ADDRESS);
void I2C_init_Master(I2C_SFRmap* I2Cx);
void I2C_Byte_Write(uint16_t slave_addr,uint16_t reg_Addr,uint32_t I2C_data, FunctionalState NewState );
void I2C_Byte_read(uint16_t slave_addr,uint8_t *I2C_data);
#endif
/*
* PCF8563.c
*
* Created on: 2022-6-29
* Author: pc
*/
#include "system_init.h"
#include "PCF8563.h"
#include "bsp_iic.h"
#include "stdio.h"
unsigned char PCF8563_WriteByte(uint16_t Write_i2c_Addr,uint32_t I2C_data)
{
I2C_Byte_Write(0xA2,Write_i2c_Addr, I2C_data,TRUE);
}
unsigned char PCF8563_ReadByte(uint16_t Write_i2c_Addr )
{
uint8_t temp = 0;
I2C_Byte_Write(0xA2,Write_i2c_Addr, 0,FALSE);
systick_delay_us(10);
I2C_Byte_read(0xA2,&temp);
return temp;
}
void PCF8563_Timer_Disable(void)
{
PCF8563_WriteByte(PCF8563_Address_Control_Status_2, (PCF8563_ReadByte(PCF8563_Address_Control_Status_2)&0xfe));
PCF8563_WriteByte(TIMER_CTRL_BUF, PCF8563_ReadByte(TIMER_CTRL_BUF)&0x7f);
}
void PCF8563_Alarm_Disable(void)
{
PCF8563_WriteByte(0x01, (PCF8563_ReadByte(0x01)&0xfd));
PCF8563_WriteByte(PCF8563_Alarm_Minutes, PCF8563_ReadByte(PCF8563_Alarm_Minutes)|0x80);
PCF8563_WriteByte(PCF8563_Alarm_Hours, PCF8563_ReadByte(PCF8563_Alarm_Hours)|0x80);
PCF8563_WriteByte(PCF8563_Alarm_Days,0x80);
PCF8563_WriteByte(PCF8563_Alarm_WeekDays,0x80);
}
char PCF8563_Init(void)
{
PCF8563_WriteByte(PCF8563_Address_Control_Status_1,0x00);
PCF8563_WriteByte(PCF8563_Address_Control_Status_2,0x00);
PCF8563_Timer_Disable();
PCF8563_Alarm_Disable();
}
void PCF8563_Set_Time(int hour, int minute, int second)
{
if(hour>=0){
hour = changeIntToHex(hour%60);
PCF8563_WriteByte(HOUR_DATA_BUF, hour);
}
if(minute>=0){
minute = changeIntToHex(minute%60);
PCF8563_WriteByte(MINUTE_DATA_BUF, minute);
}
if(second>=0){
second = changeIntToHex(second%60);
PCF8563_WriteByte(SECOND_DATA_BUF, second);
}
}
void PCF8563_Set_Alarm(int hour, int minute)
{
if(minute >= 0){
minute = changeIntToHex(minute);
PCF8563_WriteByte(MINUTE_AE_BUF, minute);
}
if(hour >= 0){
hour = changeIntToHex(hour);
PCF8563_WriteByte(HOUR_AE_BUF, hour);
}
}
void PCF8563_Set_Days(int year, int months, int days)
{
if(days >= 0 && days <= 31){
days = changeIntToHex(days);
PCF8563_WriteByte(DAY_DATA_BUF, days);
}
if(months>=0 && months <= 12 ){
months = changeIntToHex(months);
PCF8563_WriteByte(MONTH_DATA_BUF, (PCF8563_ReadByte(MONTH_DATA_BUF)&0x80)| months);
}
if(year>=1900 && year<2000){
PCF8563_WriteByte(MONTH_DATA_BUF, PCF8563_ReadByte(MONTH_DATA_BUF) | 0x80);
PCF8563_WriteByte(YEAR_DATA_BUF, year%100);
}else if(year>= 2000 && year < 3000){
PCF8563_WriteByte(MONTH_DATA_BUF, PCF8563_ReadByte(MONTH_DATA_BUF) & 0x7F);
PCF8563_WriteByte(YEAR_DATA_BUF, year%100);
}
}
unsigned char PCF8563_Check(void)
{
uint8_t temp = 0;
unsigned char Time_Count = 0;
if(PCF8563_ReadByte(PCF8563_Address_Timer) & 0x80)
{
PCF8563_WriteByte(PCF8563_Address_Timer,PCF_Timer_Close);
Time_Count = PCF8563_ReadByte(PCF8563_Address_Timer_VAL);
}
PCF8563_WriteByte(PCF8563_Address_Timer_VAL,0xAA);
temp = PCF8563_ReadByte(PCF8563_Address_Timer_VAL);
if(0xAA != temp)
{
temp = 0;
fprintf(USART0_STREAM,"PCF8563 Check Error\r\n");
}else{
temp = 1;
fprintf(USART0_STREAM,"PCF8563 Check Success\r\n");
}
if(Time_Count != 0)
{
PCF8563_WriteByte(PCF8563_Address_Timer_VAL, Time_Count);
PCF8563_WriteByte(PCF8563_Address_Timer, PCF_Timer_Open);
}
return temp;
}
void PCF8563_Set_Timer(int Timer_Frequency ,unsigned char Value)
{
// PCF8563_WriteByte(TIMER_CTRL_BUF, PCF8563_ReadByte(TIMER_CTRL_BUF)&0x7f);
PCF8563_WriteByte(COUNT_VAL_BUF, Value);
if(Timer_Frequency == 4096){
PCF8563_WriteByte(TIMER_CTRL_BUF, ((PCF8563_ReadByte(TIMER_CTRL_BUF))&0xfc)|TIMER_FREQUENCY_4096);
}else if(Timer_Frequency == 64){
PCF8563_WriteByte(TIMER_CTRL_BUF, ((PCF8563_ReadByte(TIMER_CTRL_BUF))&0xfc)|TIMER_FREQUENCY_64);
}else if(Timer_Frequency == 1){
PCF8563_WriteByte(TIMER_CTRL_BUF, ((PCF8563_ReadByte(TIMER_CTRL_BUF))&0xfc)|TIMER_FREQUENCY_1);
}else if(Timer_Frequency == 0){// 1/60
PCF8563_WriteByte(TIMER_CTRL_BUF, ((PCF8563_ReadByte(TIMER_CTRL_BUF))&0xfc)|TIMER_FREQUENCY_1_60);
}else{
printf("Set Timer Error\r\n");
}
}
void PCF8563_CLKOUT_FrequencyHZ(unsigned char Frequency)
{
if(Frequency == 32768){
PCF8563_WriteByte(CLK_FRQ_BUF, (PCF8563_ReadByte(CLK_FRQ_BUF)&0xfC)|0x00);
}else if(Frequency == 1024){
PCF8563_WriteByte(CLK_FRQ_BUF, (PCF8563_ReadByte(CLK_FRQ_BUF)&0xfC)|0x01);
}else if(Frequency == 32){
PCF8563_WriteByte(CLK_FRQ_BUF, (PCF8563_ReadByte(CLK_FRQ_BUF)&0xfC)|0x02);
}else if(Frequency == 1){
PCF8563_WriteByte(CLK_FRQ_BUF, (PCF8563_ReadByte(CLK_FRQ_BUF)&0xfC)|0x03);
}else {
printf("Set CLKOUT requency Selection Error\r\n");
}
}
void PCF8563_Alarm_Enable(void)
{
PCF8563_WriteByte(0x01, (PCF8563_ReadByte(0x01)|0x02));
PCF8563_WriteByte(MINUTE_AE_BUF, PCF8563_ReadByte(MINUTE_AE_BUF)&0x7f);
PCF8563_WriteByte(HOUR_AE_BUF, PCF8563_ReadByte(HOUR_AE_BUF)&0x7f);
PCF8563_WriteByte(DAY_AE_BUF,0x80);//鍏抽棴
PCF8563_WriteByte(WEEK_AE_BUF,0x80);//鍏抽棴
}
void PCF8563_Timer_Enable(void)
{
PCF8563_WriteByte(0x01, (PCF8563_ReadByte(0x01)|0x01));
PCF8563_WriteByte(TIMER_CTRL_BUF, PCF8563_ReadByte(TIMER_CTRL_BUF)|0x80);
}
void PCF8563_CLKOUT_Enable(void)
{
PCF8563_WriteByte(CLK_FRQ_BUF, PCF8563_ReadByte(CLK_FRQ_BUF)|0x80);
}
void PCF8563_Get_Time(unsigned char *buf)
{
buf[0] = PCF8563_ReadByte(SECOND_DATA_BUF) & 0x7f; //get second data
buf[1] = PCF8563_ReadByte(MINUTE_DATA_BUF) & 0x7f; //get minute data
buf[2] = PCF8563_ReadByte(HOUR_DATA_BUF) & 0x3f; //get hour data
buf[0] = changeHexToInt(buf[0]);
buf[1] = changeHexToInt(buf[1]);
buf[2] = changeHexToInt(buf[2]);
}
unsigned char PCF8563_Get_Flag(void)
{
unsigned char temp=0;
if(PCF8563_ReadByte(0x01)&0x08){
temp = temp|0x01;
}
if(PCF8563_ReadByte(0x01)&0x04){
temp = temp|0x02;
}
return temp;
}
void PCF8563_Get_Days(unsigned char *buf)
{
buf[0] = PCF8563_ReadByte(DAY_DATA_BUF)&0x3f;
buf[1] = PCF8563_ReadByte(MONTH_DATA_BUF) & 0x1f;
buf[2] = PCF8563_ReadByte(YEAR_DATA_BUF)&0xff;
buf[0] = changeHexToInt(buf[0]);
buf[1] = changeHexToInt(buf[1]);
if(PCF8563_ReadByte(MONTH_DATA_BUF) & 0x80){
buf[3] = 19;
}else{
buf[3] = 20;
}
}
void PCF8563_Cleare_AF_Flag(void)
{
PCF8563_WriteByte(0x01, PCF8563_ReadByte(0x01)&0xf7);
}
void PCF8563_Cleare_TF_Flag(void)
{
PCF8563_WriteByte(0x01, PCF8563_ReadByte(0x01)&0xfB);
}
/*
* PCF8563.h
*
* Created on: 2022-6-29
* Author: pc
*/
#ifndef PCF8563_H_
#define PCF8563_H_
#define CLK_FRQ_BUF 0x0D
#define TIMER_CTRL_BUF 0x0E
#define COUNT_VAL_BUF 0x0F
#define PCF_Timer_Open (unsigned char)(1<<7) //定时器有效
#define PCF_Timer_Close (unsigned char)(~(1<<7)) //定时器无效
#define PCF_Timer_F4096 (unsigned char)0x00 //定时器时钟频率为4096Hz
#define PCF_Timer_F64 (unsigned char)0x01 //定时器时钟频率为64Hz
#define PCF_Timer_F1 (unsigned char)0x02 //定时器时钟频率为1Hz
#define PCF_Timer_F160 (unsigned char)0x03 //定时器时钟频率为1/60Hz
#define PCF_Time_INT_Open (unsigned char)(1<<0) //定时器中断有效
#define PCF_Time_INT_Close (unsigned char)(~(1<<0)) //定时器中断无效
#define PCF_Control_Status_NormalMode (unsigned char)(~(1<<7)) //普通模式
#define PCF_Control_Status_EXT_CLKMode (unsigned char)(1<<7) //EXT_CLK测试模式
#define PCF_Control_ChipRuns (unsigned char)(~(1<<5)) //芯片运行
#define PCF_Control_ChipStop (unsigned char)(1<<5) //芯片停止运行,所有芯片分频器异步置逻辑0
#define PCF_Control_TestcClose (unsigned char)(~(1<<3)) //电源复位功能失效(普通模式时置逻辑0)
#define PCF_Control_TestcOpen (unsigned char)(1<<3) //电源复位功能有效
#define PCF8563_Address_Control_Status_1 (unsigned char)0x00 //控制/状态寄存器1
#define PCF8563_Address_Control_Status_2 (unsigned char)0x01 //控制/状态寄存器2
#define PCF8563_Address_CLKOUT (unsigned char)0x0d //CLKOUT频率寄存器
#define PCF8563_Address_Timer (unsigned char)0x0e //定时器控制寄存器
#define PCF8563_Address_Timer_VAL (unsigned char)0x0f //定时器倒计数寄存器
#define PCF8563_Address_Years (unsigned char)0x08 //年
#define PCF8563_Address_Months (unsigned char)0x07 //月
#define PCF8563_Address_Days (unsigned char)0x05 //日
#define PCF8563_Address_WeekDays (unsigned char)0x06 //星期
#define PCF8563_Address_Hours (unsigned char)0x04 //小时
#define PCF8563_Address_Minutes (unsigned char)0x03 //分钟
#define PCF8563_Address_Seconds (unsigned char)0x02 //秒
#define SECOND_DATA_BUF 0x02
#define MINUTE_DATA_BUF 0x03
#define HOUR_DATA_BUF 0x04
#define DAY_DATA_BUF 0x05
#define WEEK_DATA_BUF 0x06
#define MONTH_DATA_BUF 0x07
#define YEAR_DATA_BUF 0x08
#define MINUTE_AE_BUF 0x09
#define HOUR_AE_BUF 0x0A
#define DAY_AE_BUF 0x0B
#define WEEK_AE_BUF 0x0C
#define CLK_FRQ_BUF 0x0D
#define TIMER_CTRL_BUF 0x0E
#define COUNT_VAL_BUF 0x0F
#define PCF8563_Alarm_Minutes (unsigned char)0x09 //分钟报警
#define PCF8563_Alarm_Hours (unsigned char)0x0a //小时报警
#define PCF8563_Alarm_Days (unsigned char)0x0b //日报警
#define PCF8563_Alarm_WeekDays (unsigned char)0x0c //星期报警
#define TIMER_FREQUENCY_4096 0 // 4096HZ
#define TIMER_FREQUENCY_64 1 // 64HZ
#define TIMER_FREQUENCY_1 2 // 1HZ
#define TIMER_FREQUENCY_1_60 3 // 1/60Hz
#define changeIntToHex(dec) ((((dec)/10) <<4) + ((dec)%10) )
#define converseIntToHex(dec) ((((dec)>>4) *10) + ((dec)%16) )
#define changeHexToInt(hex) ((((hex)>>4) *10 ) + ((hex)%16) )
#define converseHexToInt(hex) ((((hex)/10) <<4 ) + ((hex)%10) )
char PCF8563_Init(void);
unsigned char PCF8563_Check(void);
void PCF8563_Set_Time(int hour, int minute, int second);
void PCF8563_Get_Time(unsigned char *buf);
void PCF8563_Set_Days(int year, int months, int days);
void PCF8563_Get_Days(unsigned char *buf);
void PCF8563_Set_WeekData(int WeekData);
void PCF8563_Set_Alarm(int hour, int minute);
void PCF8563_Set_Timer(int Timer_frequency ,unsigned char value);
void PCF8563_Alarm_Enable(void);
void PCF8563_Alarm_Disable(void);
void PCF8563_Timer_Enable(void);
void PCF8563_Timer_Disable(void);
void PCF8563_Cleare_AF_Flag(void);//Alarm
void PCF8563_Cleare_TF_Flag(void);//Timer
unsigned char PCF8563_Get_Flag(void);
void PCF8563_CLKOUT_FrequencyHZ(unsigned char Frequency);
void PCF8563_CLKOUT_Disable(void);
void PCF8563_CLKOUT_Enable(void);
#endif /* PCF8563_H_ */
|
|