项目场景:
最近在使用国产DAC芯片GP8211S,使用STM32F030通过IIC与之连接,发现设置输出寄存器内容成0x7FFF后,最大输出达到12V,超过了手册中说明的10V;
问题描述
这个是我GP8211S初始化函数和发送,设置0x77是想得到最大10V的电压输出;
void Gp8211s_Init(void)
{
//Range 0 to 5V
Gp8211s_IIC_Start();
Gp8211s_IIC_SendByte(0xB0);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x01);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x77);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_Stop();
}
// data_hex max: 0x7FFF
void gp8211s_send_cmd(uint16_t data_hex )
{
uint8_t data8_tmp = 0;
//Set Reg value
Gp8211s_IIC_Start();
Gp8211s_IIC_SendByte(0xB0);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x02);
Gp8211s_IIC_WaitAck();
data8_tmp = data_hex & 0xFF;
Gp8211s_IIC_SendByte(data8_tmp);//DATA Low
//Gp8211s_IIC_WaitAck(); //!!! add this, not OK;
data8_tmp = (data_hex & 0x7F00 )>> 8;
Gp8211s_IIC_SendByte(data8_tmp);//DATA High
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_Stop();
}
GP8211S 配置手册描述:

我的电路图如下,这个电路是12V供电,代码里设置0x7FFF,输出12V;


原因分析:
通过实际测试发现:
1)好像1byte设置为0x55以下的数值,得到的最大输出范围就是5V的;
2)设置数值大于0x55的,就会得到超过10V的输出;
3)而等于0x55,最大输出就是10V;
还有,时序图中的DATA Low和DATA High之间的ACK,程序要“不检查ACK”,才能设置数据成功!
c代码:
提示:这里填写该问题的具体解决方案:
#include "gp8211s.h"
#include "main.h"
#include "delay.h"
uint8_t Gp8211s_Channel_Sel;
void Gp8211s_Choose_Channel(uint8_t ch)
{
if( !ch )
Gp8211s_Channel_Sel = 0;
else
Gp8211s_Channel_Sel = 1;
}
void Gp8211s_SCL_Clr()
{
if( !Gp8211s_Channel_Sel )
HAL_GPIO_WritePin(GP1_SCLK_GPIO_Port, GP1_SCLK_Pin, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GP2_SCLK_GPIO_Port, GP2_SCLK_Pin, GPIO_PIN_RESET);
}
void Gp8211s_SCL_Set()
{
if( !Gp8211s_Channel_Sel )
HAL_GPIO_WritePin(GP1_SCLK_GPIO_Port, GP1_SCLK_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(GP2_SCLK_GPIO_Port, GP2_SCLK_Pin, GPIO_PIN_SET);
}
void Gp8211s_SDA_Clr()
{
if( !Gp8211s_Channel_Sel )
HAL_GPIO_WritePin(GP1_SDA_GPIO_Port, GP1_SDA_Pin, GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(GP2_SDA_GPIO_Port, GP2_SDA_Pin, GPIO_PIN_RESET);
}
void Gp8211s_SDA_Set()
{
if( !Gp8211s_Channel_Sel )
HAL_GPIO_WritePin(GP1_SDA_GPIO_Port, GP1_SDA_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(GP2_SDA_GPIO_Port, GP2_SDA_Pin, GPIO_PIN_SET);
}
void Gp8211s_IIC_SdaOut()
{
GPIO_InitTypeDef GPIO_InitStruct;
if( !Gp8211s_Channel_Sel )
{
GPIO_InitStruct.Pin = GP1_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init( GP1_SDA_GPIO_Port, &GPIO_InitStruct );
}
else
{
GPIO_InitStruct.Pin = GP2_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init( GP2_SDA_GPIO_Port, &GPIO_InitStruct );
}
}
void Gp8211s_IIC_SdaIn()
{
GPIO_InitTypeDef GPIO_InitStruct;
//return;
if( !Gp8211s_Channel_Sel )
{
GPIO_InitStruct.Pin = GP1_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init( GP1_SDA_GPIO_Port, &GPIO_InitStruct );
}
else
{
GPIO_InitStruct.Pin = GP2_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init( GP2_SDA_GPIO_Port, &GPIO_InitStruct );
}
}
void Gp8211s_IIC_Init()
{
Gp8211s_IIC_SdaOut();
Gp8211s_SDA_Set();
Gp8211s_SCL_Set();
delay_us(10);
}
void Gp8211s_IIC_Start(void)
{
Gp8211s_IIC_SdaOut();
Gp8211s_SDA_Set();
Gp8211s_SCL_Set();
delay_us(10);
Gp8211s_SDA_Clr();
delay_us(10);
}
void Gp8211s_IIC_Stop(void)
{
Gp8211s_IIC_SdaOut();
Gp8211s_SDA_Clr();
Gp8211s_SCL_Set();
delay_us(10);
Gp8211s_SDA_Set();
delay_us(10);
}
void Gp8211s_IIC_SendByte(uint8_t txd)
{
uint8_t t;
uint8_t tdata = txd;
Gp8211s_IIC_SdaOut();
Gp8211s_SCL_Clr();
delay_us(10);
for(t=0; t<8; t++)
{
if( tdata & 0x80 )
Gp8211s_SDA_Set();
else
Gp8211s_SDA_Clr();
tdata <<= 1;
delay_us(10);
Gp8211s_SCL_Set();
delay_us(10);
Gp8211s_SCL_Clr();
delay_us(10);
}
}
uint8_t Gp8211s_IIC_SdaState()
{
uint8_t ret;
if( !Gp8211s_Channel_Sel )
ret = HAL_GPIO_ReadPin(GP1_SDA_GPIO_Port, GP1_SDA_Pin);
else
ret = HAL_GPIO_ReadPin(GP2_SDA_GPIO_Port, GP2_SDA_Pin);
return ret;
}
uint8_t Gp8211s_IIC_ReadByte(void)
{
uint8_t t;
uint8_t rdata=0;
Gp8211s_IIC_SdaIn();
for(t=0; t<8; t++)
{
Gp8211s_SCL_Set();
delay_us(10);
rdata <<= 1;
if( Gp8211s_IIC_SdaState() )
rdata|=0x01;
Gp8211s_SCL_Clr();
delay_us(10);
}
return rdata;
}
uint8_t Gp8211s_IIC_WaitAck(void)
{
uint32_t ucErrTime = 0;
GPIO_PinState sda_state;
uint8_t RetValue = 0;
Gp8211s_SCL_Set();
delay_us(20);
#if 0
Gp8211s_IIC_SdaIn();
while(ucErrTime++ < 10000)
{
delay_us(20);
sda_state = Gp8211s_IIC_SdaState();
if( sda_state == GPIO_PIN_RESET )
{
RetValue = 1;
break;
}
}
if( ucErrTime >= 10000 )
{
printf("Gp8211s_IIC_WaitAck timeout\n");
Gp8211s_IIC_Stop();
}
#endif
return RetValue;
}
void Gp8211s_Init(void)
{
//Range 0 to 5V
Gp8211s_IIC_Start();
Gp8211s_IIC_SendByte(0xB0);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x01);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x55); //0x44, 5V; 0x55: 10V; 0x77:12V;
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_Stop();
}
// data_hex max: 0x7FFF
void gp8211s_send_cmd(uint16_t data_hex )
{
uint8_t data8_tmp = 0;
//Set Reg value
Gp8211s_IIC_Start();
Gp8211s_IIC_SendByte(0xB0);
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_SendByte(0x02);
Gp8211s_IIC_WaitAck();
data8_tmp = data_hex & 0xFF;
Gp8211s_IIC_SendByte(data8_tmp);//DATA Low
//Gp8211s_IIC_WaitAck(); //!!! add this, not OK;
data8_tmp = (data_hex & 0x7F00 )>> 8;
Gp8211s_IIC_SendByte(data8_tmp);//DATA High
Gp8211s_IIC_WaitAck();
Gp8211s_IIC_Stop();
}
void gp8211s_OutPutVolt(uint16_t volt_in_mv )
{
uint32_t VoltRange = 10*1000; //10V
uint16_t RegVal = 0;
if( volt_in_mv > VoltRange )
volt_in_mv = VoltRange;
RegVal = volt_in_mv * 0x7FFF / VoltRange;
RegVal &= 0x7FFF;
//printf("volt_in_mv: %d, RegVal: %X \n ", volt_in_mv, RegVal);
gp8211s_send_cmd(RegVal);
// gp8211s_send_cmd(0x4000);
//printf("volt_in_mv: %d, RegVal: %X \n ", volt_in_mv, RegVal);
}
更多技术讨论: 添加请微信: automan_111 tel: