在HAL库实现HART协议收发数据的文章中提及到了
这里其实还有一个获得主变量PV值的一个函数,和一个控制电流输出PV值的函数。前者是通过ad5421_read函数读失调调整寄存器和增益调整寄存器的值;并判断是否为输出电流模式,是则判断固定电流模式是否为0,不为0则写入该电流值,否则计算相应的电流输出值(调用后者函数,控制AD5421的DAC)。
本工程的AD5421中失调调整寄存器以及增益调整寄存器的值直接给了默认值。
可以先了解AD5421中的失调调整寄存器以及增益调整寄存器,以及AD5421工作电流范围。
失调和增益调整值的传递函数公式
0x83、0x84分别为读取AD5421的失调调整寄存器和增益调整寄存器的值。
void Ctrl_Current_OUT(float pv)
{
float current=0.0f;
uint16_t offset=0;
uint16_t gain=0;
offset = ad5421_read(0x83);
gain = ad5421_read(0x84);
if(GUI_Setting.Unique_Value.Current_Mode[1]==0x00)//#define GUI_Current_Mode_4_20 0x00
{
current=20.0f-16.0f*(GUI_Setting.Adjust.high-pv)/(GUI_Setting.Adjust.high-GUI_Setting.Adjust.low); //PV(空高)值越小 电流越大 低料位-高料位对应4-20mA
}
else
{
current=20.0f+16.0f*(pv-GUI_Setting.Adjust.low)/(GUI_Setting.Adjust.low-GUI_Setting.Adjust.high); //PV(空高)值越大 电流越大 低料位-高料位对应20-4mA
}
ad5421CurDAC(current,true,offset,gain);
}
float Get_PV(void)
{
float pv = 0.0f;
uint16_t offset = 0;
uint16_t gain = 0;
offset = ad5421_read(0x83);
gain = ad5421_read(0x84);
pv = 1.0f;
if(GUI_Setting.Unique_Value.Current_Mode[0] != 0x00)//#define GUI_Current_Mode_Disable 0x00 //关闭电流输出
{
if(GUI_Setting.Unique_Value.Fixed_Current_Mode != 0.0f)
{
ad5421CurDAC(GUI_Setting.Unique_Value.Fixed_Current_Mode,true,offset,gain);
}
else
{
Ctrl_Current_OUT(pv);
}
}
else
{
ad5421CurDAC(4,true,offset,gain);
}
return pv;
}
而这里的ad5421CurDAC函数则是读写DAC寄存器。
可以从芯片手册中了解到,DAC寄存器是一个读/写寄存器,具体内容可以寻找芯片手册。
控制AD5421的读写寄存器,因为HART协议的工作电流在4-20mA,故当我们上位机想要控制AD5700的工作电流模式时,需要输入4-20mA之间的数字(数据类型定义为浮点型),如果输入的数值小于4,则输出4,若大于20,则输出20,保持AD5700的工作状态在4-20mA之间(工作电流在这之间HART才能够正常通信)。
该函数的第一个形参input_ctrl就是我们要输入的电流值。
(也许判断DAC寄存器的读写状态用switchcase会更好些,也许)
float ad5421CurDAC(float input_ctrl,bool write_cmd,uint16_t offset,uint16_t gain)
{
int64_t real_data = 0;
uint16_t data = 0;
//real_data = input_ctrl;
float offset_effect=0.0;
float gain_effect=0.0;
offset_effect = 16.0f/65536*(offset-32768)+4.0f;
gain_effect=16.0f/65536/65536*gain;
if(write_cmd)//write DAC
{
if(input_ctrl>20.0f)
{
input_ctrl = 20.0f;
}
else if(input_ctrl<4.0f)
{
input_ctrl = 4.0f;
}
// else
// {
// data = (input_ctrl-4.0f)*0x10000/16.0f;
// }
// ad5421_write(0x01,data);
// ad5421_write(0x05,0);
// }
// else
// {
// data = ad5421_read(0x81);
// input_ctrl = 16.0f*data/0x10000+4.0f;
// ad5421_write(0x05,0);
real_data = (input_ctrl-offset_effect)/gain_effect;
if(real_data<0)
{
real_data = 0;
}
else if(real_data>65535)
{
real_data = 65535;
}
data = real_data;
ad5421_write(0x02,data);//写入控制寄存器
ad5421_write(0x05,0);//加载DAC
}
else//read DAC
{
data = ad5421_read(0x82);//读取控制寄存器
input_ctrl = gain_effect * data + offset_effect;
//printf("read DAC input_ctrl = %0.6f\n",input_ctrl);
}
return input_ctrl;
}
结尾
就连我也觉得本文写得没头没尾的,并且有很多东西想写但是写来写去却只能浮于表面地描述:啊… …这是什么函数,那是什么变量,先这样再那样,最后再那样这样… …
只能说是我对这块地方的知识还不够了解,如同浮于水面的油,无法写出鞭辟入里的文章了。