• 【USB电压电流表】基于STM32F103C8T6 for Arduino


    主控芯片为STM32F103C8T6

    Arduino 的库确实多

    项目链接:USB电压电流表 - 嘉立创EDA开源硬件平台

    代码也挺简单的,没有多少行。

    这个项目主要是想学硬件。

    经过验证作者提供了两个版本的源代码,第一版能成功编译,第二版有变量名定义错误,还比较多。经过更改后仍可使用。


    输入输出

    SMAJ30A:瞬态抑制二极管


    供电部分

     最上 5V0 部分供电是预备留用的,并没有用到!


    部分检测口

    • PA0:D+电压采样
    • PA3:D- 电压采样
    • PA4:热敏电阻采样
    • PA5:输出电压采样
    • REST:上电自复位
    • PA15:KEY1
    • PB4:KEY2
    • PB10:KEY3
    • PB1:KEY4

    电流采样

    • PA1:大电流采样
    • PA2:小电流采样
    • PB9:大电流控制
    • PB8:小电流控制

    OPA2333:运算放大器芯片

    啊啊啊啊!!真烦,这一部分看不懂啊!!!!

    DGND只跟两个 NMOS 管相连。

    ▶️ 电流检测值为:

    1. map(analogRead(a1),0,4095,0,3270)/101/5
    2. /* 这里实际上是 */
    3. map(analogRead(a1),0,4095,0,3270)/101/(1000*0.005)

    ▶️ 这样,画了一个示意图:

    DGND 的电流 I 流向 GND 时,PA1检测到的电压为:

    I*0.005*\frac{101}{1}

    故,可知电流检测值的公式由来。

    很不错,学到了知识点!!!


    STM32周围接口

    基本都是备用留用的,没有用到!


    函数分析

    变量定义

    1. //USB测试表
    2. //量程10mA-6.5A
    3. #include
    4. #include
    5. #include
    6. #define OLED_RESET 4
    7. Adafruit_SSD1306 display(OLED_RESET);
    8. byte a1 = PA1; //大电流采样
    9. byte a2 = PA2; //小电流采样
    10. byte dn = PA3; //D-电压采样
    11. byte dp = PA0; //D+电压采样
    12. byte wd = PA4; //NTC采样
    13. byte dy = PA5; //电压采样
    14. byte k1 = PA15; //按键检测
    15. byte k2 = PB4; //按键检测
    16. byte k3 = PB10; //按键检测
    17. byte k4 = PB1; //按键检测
    18. byte M1 = PB9; //大电流控制
    19. byte M2 = PB8; //小电流控制
    20. float V ; //电源电压
    21. float VN ; //D-电压
    22. float VP ; //D+电压
    23. float A ; //电流
    24. int uA ; //电流
    25. float W ; //功率
    26. float R ; //负载
    27. float C ; //温度
    28. int Wh ; //电量
    29. long int T; //时间
    30. long int WT ; //电功
    31. long int i; //时间
    32. byte K1,K2,K3,K4; //按键
    33. byte ms = 0;

    电流、电压、功率测量

    1. void VA(){
    2. float vn = map(analogRead(dn),0,4095,0,3300); //D-电压采样
    3. VN = vn*2/1000;
    4. float vp = map(analogRead(dp),0,4095,0,3300); //D+电压采样
    5. VP = vp*2/1000;
    6. float LV = 0;
    7. float LA = 0;
    8. for(byte i = 0; i < 100; i++){
    9. float v = map(analogRead(dy),0,4095,0,3300); //输出电压采样
    10. V = v * 11/1000;
    11. LV = LV + V;
    12. float a = map(analogRead(a1),0,4095,0,3270); //大电流采样
    13. A = a/101/5;
    14. LA = LA + A;
    15. }
    16. V = LV/100; //平均值
    17. A = LA/100;
    18. W = V*A; //功率
    19. if( A > 0){
    20. R = V/A; //电阻
    21. if(R >= 100){ R = 99.99; }
    22. UIT();
    23. }else{
    24. R = 0;
    25. }
    26. if( A > 6.5){ digitalWrite( M1 ,LOW); } //设置大电流控制接口低电平
    27. }
    • analogRead(pin):读模拟引脚, 返回0-1023之间的值。
    • map(value, fromLow, fromHigh, toLow, toHigh):等比例缩放值。

    测量电量

    1. void UIT(){
    2. if(millis() - T > 1000){
    3. T = millis();
    4. WT = WT+W;
    5. Wh = WT/3.6;
    6. }
    7. }

    测量温度

    1. void NTC(){
    2. pinMode( wd , INPUT_ANALOG); //模拟量输入
    3. float r = map(analogRead(wd),0,4095,0,3270); //NTC采样
    4. float ntc = (10000 * r)/(3270 - r); //计算NTC值
    5. //K =(3950 * 298.15)/(3950 +(298.15 * log( ntc/ 10000)));
    6. C = (3950 * 298.15)/(3950 +(298.15 * log( ntc/10000))) - 273.15 - 4; //计算温度
    7. }

    0.96OLED显示

    显示样式
    1. void SSD1306(){
    2. display.clearDisplay(); //清理1306屏幕,准备显示:
    3. display.setTextColor(WHITE); //设置字体颜色
    4. display.setTextSize(2,2); //设置字体大小,(X,Y)比
    5. display.setCursor( 0 , 0 );
    6. display.print(V);
    7. display.setCursor(62, 0 );
    8. display.print("V");
    9. display.setCursor( 0 , 16 );
    10. display.print(A,3);
    11. display.setCursor( 62, 17 );
    12. display.print("A");
    13. display.setCursor( 0 , 33);
    14. display.print(W);
    15. display.setCursor( 62, 33);
    16. display.print("W");
    17. display.setCursor( 0 , 49);
    18. display.print(R);
    19. display.setCursor( 62, 49);
    20. display.print("R");
    21. display.setTextSize(1);
    22. display.setCursor( 81, 0 );
    23. display.print(C);
    24. display.setCursor(116, 0 );
    25. display.print("C*");
    26. display.setCursor( 81, 8 );
    27. display.print(VP);
    28. display.setCursor(116, 8 );
    29. display.print("D+");
    30. display.setCursor( 81, 17);
    31. display.print(VN);
    32. display.setCursor(116, 17);
    33. display.print("D-");
    34. display.setCursor( 81, 25);
    35. display.print(Wh);
    36. display.setCursor(110, 25);
    37. display.print("mWh");
    38. display.display(); //把缓存都显示
    39. }

    初始化

    1. void setup(){
    2. Serial.begin(9600);
    3. pinMode( a1 , INPUT_ANALOG);
    4. pinMode( a2 , INPUT_ANALOG);
    5. pinMode( dn , INPUT_ANALOG);
    6. pinMode( dp , INPUT_ANALOG);
    7. pinMode( wd , INPUT_ANALOG);
    8. pinMode( dy , INPUT_ANALOG);
    9. pinMode( k1 , INPUT_PULLUP);
    10. pinMode( k2 , INPUT_PULLUP);
    11. pinMode( k3 , INPUT_PULLUP);
    12. pinMode( k4 , INPUT_PULLUP);
    13. pinMode( M1, OUTPUT);
    14. pinMode( M2, OUTPUT);
    15. digitalWrite( M1 ,HIGH);
    16. digitalWrite( M2 ,LOW);
    17. display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //OLED通讯地址
    18. display.clearDisplay();
    19. }

    循环函数

    1. void loop(){
    2. VA(); //测量各种东西
    3. NTC(); //温度检测函数,应该加高温断电功能的!
    4. KEY(); //按键检测,没用上,相关函数没写
    5. if(millis() - i > 200){ //刷新
    6. i = millis();
    7. SSD1306();
    8. }
    9. }

    总结

    参考:Adafruit_SSD1306库学习_RenKaixuan0124的博客-CSDN博客_ssd1306库

    项目资源,来自于原作者负熵生之光

    链接:https://pan.baidu.com/s/1QG5SR7RUGEHU3qOS54ZcHg
    提取码:dj85

    本项目复刻起来比较容易,软件都是库,主要是硬件问题。

    🉑 ㊗️ 学会了电流检测的方法!很棒!!!!!!!!

    加油学习!!!

    都是自己分析开源项目的一些笔记,如果对您有些帮助,点点赞吧!

  • 相关阅读:
    CUDA指针数组Kernel函数
    基础算法练习200题10、合作工程
    【YOLOv7】使用 YOLOv7 做目标检测 (使用自己的数据集 + 图解超详细)
    cloudstack中ConsoleProxyManagerImpl
    C#【疑难杂症篇】CS0012:必须添加对程序集“netstandard, Version=2.0.0.0, Culture=neutral...”的引用
    同花顺自动化交易股票下单接口API量化系统,别信那些外挂插件和软件,头部券商有现成的接口
    软考系统架构之案例篇(Redis相关概念)
    Nestjs-cli通过命令行生成module无效问题处理
    Mac 部署 GPT-2 预训练模型 gpt2-chinese-cluecorpussmall
    10月最新H5自适应樱花导航网站源码SEO增强版
  • 原文地址:https://blog.csdn.net/qq_41650023/article/details/125854201