打印
[单片机芯片]

全国产化便携式高精度4~20mA电流信号源

[复制链接]
832|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
4~20mA电流信号是各类工业仪表和测试设备最常用的信号之一,针对AD5422类高精度4-20mA输出芯片无国产替代芯片的现状,为摆脱对国外芯片的依赖,研制了一套全国产化便携式高精度4~20mA电流信号源,精度可达0.1%,以32位互联型RISC-V MCU CH32V307为主控芯片,控制电压型DA输出电压信号,利用电压信号控制以运放和三极管及高精度电阻为主组成的压控电流源电路,输出高精度的4-20mA信号,为各类工业仪表测试结果输出和测试仪器设备的国产化替代提供支撑。
同时为了适应单独使用需求和增加可扩展及远程控制能力,开发了本地屏幕控制及远程Uart控制和CAN总线控制。



u_int16_t I2C1_CYDL(){
    //I2C1 可用//

    u_int16_t I2C1_CYDL_Value;
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET)
      ;
    I2C_GenerateSTART(I2C1, ENABLE);

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
          ;
    I2C_Send7bitAddress(I2C1, 0X90, I2C_Direction_Receiver);

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
          ;
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C1, ENABLE);//是否连续
    RX_T1 = I2C_ReceiveData(I2C1);//接收第1个字节 高8位
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C1, ENABLE);//是否连续
    RX_T2 = I2C_ReceiveData(I2C1);//接收第2个字节 低8位
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C1, ENABLE);//是否连续
    RX_T3 = I2C_ReceiveData(I2C1);//接收第3个字节 控制字
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C1, DISABLE);//是否连续
    I2C_GenerateSTOP(I2C1, ENABLE);

    pxbuf[1] = RX_T1;
    pxbuf[2] = RX_T2;
    pxbuf[3] = RX_T3;

    I2C1_CYDL_Value = (RX_T1 << 8) +  RX_T2; //高字节在前,合成16位
    I2C1_CYDL_Value = (I2C1_CYDL_Value*20480)>>15;// 将单位转换为uA ,统一以uA做计算
//    I2C1_CYDL_Value = (I2C1_CYDL_Value*0.9946-39.55 + 80);
//    if (I2C1_CYDL_Value < 1 ) {
//        I2C1_CYDL_Value = 1;
//    }
//    else if (I2C1_CYDL_Value >65534) {
//        I2C1_CYDL_Value = 65534;
//    }
    // 采样电流 屏幕显示值
    sprintf(num2str_temp,"DLCL.n0.val=%d",I2C1_CYDL_Value); //page DLCL n0对象 val参数显示
//    printf(num2str_temp);
//    printf("\r\n");
    uart8_send_string(num2str_temp);
    USART_SendData(UART8, 0xFF);
    Delay_Us(100);
    USART_SendData(UART8, 0xFF);
    Delay_Us(100);
    USART_SendData(UART8, 0xFF);

    return I2C1_CYDL_Value;

}

int16_t I2C2_HCDL(){
    //I2C2 可用//

    int16_t I2C2_HCDL_Value;

    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
      ;
    I2C_GenerateSTART(I2C2, ENABLE);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
          ;
    I2C_Send7bitAddress(I2C2, 0X90, I2C_Direction_Receiver);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
          ;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C2, ENABLE);//是否连续
    RX_T1 = I2C_ReceiveData(I2C2);//接收第1个字节 高8位
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C2, ENABLE);//是否连续
    RX_T2 = I2C_ReceiveData(I2C2);//接收第2个字节 低8位
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C2, ENABLE);//是否连续
    RX_T3 = I2C_ReceiveData(I2C2);//接收第3个字节 控制字
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
    I2C_AcknowledgeConfig(I2C2, DISABLE);//是否连续
    I2C_GenerateSTOP(I2C2, ENABLE);

//    pxbuf[4] = RX_T1;
//    pxbuf[5] = RX_T2;
    pxbuf[6] = RX_T3;

//    USART_SendData(USART1, 0x01);
//    Delay_Us(100);
//    USART_SendData(USART1, RX_T1);
//    Delay_Us(100);
//    USART_SendData(USART1, 0x02);
//    Delay_Us(100);
//    USART_SendData(USART1, RX_T2);
//    Delay_Us(100);

    I2C2_HCDL_Value = (RX_T1 << 8) +  RX_T2;//高字节在前,合成16位

    // 回采电流 屏幕显示值
    //page DLSC n1对象 val参数显示 2.048V*10000将单位转换为uA,>>15为除以32768
    I2C2_HCDL_Value = (I2C2_HCDL_Value*20480)>>15;// 将单位转换为uA ,统一以uA做计算
    I2C2_HCDL_Value = (I2C2_HCDL_Value*0.9946-39.55 + 80);
    if (I2C2_HCDL_Value < 1 ) {
        I2C2_HCDL_Value = 1;
    }
    else if (I2C2_HCDL_Value >65534) {
        I2C2_HCDL_Value = 65534;
    }
    pxbuf[4] = I2C2_HCDL_Value >> 8;
    pxbuf[5] = I2C2_HCDL_Value & 0x00ff;
    sprintf(num2str_temp,"DLSC.n1.val=%d",I2C2_HCDL_Value);
    uart8_send_string(num2str_temp);
    USART_SendData(UART8, 0xFF);
    Delay_Us(100);
    USART_SendData(UART8, 0xFF);
    Delay_Us(100);
    USART_SendData(UART8, 0xFF);
    sprintf(num2str_temp,"DLSC.n1.val=%d",I2C2_HCDL_Value);
    printf(num2str_temp);
    printf("\r\n");
    return I2C2_HCDL_Value;

}

u8 SPI1_DYSC(u_int16_t SPI1_5541_DYSC){
//SPI 可用  设置初始输出电压  0x672A:1.000V  0x3395:0.500V 0x528:0.05V
    sprintf(num2str_temp,"DYSC.val=%d",SPI1_5541_DYSC);
    printf(num2str_temp);
    printf("\r\n");
    if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != RESET){
        GPIO_WriteBit(GPIOA, GPIO_Pin_4,0);
        SPI_I2S_SendData(SPI1, SPI1_5541_DYSC);
        Delay_Us(14);
        GPIO_WriteBit(GPIOA, GPIO_Pin_4,1);
        return 0;
    }
    else {
        return 1;
    }
}

使用特权

评论回复
沙发
sblpp| | 2023-3-12 14:03 | 只看该作者
这是开源的嘛?
这算开源嘛?

使用特权

评论回复
板凳
643757107| | 2023-3-15 16:09 | 只看该作者
问一下4-20mA电流信号是怎么表达0和1的,是传输的模拟信号还是数字信号?

使用特权

评论回复
地板
tpgf| | 2023-4-3 13:53 | 只看该作者
咨询一个问题  就是为什么4~20mA电流信号很好买 而0-75mV的电压信号不好找呢

使用特权

评论回复
5
aoyi| | 2023-4-3 15:42 | 只看该作者
一般这种在什么范围内能保证输出的稳定呢

使用特权

评论回复
6
nawu| | 2023-4-3 15:56 | 只看该作者
请教楼主一下 我们一般如何模拟输出二线制电流输出呢

使用特权

评论回复
7
zljiu| | 2023-4-3 16:40 | 只看该作者
nawu 发表于 2023-4-3 15:56
请教楼主一下 我们一般如何模拟输出二线制电流输出呢

哈哈哈  我一般就是用的一个滑动变阻器模拟一下

使用特权

评论回复
8
gwsan| | 2023-4-3 17:07 | 只看该作者
643757107 发表于 2023-3-15 16:09
问一下4-20mA电流信号是怎么表达0和1的,是传输的模拟信号还是数字信号?

这种信号不能表达吧  或者必须认为定义一个范围

使用特权

评论回复
9
tfqi| | 2023-4-3 17:22 | 只看该作者
仔细看了看感觉电路板的精髓都在VI转换电路那块是吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝