int main(void) { /*初始化i2c*/ MyI2C_Init(); /*设置对应电流*/ uint16_t dac_val GP8212S_Calc_Data(12.0f); // 12mA GP8212S_Write_Data(dac_val); /*掉电保存*/ GP8212S_Save_Data(); while (1) { } }#include stm32f10x.h // 引入你之前写的模拟I2C底层代码头文件若有 #include myi2c.h #include Delay.h /************************** GP8212S 芯片专属宏定义 **************************/ #define GP8212S_Rs 100 // 采样电阻默认100Ω芯片规格书推荐 #define GP8212S_MAX_DATA 0x7FFF // 15bit最大数字量 0~32767 #define GP8212S_V_REF 2.5f // 参考电压2.5V #define GP8212S_SAVE_DELAY_MS 7 // 掉电保存需等待至少7ms /************************** 函数声明 **************************/ void GP8212S_Write_Data(uint16_t data); // 写入15bit数字量 void GP8212S_Save_Data(void); // 固化数据到芯片掉电保存 uint16_t GP8212S_Calc_Data(float i_out); // 根据目标电流计算对应15bit数字量 /************************** GP8212S 核心驱动函数 **************************/ /** * brief 向GP8212S写入15bit数字量高字节低字节 * param data: 待写入的15bit数字量0~0x7FFF * note 协议START - 高字节(8bit) ACK - 低字节(8bit) ACK - STOP */ void GP8212S_Write_Data(uint16_t data) { // 限制数据范围为15bit防止溢出 if(data GP8212S_MAX_DATA) { data GP8212S_MAX_DATA; } uint8_t data_h (data 8) 0x7F; // 高7bit15bit数据高字节仅7位有效 uint8_t data_l data 0xFF; // 低8bit全部有效 MyI2C_Start(); // I2C起始信号 MyI2C_SendByte(0XB0); // 发送地址 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0X02); //配置指令 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(data_l); // 发送低字节 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(data_h); // 发送高字节 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); // I2C停止信号 } /** * brief 将当前配置的数字量固化到GP8212S芯片内部掉电后仍保留 * note 严格遵循芯片规格书固定指令序列 至少7ms延时 */ void GP8212S_Save_Data(void) { // 第一步发送固化起始指令序列 MyI2C_Start(); MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_Stop(); MyI2C_Start(); MyI2C_SendByte(0x10); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0x03); // 规格书固定指令 0000 0011 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); /*第二行*/ MyI2C_Start(); MyI2C_SendByte(0xB0); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 for(uint8_t i0;i6;i) { MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 } MyI2C_Stop(); // 第二步必须等待7ms以上芯片内部擦写时间 Delay_ms(GP8212S_SAVE_DELAY_MS 1); // 加1ms冗余避免时序问题 MyI2C_Start(); MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_Stop(); MyI2C_Start(); MyI2C_SendByte(0x10); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); } /** * brief 根据目标输出电流计算GP8212S对应的15bit数字量 * param i_out: 目标输出电流单位mA0~25mARs100Ω时 * retval 对应的15bit数字量0~0x7FFF * note 公式IOUT 2.5V/Rs * DATA/0x7FFF → DATA IOUT * Rs * 0x7FFF / 2.5V */ uint16_t GP8212S_Calc_Data(float i_out) { uint16_t data 0; // 限制电流范围Rs100Ω时芯片最大输出25mA if(i_out 0.0f) { i_out 0.0f; } else if(i_out 25.0f) { i_out 25.0f; } // 核心计算公式单位转换mA→A即÷1000 data (uint16_t)(i_out * 0.001f * GP8212S_Rs * GP8212S_MAX_DATA / GP8212S_V_REF); // 二次校验确保数据在15bit范围内 if(data GP8212S_MAX_DATA) { data GP8212S_MAX_DATA; } return data; }
GP8201S dac芯片外设驱动标准库驱动例程(带掉电保存)
int main(void) { /*初始化i2c*/ MyI2C_Init(); /*设置对应电流*/ uint16_t dac_val GP8212S_Calc_Data(12.0f); // 12mA GP8212S_Write_Data(dac_val); /*掉电保存*/ GP8212S_Save_Data(); while (1) { } }#include stm32f10x.h // 引入你之前写的模拟I2C底层代码头文件若有 #include myi2c.h #include Delay.h /************************** GP8212S 芯片专属宏定义 **************************/ #define GP8212S_Rs 100 // 采样电阻默认100Ω芯片规格书推荐 #define GP8212S_MAX_DATA 0x7FFF // 15bit最大数字量 0~32767 #define GP8212S_V_REF 2.5f // 参考电压2.5V #define GP8212S_SAVE_DELAY_MS 7 // 掉电保存需等待至少7ms /************************** 函数声明 **************************/ void GP8212S_Write_Data(uint16_t data); // 写入15bit数字量 void GP8212S_Save_Data(void); // 固化数据到芯片掉电保存 uint16_t GP8212S_Calc_Data(float i_out); // 根据目标电流计算对应15bit数字量 /************************** GP8212S 核心驱动函数 **************************/ /** * brief 向GP8212S写入15bit数字量高字节低字节 * param data: 待写入的15bit数字量0~0x7FFF * note 协议START - 高字节(8bit) ACK - 低字节(8bit) ACK - STOP */ void GP8212S_Write_Data(uint16_t data) { // 限制数据范围为15bit防止溢出 if(data GP8212S_MAX_DATA) { data GP8212S_MAX_DATA; } uint8_t data_h (data 8) 0x7F; // 高7bit15bit数据高字节仅7位有效 uint8_t data_l data 0xFF; // 低8bit全部有效 MyI2C_Start(); // I2C起始信号 MyI2C_SendByte(0XB0); // 发送地址 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0X02); //配置指令 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(data_l); // 发送低字节 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(data_h); // 发送高字节 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); // I2C停止信号 } /** * brief 将当前配置的数字量固化到GP8212S芯片内部掉电后仍保留 * note 严格遵循芯片规格书固定指令序列 至少7ms延时 */ void GP8212S_Save_Data(void) { // 第一步发送固化起始指令序列 MyI2C_Start(); MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_Stop(); MyI2C_Start(); MyI2C_SendByte(0x10); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0x03); // 规格书固定指令 0000 0011 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); /*第二行*/ MyI2C_Start(); MyI2C_SendByte(0xB0); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 for(uint8_t i0;i6;i) { MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 } MyI2C_Stop(); // 第二步必须等待7ms以上芯片内部擦写时间 Delay_ms(GP8212S_SAVE_DELAY_MS 1); // 加1ms冗余避免时序问题 MyI2C_Start(); MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(1); //1 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_W_SDA(0); //0 MyI2C_W_SCL(1); //从机采集数据 MyI2C_W_SCL(0); //更换数据 MyI2C_Stop(); MyI2C_Start(); MyI2C_SendByte(0x10); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_SendByte(0x00); // 规格书固定指令 0001 0000 while(MyI2C_ReceiveAck()1); // 等待ACK应答 MyI2C_Stop(); } /** * brief 根据目标输出电流计算GP8212S对应的15bit数字量 * param i_out: 目标输出电流单位mA0~25mARs100Ω时 * retval 对应的15bit数字量0~0x7FFF * note 公式IOUT 2.5V/Rs * DATA/0x7FFF → DATA IOUT * Rs * 0x7FFF / 2.5V */ uint16_t GP8212S_Calc_Data(float i_out) { uint16_t data 0; // 限制电流范围Rs100Ω时芯片最大输出25mA if(i_out 0.0f) { i_out 0.0f; } else if(i_out 25.0f) { i_out 25.0f; } // 核心计算公式单位转换mA→A即÷1000 data (uint16_t)(i_out * 0.001f * GP8212S_Rs * GP8212S_MAX_DATA / GP8212S_V_REF); // 二次校验确保数据在15bit范围内 if(data GP8212S_MAX_DATA) { data GP8212S_MAX_DATA; } return data; }