[KungFu32位 MCU]

KF32F350_demo-I2C读写外部eeprom

[复制链接]
475|11
手机看帖
扫描二维码
随时随地手机跟帖
静听风易|  楼主 | 2020-10-25 21:45 | 显示全部楼层 |阅读模式
main.c
/****************************************************************************************
*
* 文件名: main.c
* 项目名: EEPROM
* 版 本:  V2.1
* 日 期:  2019年11月16日
* 作 者:  ChipON_AE/FAE_Group
*
****************************************************************************************/
#include "system_init.h"
#include "EEPROM_24LC256.h"
#include "Usart.h"



/**
  * 描述  GPIOx 输出初始化配置。
  * 输入 : GPIOx: 指向GPIO内存结构的指针,取值为GPIOA_SFR~GPIOH_SFR。
  *       GpioPin: 端口引脚掩码,取值为GPIO_PIN_MASK_0~GPIO_PIN_MASK_15中的一个或多个组合。
  * 返回  无。
  */
void GPIOInit_Output_Config(GPIO_SFRmap* GPIOx,uint16_t GpioPin)
{
        /*初始化复位GPIOx外设,使能GPIOx外设时钟*/
                GPIO_Reset(GPIOx);

        /* 配置 Pxy作为输出模式参数 */
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_Struct_Init(&GPIO_InitStructure);
        GPIO_InitStructure.m_Pin = GpioPin;
        GPIO_InitStructure.m_Speed = GPIO_LOW_SPEED;          //初始化 GPIO输出速度
        GPIO_InitStructure.m_Mode = GPIO_MODE_OUT;            //初始化 GPIO方向为输出
        GPIO_InitStructure.m_PullUp = GPIO_NOPULL;            //初始化 GPIO是否上拉
        GPIO_InitStructure.m_PullDown = GPIO_NOPULL;          //初始化 GPIO是否下拉
        GPIO_Configuration(GPIOx,&GPIO_InitStructure);

        GPIO_Set_Output_Data_Bits(GPIOx,GpioPin,Bit_SET);           //先设置为高电平

}

/**
  * 描述  I2Cx引脚上拉初始化及重映射配置。
  * 输入  无
  *
  * 返回  无。
  */
void I2C_GPIO_init(void)
{
        /*I2Cx引脚上拉初始化及重映射配置*/
        GPIO_InitTypeDef I2C_GPIO_Init;

        I2C_GPIO_Init.m_Mode = GPIO_MODE_RMP;                   //GPIO设为重映射
        I2C_GPIO_Init.m_OpenDrain = GPIO_POD_OD;                //GPIO设为开漏输出
        I2C_GPIO_Init.m_Pin = GPIO_PIN_MASK_0|GPIO_PIN_MASK_1;  //选用的GPIO端口
        I2C_GPIO_Init.m_PullUp = GPIO_PULLUP;                   //GPIO设为上拉
        I2C_GPIO_Init.m_PullDown = GPIO_NOPULL;                 //GPIO不下拉
        I2C_GPIO_Init.m_Speed = GPIO_HIGH_SPEED;                //GPIO速度设为高速
        GPIO_Pin_RMP_Config(GPIOA_SFR,GPIO_Pin_Num_0,GPIO_RMP_AF8_I2C0);  //设PA0为I2C0的SDA
        GPIO_Pin_RMP_Config(GPIOA_SFR,GPIO_Pin_Num_1,GPIO_RMP_AF8_I2C0);  //设PA1为I2C0的SCK

        GPIO_Configuration(GPIOA_SFR,&I2C_GPIO_Init);

}
/**
  * 描述  初始化I2Cx参数配置波特率设置。
  * 输入  I2Cx:指向I2C内存结构的指针,取值为I2C0_SFR~I2C3_SFR。
  *
  * 返回  无。
  */
void I2C_init(I2C_SFRmap* I2Cx)
{
        /*I2Cx*/
        I2C_Reset(I2Cx);
        I2C_InitTypeDef newStruct_I2C;
        newStruct_I2C.m_Mode = I2C_MODE_I2C;              //I2C模式
        newStruct_I2C.m_ClockSource = I2C_CLK_SCLK;      //采用主频120M,一个时钟周期为0.00833us
        newStruct_I2C.m_BADR10 = I2C_BUFRADDRESS_7BIT;    //7位的地址模式
        newStruct_I2C.m_MasterSlave = I2C_MODE_SMBUSHOST; //SMBus类型选择:HOST
        newStruct_I2C.m_BaudRateL = 150;                   //波特率低电平时间:150X0.00833us=1.25us
        newStruct_I2C.m_BaudRateH = 150;                   //波特率高电平时间:150X0.00833us=1.25us 得到400KHZ
        newStruct_I2C.m_AckEn = TRUE;                     //ACK应答使能
        newStruct_I2C.m_AckData = I2C_ACKDATA_ACK;        //应答ACK
        I2C_Configuration(I2Cx, &newStruct_I2C);

        /*使能I2C模块*/
        I2C_Cmd(I2Cx,TRUE);
        I2C_Clear_INTERRUPT_Flag(I2Cx);  //清I2C中断标志位

}



//主函数
void main()
{
        /*用户可参考该例程在KF32F350_demo板上实现I2C主模式读写外部的EERPOM功能。
        * 例程中使用I2C0 PA0 PA1用于主机I2C通信。EEPROM 24LC256最高支持400KHZ。
        * 功能简述:        KF32F350通过I2C总线以CPU读写的形式在EERPOM的0x0000地址写入64个字节数据,然后再从0x0000地址再读出64个字节数据进行对比,
        *           数据匹配后PB8翻转LED0闪烁,否则PB9翻转LED1闪烁
        * 硬件说明:    设PA0为I2C0的SDA  设PA1为I2C0的SCK
        *            PB8对应控制LED0灯\PB9对应控制LED1灯\PB10对应控制LED2灯
        *           如果需要用串口接USART0_RX PB6         USART0_TX0        PB7  并在Usart.h打开 串口宏定义Usart_Print  1
        *EERPOM:型号为24LC256
        *
    */

        //系统时钟120M,外设高频时钟16M
        SystemInit();//系统时钟初始化
        /*PB9 PB9 PB10初始化设为输出高*/
        GPIOInit_Output_Config(GPIOB_SFR,GPIO_PIN_MASK_8|GPIO_PIN_MASK_9|GPIO_PIN_MASK_10);

        //I2C GPIO选用及功能重映射
        I2C_GPIO_init();      //设PA0为I2C0的SDA  设PA1为I2C0的SCK
        //初始化I2C0模块参数
        I2C_init(I2C0_SFR);   //波特率设为400KHZ

#if Usart_Print
        //配置USART0引脚重映射
        GPIO_USART();////USART2_RX                PB15         USART2_TX0        PB14
        USART_Async_config(USART2_SFR);//全双工异步8bit 9600波特率
#endif

        while(1)
    {
#if Usart_Print
                //串口打印读到的数组数据
                USART_Send(USART2_SFR,i2c_buffer_read,sizeof(i2c_buffer_read));
#endif

                if(I2C_OK == AT24LC256_TEST())//检测写入EERPOM与读出数据是否匹配
                {
                        GPIO_Toggle_Output_Data_Config(GPIOB_SFR,GPIO_PIN_MASK_8);  //PB8翻转
                        Delay(0XFFFFF);

                }else
                {
                        GPIO_Toggle_Output_Data_Config(GPIOB_SFR,GPIO_PIN_MASK_9);  //PB9翻转
                }

    }

}



/**
  * 描述   报告校验发生错误的文件和行
  * 输入   file: 指向文件名称的指针
  *      line: 校验错误的行
  * 返回  无。
  */
void check_failed(uint8_t* file, uint32_t line)
{
          /* 用户可以添加自己的代码实现报告文件名和行号,
                     例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

          while(1)
          {
                  ;
          }
}



使用特权

评论回复
静听风易|  楼主 | 2020-10-25 21:46 | 显示全部楼层
EEPROM_24LC256.c
/**
  ********************************************************************
  * 文件名  EEPROM_24LC256.c
  * 作  者   ChipON_AE/FAE_Group
  * 版  本  V2.1
  * 日  期  2019-11-16
  * 描  述  该文件提供了EERPOM读写功能函数等相关函数。
  *
  *********************************************************************
*/
#include "system_init.h"
#include "EEPROM_24LC256.h"
#include "Usart.h"



I2C_SFRmap* I2C_Choose;



//延时函数 局部变量用volatile声明,否则可能会被优化
void Delay(volatile uint32_t cnt)
{
        while(cnt--);
}

/**
  * 描述  eeprom 写入单字节数据。
  * 输入  write_address:eeprom 16位寄存器地址
  *           p_buffer: 写入数据,取值为10位数据。
  * 返回  无。
  */
void eeprom_byte_write(uint16_t write_address,uint32_t p_buffer)
{

        I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR
        static uint8_t EEPROM_AddH=0;
        static uint8_t EEPROM_AddL=0;

        EEPROM_AddL=write_address& 0xff;                //低8位寄存器地址
        EEPROM_AddH=(write_address>>8)& 0xff;           //高8位寄存器地址

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清I2C中断标志位ISIF位
        I2C_Cmd(I2C_Choose,TRUE);                       //使能I2C模块

        /*起始位*/
        I2C_Generate_START(I2C_Choose,TRUE);            //使能起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待起始位稳定


        /*发送I2C从机地址*/
        I2C_SendData(I2C_Choose,EEPROM_I2C_ADDRESS);   //发送从机I2C地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待发送完成


        /*发送高位地址*/
        I2C_SendData(I2C_Choose,EEPROM_AddH);          //发送从机高位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);          //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));    //等待发送完成

        /*发送低位地址*/
        I2C_SendData(I2C_Choose,EEPROM_AddL);          //发送从机低位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);          //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));    //等待发送完成


        /*发送数据*/
        I2C_SendData(I2C_Choose, p_buffer);            //发送8位数据
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);          //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));    //等待发送完成


        /*停止位*/
        I2C_Generate_STOP(I2C_Choose,TRUE);         //使能停止信号

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        I2C_Clear_Stop_Flag(I2C_Choose);            //清I2C停止标志位PIF位
        I2C_Cmd(I2C_Choose,FALSE);                  //关闭I2C模块

}

/**
  * 描述  eeprom 写入多字节数据。
  * 输入  write_address:eeprom 16位寄存器地址
  *           p_buffer: 写入数据指针
  *      number_of_byte:写入数据长度
  * 返回  无。
  */
void eeprom_buffer_write(uint16_t Write_address,uint8_t *p_buffer,uint16_t number_of_byte)
{
        I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR

        static  uint8_t EEPROM_AddH=0;
        static  uint8_t EEPROM_AddL=0;

        EEPROM_AddL=Write_address& 0xff;                     //低8位寄存器地址
        EEPROM_AddH=(Write_address>>8)& 0xff;                //高8位寄存器地址

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        I2C_Cmd(I2C_Choose,TRUE);                            //使能I2C模块
        /*起始位*/
        I2C_Generate_START(I2C_Choose,TRUE);                 //使能起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));



        /*发送I2C从机地址*/
        I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS);        //发送从机I2C地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                    //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));              //等待发送完成
        while(I2C_Get_Ack_Fail_Flag(I2C_Choose));    //判断是否有ACK应答,如没有则停止,如果有则继续发


        /*发送高位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddH);            //发送从机高位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));          //等待发送完成

        /*发送低位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddL);            //发送从机低位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));          //等待发送完成

    /* 循环写数据操作 */
    while(number_of_byte--){
            I2C_SendData8(I2C_Choose, *p_buffer);        //发送8位数据
            I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清I2C中断标志位ISIF位
        /* 指向下一个所要写的字节 */
        p_buffer++;
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待发送完成

    }

        /*停止位*/
        I2C_Generate_STOP(I2C_Choose,TRUE);         //使能停止信号

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        I2C_Clear_Stop_Flag(I2C_Choose);            //清I2C停止标志位PIF位
        I2C_Cmd(I2C_Choose,FALSE);                  //关闭I2C模组

}


/**
  * 描述  eeprom 读出单字节数据。
  * 输入  write_address:eeprom 16位寄存器地址
  *           p_buffer: 读出数据,取值为8位数据。
  * 返回  无。
  */
void eeprom_byte_read(uint16_t Write_address,uint8_t p_buffer)
{
        I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR

        static uint8_t EEPROM_AddH=0;
        static uint8_t EEPROM_AddL=0;


        EEPROM_AddL=Write_address& 0xff;//低8位寄存器地址
        EEPROM_AddH=(Write_address>>8)& 0xff;  //高8位寄存器地址

        I2C_Cmd(I2C_Choose,TRUE);

        /*起始位*/
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清I2C中断标志位ISIF位
        I2C_Generate_START(I2C_Choose,TRUE);            //使能起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待起始位稳定


        /*发送I2C从机地址*/
        I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS);        //发送从机I2C地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                    //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));              //等待发送完成
        while(I2C_Get_Ack_Fail_Flag(I2C_Choose));    //判断是否有ACK应答,如没有则停止,如果有则继续发


        /*发送要读寄存器高位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddH);                 //发送从机高位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                     //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));                //等待发送完成


        /*发送要读寄存器低位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddL);                 //发送从机低位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                     //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));               //等待发送完成


        I2C_Cmd(I2C_Choose,FALSE);                              //关I2C模块

        I2C_Clear_Start_Flag(I2C_Choose);                       //清I2C起始标志位SIF位
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                  //清I2C中断标志位ISIF位
        I2C_Cmd(I2C_Choose,TRUE);                               //使能I2C模块
        /*起始位*/
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                 //清I2C中断标志位ISIF
        I2C_Generate_START(I2C_Choose,TRUE);                  //使能起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));           //等待起始信号稳定


        /*发送读指令*/
        I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS|0x01);//发送从机地址及读操作
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清标志位ISIF位

        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待发送完成ISIF会置1
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //然后完成清标志位ISIF位


        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));  //等待读取Buff完成ISIF会置1
        if(I2C_Get_Receive_Buff_Flag(I2C_Choose))     //判断Buff是否为满
        {
                I2C_Ack_DATA_Config(I2C_Choose,I2C_ACKDATA_ACK);//回复ACK
                p_buffer = I2C_ReceiveData(I2C_Choose);
                 I2C_Clear_INTERRUPT_Flag(I2C_Choose);        //然后读完后清标志位ISIF位

        }


    while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
        /*停止位*/
        I2C_Generate_STOP(I2C_Choose,TRUE);         //使能停止信号

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        I2C_Clear_Stop_Flag(I2C_Choose);            //清I2C停止标志位PIF位
        I2C_Cmd(I2C_Choose,FALSE);                  //关闭I2C模组


}



/**
  * 描述  eeprom 读出多字节数据。
  * 输入  write_address:eeprom 16位寄存器地址
  *           p_buffer: 读出数据指针
  *      number_of_byte:读出数据长度
  * 返回  无。
  */
void eeprom_buffer_read(uint16_t Write_address,uint8_t *p_buffer,uint16_t number_of_byte)
{
        I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR

        static uint8_t EEPROM_AddH=0;
        static uint8_t EEPROM_AddL=0;

        EEPROM_AddL=Write_address& 0xff;       //低8位寄存器地址
        EEPROM_AddH=(Write_address>>8)& 0xff;  //高8位寄存器地址

        I2C_Cmd(I2C_Choose,TRUE);                            //使能I2C3模块

        /*起始位*/
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        I2C_Generate_START(I2C_Choose,TRUE);                 //使能起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));          //等待起始位稳定



        /*发送I2C从机地址*/
        I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS);     //发送从机I2C地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                 //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));           //等待发送完成
        while(I2C_Get_Ack_Fail_Flag(I2C_Choose));    //判断是否有ACK应答,如没有则停止,如果有则继续发


        /*发送要读寄存器高位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddH);            //发送从机高位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));           //等待发送完成


        /*发送要读寄存器低位地址*/
        I2C_SendData8(I2C_Choose,EEPROM_AddL);            //发送从机低位寄存器地址
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);                //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));          //等待发送完成


        I2C_Cmd(I2C_Choose,FALSE);                       //关I2C模块

        I2C_Clear_Start_Flag(I2C_Choose);               //清I2C起始标志位SIF位
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清标志位ISIF位
        I2C_Cmd(I2C_Choose,TRUE);                       //打开I2C模块
        /*起始位*/
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清中断标志位ISIF位
        I2C_Generate_START(I2C_Choose,TRUE);             //起始信号
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待起始位稳定


        /*发送读指令*/
        I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS|0x01);//发送从机地址及读操作
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //清标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));     //等待发送完成ISIF会置1
        while(I2C_Get_Ack_Fail_Flag(I2C_Choose));    //判断是否有ACK应答,如没有则停止,如果有则继续发
        I2C_Clear_INTERRUPT_Flag(I2C_Choose);           //然后完成清标志位ISIF位


        while(number_of_byte)
        {
                while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));  //等待读取Buff完成ISIF会置1
        if(I2C_Get_Receive_Buff_Flag(I2C_Choose))     //判断Buff是否为满
                {
                        *p_buffer = I2C_ReceiveData(I2C_Choose);
                         I2C_Ack_DATA_Config(I2C_Choose,I2C_ACKDATA_ACK);//回复ACK
                         I2C_Clear_INTERRUPT_Flag(I2C_Choose);        //然后读完后清标志位ISIF位
                         p_buffer++;      /* 指向下一个被读取的字节将被保存的位置 */

                  /* 递减读取字节计数器 */
                   number_of_byte--;
                }


        }


        /*停止位*/
        I2C_Generate_STOP(I2C_Choose,TRUE);         //使能停止信号

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成

        I2C_Clear_INTERRUPT_Flag(I2C_Choose);       //清I2C中断标志位ISIF位
        I2C_Clear_Stop_Flag(I2C_Choose);            //清I2C停止标志位PIF位
        I2C_Cmd(I2C_Choose,FALSE);                  //关闭I2C模组


}




/**
  * 描述  先写64个字节数据并读出64个字节数据进行比较。
  * 输入  无
  * 返回 1 :数据对比匹配。
  *     0 :数据对比不匹配。
  */
uint8_t AT24LC256_TEST(void)
{
        static volatile        uint16_t i;
        static volatile uint16_t j;
        i=0;
        j=0;
    /* 初始化i2c写缓冲区 */
    for(i = 0;i < BUFFER_SIZE;i++)
    {
        i2c_buffer_write[i]=i;
    }

    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    /* EEPROM 数据写入 */

   eeprom_buffer_write(EEP_FIRST_PAGE,i2c_buffer_write,sizeof(i2c_buffer_write));

    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    /* EEPROM 数据读取 */
    eeprom_buffer_read(EEP_FIRST_PAGE,i2c_buffer_read,sizeof(i2c_buffer_read));

    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);
    Delay(0XFFFF);

    for(j = 0;j < BUFFER_SIZE;j++)
    {
        if(i2c_buffer_read[j] != i2c_buffer_write[j])
        {
           return I2C_FAIL;
        }
    }
    return I2C_OK;
}







使用特权

评论回复
静听风易|  楼主 | 2020-10-25 21:46 | 显示全部楼层
system_init.c
/**
  ******************************************************************************
  * 文件名  system_init.c
  * 作  者  ChipON_AE/FAE_Group
  * 版  本  V2.1
  * 日  期  2019-11-16
  * 描  述  该文件提供了外设时钟与系统时钟初始化
  *
  ******************************************************************************
  */
#include "system_init.h"
/**
  * 描述  时钟默认配置。
  * 输入  无。
  * 返回  无。
*/
static void SetSysClock(void)
{
        /* 使能内部高频时钟*/
        OSC_INTHF_Software_Enable(TRUE);
        while(OSC_Get_INTHF_INT_Flag() != SET);
        /* PLL时钟源选择 */
#ifdef SYSCLK_FREQ_HSI
        OSC_PLL_Input_Source_Config(PLL_INPUT_INTHF);
#else
        OSC_PLL_Input_Source_Config(PLL_INPUT_EXTHF);
#endif
        /* PLL倍频时钟选择 */
#ifdef SYSCLK_FREQ_48MHz
        OSC_PLL_Multiple_Value_Select(48,2,8);
#elif defined SYSCLK_FREQ_72MHz
        OSC_PLL_Multiple_Value_Select(36,2,4);
#elif defined SYSCLK_FREQ_96MHz
        OSC_PLL_Multiple_Value_Select(12,1,2);
#elif defined SYSCLK_FREQ_120MHz
        OSC_PLL_Multiple_Value_Select(30,2,2);
#endif
        OSC_PLL_Start_Delay_Config(PLL_START_DELAY_1024);
        OSC_PLL_Software_Enable(TRUE);
        OSC_PLL_RST();
        while(OSC_Get_PLL_INT_Flag() != SET);
        /* 主时钟配置 */
        OSC_SCK_Division_Config(SCLK_DIVISION_1);
        OSC_SCK_Source_Config(SCLK_SOURCE_PLL);
        /* 外设高速时钟 */
        OSC_HFCK_Division_Config(HFCK_DIVISION_1);
        OSC_HFCK_Source_Config(HFCK_SOURCE_INTHF);
        OSC_HFCK_Enable(TRUE);

        OSC_LFCK_Division_Config(LFCK_DIVISION_1);                //低频工作分频选择
        OSC_LFCK_Source_Config (LFCK_INPUT_INTLF);                //选择INTLF作为LFCLK时钟
        OSC_LFCK_Enable (TRUE);                                                        //LFCLK时钟信号允许
        OSC_INTLF_Software_Enable(TRUE);
        OSC_INTHF_Software_Enable(TRUE);                                //内部高频振荡器软件使能
}

/**
  * 描述  系统初始化。
  * 输入  无。
  * 返回  无。
*/
void SystemInit(void)
{
        /* 时钟配置 */
        SetSysClock();
}

使用特权

评论回复
静听风易|  楼主 | 2020-10-25 21:47 | 显示全部楼层
Usart.c
/**
  ********************************************************************
  * 文件名  Usart.c
  * 作  者   ChipON_AE/FAE_Group
  * 版  本  V2.1
  * 日  期  2019-11-16
  * 描  述  该文件提供了Usart GPIO初始化、Usart配置参数、Usart发送函数等相关函数。
  *
  *********************************************************************
*/
#include "system_init.h"




/**
  * 描述   串口GPIO重映射
  * 输入   无
  * 返回   无
  */
void GPIO_USART(void)
{
         /* 端口重映射AF5 */
        //USART2_RX                PB15
        //USART2_TX0        PB14
        GPIO_Write_Mode_Bits(GPIOB_SFR ,GPIO_PIN_MASK_14, GPIO_MODE_RMP);           //重映射IO口功能模式
        GPIO_Write_Mode_Bits(GPIOB_SFR ,GPIO_PIN_MASK_15, GPIO_MODE_RMP);           //重映射IO口功能模式
        GPIO_Pin_RMP_Config (GPIOB_SFR, GPIO_Pin_Num_14, GPIO_RMP_AF5_USART2);           //重映射为USART2
        GPIO_Pin_RMP_Config (GPIOB_SFR,GPIO_Pin_Num_15, GPIO_RMP_AF5_USART2);       //重映射为USART2
        GPIO_Pin_Lock_Config (GPIOB_SFR ,GPIO_PIN_MASK_14, TRUE);                   //配置锁存
        GPIO_Pin_Lock_Config (GPIOB_SFR ,GPIO_PIN_MASK_15, TRUE);                   //配置锁存

}

/**
  * 描述   串口发送
  * 输入   USARTx:   指向USART内存结构的指针,取值为USART0_SFR~USART8_SFR
  *      Databuf:   指向发送数据的指针
  *      length:      发送的长度
  * 返回   无
  */
void USART_Send(USART_SFRmap* USARTx, uint8_t* Databuf, uint32_t length)
{
        uint32_t i;
        for(i=0;i<length;i++)
        {
                //串口发送
                USART_SendData(USARTx,Databuf[i]);
                //发送完成标志
                while(!USART_Get_Transmitter_Empty_Flag(USARTx));
        }
}


/**
  * 描述  串口异步全双工配置(默认8bit收发使能  全双工 9600)
  * 输入   指向USART内存结构的指针,取值为USART0_SFR~USART8_SFR
  * 返回   无
  */
void USART_Async_config(USART_SFRmap *USARTx)
{
        USART_InitTypeDef USART_InitStructure;

        USART_Struct_Init(&USART_InitStructure);
    USART_InitStructure.m_Mode=USART_MODE_FULLDUPLEXASY;                        //全双工
    USART_InitStructure.m_TransferDir=USART_DIRECTION_FULL_DUPLEX;              //传输方向
    USART_InitStructure.m_WordLength=USART_WORDLENGTH_8B;                       //8位数据
    USART_InitStructure.m_StopBits=USART_STOPBITS_1;                            //1位停止位
    USART_InitStructure.m_BaudRateBRCKS=USART_CLK_HFCLK;                        //内部高频时钟作为 USART波特率发生器时钟

    /* 波特率 =Fck/(16*z(1+x/y)) 外设时钟内部高频16M*/
    //4800    z:208    x:0    y:0
    //9600    z:104    x:0    y:0
    //19200   z:52     x:0    y:0
    //115200  z:8      x:1    y:13
    //波特率9600
    USART_InitStructure.m_BaudRateInteger=104;         //USART波特率整数部分z,取值为0~65535
    USART_InitStructure.m_BaudRateNumerator=0;         //USART波特率小数分子部分x,取值为0~0xF
    USART_InitStructure.m_BaudRateDenominator=0;       //USART波特率小数分母部分y,取值为0~0xF

        USART_Reset(USARTx);                                       //USARTx复位
        USART_Configuration(USARTx,&USART_InitStructure);          //USARTx配置
        USART_Clear_Transmit_BUFR_INT_Flag(USARTx);                //USARTx发送BUF清零
        USART_RESHD_Enable (USARTx, TRUE);                                                   //使能RESHD位
        USART_Cmd(USARTx,TRUE);                                    //USARTx使能
}

使用特权

评论回复
答案很长吧| | 2020-10-29 09:38 | 显示全部楼层
有没有整个工程的文件,感谢,感谢楼主分享。

使用特权

评论回复
自己造声卡| | 2020-10-29 09:48 | 显示全部楼层
希望楼主上传一下整个工程的文件,我想看看里面的工程是如何配置的,我的配置好像有点问题,不能够运行的。

使用特权

评论回复
wahahaheihei| | 2020-10-29 10:00 | 显示全部楼层
代码很规范,学习学习

使用特权

评论回复
凯复Kane| | 2020-10-29 18:55 | 显示全部楼层
写的可读性还蛮高的 楼主应该写码习惯很好

使用特权

评论回复
yangxiaor520| | 2020-10-30 08:00 | 显示全部楼层
感谢楼主分享

使用特权

评论回复
heisexingqisi| | 2021-1-14 21:48 | 显示全部楼层
还是要好好的学习一下的。

使用特权

评论回复
643757107| | 2021-1-14 22:55 | 显示全部楼层
硬件收发器的学会了,很有用的。

使用特权

评论回复
piteqiu| | 2021-1-15 10:28 | 显示全部楼层
只看函数和寄存器的话,确实和ARM系列没什么区别,希望自己架构的芯片越来越好

使用特权

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

本版积分规则

22

主题

231

帖子

0

粉丝