打印
[KungFu32位 MCU]

KF32A150 硬件IIC 访问PCF563样例

[复制链接]
1101|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ghetto|  楼主 | 2022-7-1 09:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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_ */

使用特权

评论回复
沙发
lvben5d| | 2022-7-1 09:15 | 只看该作者
不能搞出 .h .C 附件吗?   帖子内容主要做一些描述。

使用特权

评论回复
板凳
wengh2016| | 2022-7-8 09:36 | 只看该作者
硬件iic不好移植的。   

使用特权

评论回复
地板
232321122| | 2022-7-8 16:10 | 只看该作者
网上有程序可以参考。   

使用特权

评论回复
5
yujielun| | 2022-7-8 16:43 | 只看该作者
模拟读取不行吗  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

0

粉丝