stm32模拟IIC驱动高精度RTC芯片RX8025的参考源码,如下。希望对大家有帮助!
/* Includes--------------------------------------------------------------*/ //#include "sysconfig.h" #include "stm32f10x.h" //#include "bsp_SIIC.h" #include "bsp_RX8025.h" /* Private define-----------------------------------------------------------------------------*/ // 设备读写地址 #define RX8025_ADDR_READ 0x65 #define RX8025_ADDR_WRITE 0x64 // 设备寄存器地址 #define RX8025_ADDR_SECONDS 0x00 #define RX8025_ADDR_WEEK 0x30 #define RX8025_ADDR_DATES 0x40 #define RX8025_ADDR_MONTH 0x50 #define RX8025_ADDR_MINUTES 0x80 #define RX8025_ADDR_CONTROL1 0xE0 #define RX8025_ADDR_CONTROL2 0xF0 // 设备操作模式 #define RX8025_WRITE_MODE 0xF0 #define RX8025_READ_MODE 0xF0 #define RX8025_SIMP_READ_MODE 0x04 #define u8BAND(addr, u8num) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(u8num<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define u8_ADDR(addr, u8num) MEM_ADDR(u8BAND(addr, u8num)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只对单一的IO口! //确保n的值小于16! #define PAout(n) u8_ADDR(GPIOA_ODR_Addr,n) //输出 #define PAin(n) u8_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) u8_ADDR(GPIOB_ODR_Addr,n) //输出 #define PBin(n) u8_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) u8_ADDR(GPIOC_ODR_Addr,n) //输出 #define PCin(n) u8_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) u8_ADDR(GPIOD_ODR_Addr,n) //输出 #define PDin(n) u8_ADDR(GPIOD_IDR_Addr,n) //输入 #define PEout(n) u8_ADDR(GPIOE_ODR_Addr,n) //输出 #define PEin(n) u8_ADDR(GPIOE_IDR_Addr,n) //输入 #define PFout(n) u8_ADDR(GPIOF_ODR_Addr,n) //输出 #define PFin(n) u8_ADDR(GPIOF_IDR_Addr,n) //输入 #define PGout(n) u8_ADDR(GPIOG_ODR_Addr,n) //输出 #define PGin(n) u8_ADDR(GPIOG_IDR_Addr,n) //输入 ///////////////////////////////////////////////////////////////// //Ex_NVIC_Config专用定义 #define GPIO_A 0 #define GPIO_B 1 #define GPIO_C 2 #define GPIO_D 3 #define GPIO_E 4 #define GPIO_F 5 #define GPIO_G 6 //IO操作函数 #define IIC_SCL PBout(15) //SCL #define IIC_SDA PBout(14) //SDA #define READ_SDA PBin(14) //输入SDA void I2C_Configuration(void); /* Private typedef----------------------------------------------------------------------------*/ // 寄存器结构 // CONTROL1,结构定义 typedef struct { u8 CT:3; u8 TEST:1; u8 nCLEN2:1; u8 HOUR24:1; u8 DALE:1; u8 WALE:1; }_RX8025_REG_CONTROL1_BITS; typedef union { u8 byte; _RX8025_REG_CONTROL1_BITS bits; }_RX8025_REG_CONTROL1; /* Private macro------------------------------------------------------------------------------*/ /* Private variables--------------------------------------------------------------------------*/ /* Private function prototypes----------------------------------------------------------------*/ /* Private functions--------------------------------------------------------------------------*/ void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO ,ENABLE); /* Configure I2C2 pins: PB15 -> SCL and PB14 -> SDA */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); } void SDA_IN(void) //sda线输入 ,PA11 { GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体 // Configure I2C1 pins:SDA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); } void SDA_OUT(void) //sda线输出 { GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); } // 延时总时间=cnt*16+24us void delay(u16 cnt) { u8 i; for(;cnt>0;cnt--) for(i=0;i<100;i++); } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA=1; IIC_SCL=1; delay(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay(4); IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay(4); IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号 delay(4); } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay(1); IIC_SCL=1;delay(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0 return 0; } //产生ACK应答 void IIC_ACK(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay(2); IIC_SCL=1; delay(2); IIC_SCL=0; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay(2); IIC_SCL=1; delay(2); IIC_SCL=0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 u8 IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { IIC_SDA=(txd&0x80)>>7; txd<<=1; delay(2); //对TEA5767这三个延时都是必须的 IIC_SCL=1; delay(2); IIC_SCL=0; delay(2); } t=IIC_Wait_Ack(); return (t); } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(u8 ack) { u8 i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL=0; delay(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay(1); } if (!ack) IIC_NAck();//发送nACK else IIC_ACK(); //发送ACK return receive; } void RX8025Write(u8 addr,u8 *pData,u8 len) { u8 i; IIC_Start(); if(IIC_Send_Byte(RX8025_ADDR_WRITE)==1) { IIC_Stop(); return; } if(IIC_Send_Byte(addr)==1) { IIC_Stop(); return; } for(i=0;i<len;i++) { if(IIC_Send_Byte(pData)==1) { IIC_Stop(); return; } } IIC_Stop(); } void RX8025Read(u8 addr,u8 *pData,u8 len) { u8 i; IIC_Start(); if(IIC_Send_Byte(RX8025_ADDR_WRITE)==1) { IIC_Stop(); return; } if(IIC_Send_Byte(addr)==1) { IIC_Stop(); return; } IIC_Start(); if(IIC_Send_Byte(RX8025_ADDR_READ)==1) { IIC_Stop(); return; } for(i=0;i<len-1;i++) { pData = IIC_Read_Byte(1); // IIC_ACK(); } pData = IIC_Read_Byte(0); // IIC_NAck(); IIC_Stop(); } /*********************************************************************************************** * Function : BSP_RX8025Write * Description : 向时钟芯片写数据 * Input : * Output : * Note(s) : * Contributor : 081218 andydriver ***********************************************************************************************/ void BSP_RX8025Write(u8 *pData,u8 len) { RX8025Write((RX8025_ADDR_SECONDS&RX8025_WRITE_MODE),pData,len); } /*********************************************************************************************** * Function : BSP_RX8025Read * Description : 从时钟芯片读取数据 * Input : * Output : * Note(s) : * Contributor : 081218 andydriver ***********************************************************************************************/ void BSP_RX8025Read(u8 *pData,u8 len) { RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),pData,len); } /*********************************************************************************************** * Function : BSP_RX8025ControlINTA * Description : 控制芯片的INTA脚状态 * Input : state:状态(_BSPRX8025_INTAOUT) BSPRX8025_INTAOUT_HIZ:高阻 BSPRX8025_INTAOUT_LOW:输出低 BSPRX8025_INTAOUT_2HZ:输出2Hz(50%)的脉冲 BSPRX8025_INTAOUT_1HZ:输出1Hz(50%)的脉冲 BSPRX8025_INTAOUT_SEC:每秒的第0秒翻转?还是脉冲? BSPRX8025_INTAOUT_MIN:每分的第0秒翻转?还是脉冲? BSPRX8025_INTAOUT_HOUR:每时的第0秒翻转?还是脉冲? BSPRX8025_INTAOUT_MONTH:每月的第0秒翻转?还是脉冲? * Output : * Note(s) : * Contributor : 081218 andydriver ***********************************************************************************************/ //void BSP_RX8025ControlINTA(_BSPRX8025_INTAOUT state) //{ // _RX8025_REG_CONTROL1 data; // // RX8025Read((RX8025_ADDR_CONTROL1&RX8025_READ_MODE),(u8 *)(&data),1); // data.bits.CT = state; // INTA输出1Hz方波 // RX8025Write((RX8025_ADDR_CONTROL1&RX8025_WRITE_MODE),(u8 *)(&data),1); //} /*********************************************************************************************** * Function : BSP_RX8025Init * Description : RX8025初始化 * Input : * Output : * Note(s) : * Contributor : 081210 andydriver ***********************************************************************************************/ void BSP_RX8025Init(void) { u8 buf[16]; u8 i; // iic_init(); RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),buf,8); buf[0] = 0x20; RX8025Write((RX8025_ADDR_CONTROL1&RX8025_WRITE_MODE),buf,1); //24小时制 RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),buf,16); i++; } |