#include "includes.h" // DAC7311输出范围:0~4095对应0~2.5v,转成成0~25mA // 延迟大约10us void DAC7311_delay() { uint32_t loop = 250; while(loop--) __NOP(); } // 通讯定义 #define DAC7311_CHANNEL_1_LATCH_LOW() \ { \ LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_8); \ DAC7311_delay(); \ } #define DAC7311_CHANNEL_1_LATCH_HIGH() \ { \ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_8); \ DAC7311_delay(); \ } #define DAC7311_CHANNEL_2_LATCH_LOW() \ { \ LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_7); \ DAC7311_delay(); \ } #define DAC7311_CHANNEL_2_LATCH_HIGH() \ { \ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7); \ DAC7311_delay(); \ } #define DAC7311_CHANNEL_3_LATCH_LOW() \ { \ LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_9); \ DAC7311_delay(); \ } #define DAC7311_CHANNEL_3_LATCH_HIGH() \ { \ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_9); \ DAC7311_delay(); \ } #define DAC7311_CLK_LOW() \ { \ LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6); \ DAC7311_delay(); \ } #define DAC7311_CLK_HIGH() \ { \ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6); \ DAC7311_delay(); \ } #define DAC7311_DATA_1() \ { \ LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_15); \ DAC7311_delay(); \ } #define DAC7311_DATA_0() \ { \ LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_15); \ DAC7311_delay(); \ } // 写 1 bit void DAC7311_Bit(uint32_t b1) { DAC7311_CLK_HIGH(); if(b1) { DAC7311_DATA_1(); } else { DAC7311_DATA_0(); } DAC7311_CLK_LOW(); } // 写多个bits void DAC7311_Bits(uint32_t bytes, uint8_t num) { uint32_t mask = (1ul << (num - 1)); while(num--) { DAC7311_Bit(bytes & mask); bytes <<= 1; } } void DAC7311_Write(uint8_t channel, uint32_t data) { if(channel == 0) { DAC7311_CHANNEL_1_LATCH_LOW(); } else if(channel == 1) { DAC7311_CHANNEL_2_LATCH_LOW(); } else { DAC7311_CHANNEL_3_LATCH_LOW(); } DAC7311_Bits(data, 16); if(channel == 0) { DAC7311_CHANNEL_1_LATCH_HIGH(); } else if(channel == 1) { DAC7311_CHANNEL_2_LATCH_HIGH(); } else { DAC7311_CHANNEL_3_LATCH_HIGH(); } DAC7311_CLK_HIGH(); } // 初始化 void DAC7311_Init() { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); /**/ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9); /**/ LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_15); /**/ LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_15; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOC, &GPIO_InitStruct); } void DAC7311_Open() { // 刷新电流输出 DAC7311_Refresh(); } // 输出正常电流, 将液位百分比转换为4~20mA电流 void DAC7311_Out(uint8_t channel, float percent) { uint32_t dac = (percent * 0.16 + 4) / 25 * 4095 + 0.5; DAC7311_Write(channel, dac << 2); } // 输出报警电流:3.5mA void DAC7311_OutAlarm(uint8_t channel) { uint32_t dac = 3.5 / 25 * 4095 + 0.5; DAC7311_Write(channel, dac << 2); } // 输出零电流:0mA void DAC7311_OutZero(uint8_t channel) { uint32_t dac = 0; DAC7311_Write(channel, dac << 2); } // 刷新电流输出 void DAC7311_Refresh() { uint8_t on = IS_VCC_MA_ON(); // 有RF模块时,4~20mA输出不能使用(共用电源控制口,且模块位置冲突) if(RF_initStatus) return; VCC_MA_ON(); #if 0 DAC7311_OutAlarm(0); // 3.5mA DAC7311_Out(1, 0); // 4mA DAC7311_Out(2, 100); // 20mA #else if(dcBuff.sampleData.staDPress.notConnect) DAC7311_OutZero(0); else if(dcBuff.sampleData.staDPress.underFlow || dcBuff.sampleData.staDPress.overFlow) DAC7311_OutAlarm(0); else if(dcBuff.configDisplay.op_HARDWARE_VER_MAJOR == 229 // 巴西罐箱 || dcBuff.configDisplay.op_USE_CAPACITY_SENSOR // 电容测量 || dcBuff.configDisplay.op_420MA_OUT_PCT // 4~20mA输出液位百分比 || dcBuff.configSensor.levelOutMMWC > 0) // 按最高液位的mmWC输出液位百分比 { DAC7311_Out(0, dcBuff.sampleData.volumePct * 0.01); // volumePct放大了100倍的 } else // 其它差压客户 { // 差压传感器的量程 DAC7311_Out(0, (dcBuff.sampleData.diff - dcBuff.configSensor.sensorDPress.lowRange) * 100.0 / (dcBuff.configSensor.sensorDPress.highRangeX10 * (dcBuff.configSensor.sensorDPress.ishighRangeX10 ? 0.1 : 1) - dcBuff.configSensor.sensorDPress.lowRange)); } if(!dcBuff.configDisplay.op_2ND_420MA_OUT_LEVEL) { if(dcBuff.sampleData.staPress.notConnect) DAC7311_OutZero(1); else if(dcBuff.sampleData.staPress.underFlow || dcBuff.sampleData.staPress.overFlow) DAC7311_OutAlarm(1); else if(dcBuff.sampleData.staPress.full) DAC7311_Out(1, 100); else { // 压力传感器的量程 DAC7311_Out(1, (dcBuff.sampleData.pressure - dcBuff.configSensor.sensorPress.lowRange) * 100.0 / (dcBuff.configSensor.sensorPress.highRange - dcBuff.configSensor.sensorPress.lowRange)); } } else { if(dcBuff.sampleData.staDPress.notConnect) DAC7311_OutZero(1); else if(dcBuff.sampleData.staDPress.underFlow || dcBuff.sampleData.staDPress.overFlow) DAC7311_OutAlarm(1); else if(dcBuff.configDisplay.op_HARDWARE_VER_MAJOR == 229 // 巴西罐箱 || dcBuff.configDisplay.op_USE_CAPACITY_SENSOR // 电容测量 || dcBuff.configDisplay.op_420MA_OUT_PCT // 4~20mA输出液位百分比 || dcBuff.configSensor.levelOutMMWC > 0) // 按最高液位的mmWC输出液位百分比 { DAC7311_Out(1, dcBuff.sampleData.volumePct * 0.01); // volumePct放大了100倍的 } else // 其它差压客户 { // 差压传感器的量程 DAC7311_Out(1, (dcBuff.sampleData.diff - dcBuff.configSensor.sensorDPress.lowRange) * 100.0 / (dcBuff.configSensor.sensorDPress.highRangeX10 * (dcBuff.configSensor.sensorDPress.ishighRangeX10 ? 0.1 : 1) - dcBuff.configSensor.sensorDPress.lowRange)); } } if(dcBuff.sampleData.staExtTempr[0].notConnect) DAC7311_OutZero(2); else if(dcBuff.sampleData.staExtTempr[0].underFlow || dcBuff.sampleData.staExtTempr[0].overFlow) DAC7311_OutAlarm(2); else if(dcBuff.sampleData.staExtTempr[0].full) DAC7311_Out(2, 100); else if(dcBuff.configDisplay.op_USE_PT100_SENSOR) { // PT100温度传感器的量程: -200~80 DAC7311_Out(2, (dcBuff.sampleData.extTempr[0] - (-200)) * 100.0 / (80 - (-200))); } else { // 4~20mA温度传感器的量程 DAC7311_Out(2, (dcBuff.sampleData.extTempr[0] - dcBuff.configSensor.sensorMTempr[0].lowRange) * 100.0 / (dcBuff.configSensor.sensorMTempr[0].highRange - dcBuff.configSensor.sensorMTempr[0].lowRange)); } #endif if(!on) VCC_MA_OFF(); }