数码之家

 找回密码
 立即注册
搜索
查看: 572|回复: 6

[ARM] 有偿求助 使用TW32F003搭配BL0942读取电流电压

[复制链接]
发表于 2025-1-4 15:57:14 | 显示全部楼层 |阅读模式
本帖最后由 hwlin555 于 2025-1-4 17:34 编辑

有偿求助 使用TW32F003搭配BL0942读取电流电压,使用天问Block软件
始终不显示电流电压的数值,
已经确认串口收到了来自bl0942的数据55 00 00 00 76 06 00 CC EE 00 00 00 00 00 00 00 20 4E 00 02 03 00 A9

电流的单位A都显示了,应该是这个  %.2f 经过计算后的结果,或者计算的过程有问题,我搞不定了,请大师出手,解决问题给一包烟钱,望勿嫌弃
  sprintf(bufferC, "%.2f A", current);





  1. #define ST7789_USE_SPI_80_MODE 1
  2. #define ASC2_12
  3. #define ST7789_driver_command  0
  4. #define ASC2_32

  5. #include <TWEN32F0xx.h>
  6. #include "myLib/TW32f0xx_ST7789.h"
  7. #include "HardwareSerial.h"

  8. // 定义相关宏
  9. #define V_REF 1.218   // 内置参考电压 (V)
  10. #define RL_CURRENT 5     // 采样电阻 (毫欧),这里会影响屏幕显示的电流准确度,改为实际的阻值就好
  11. #define R2_VOLTAGE 2000    // 分压网络电阻 (K欧),确定了屏幕上显示的电压,可适当修改阻值让电压显示的正确范围
  12. #define R1_VOLTAGE 0.51    // 分压网络电阻 (K欧)
  13. #define SERIAL_RX_MAXLEN 23  // 串口接收数据缓冲区的最大长度

  14. ST7789 tftlcd_ST7789(240, 280, PA3, PA6, PA7, PB0, PF4, PF3);
  15. HardwareSerial *bl0942Serial = &Serial1; // 使用Serial1与BL0942通信

  16. // 串口接收数据数组
  17. static char serial_data[SERIAL_RX_MAXLEN];

  18. // 初始化BL0942芯片
  19. void Init_BL0942(void) {
  20.     bl0942Serial->begin(9600); // 初始化串口确定是9600
  21.     bl0942Serial->setTimeout(30); // 设置串口超时时间为30ms
  22.     memset(serial_data, 0, SERIAL_RX_MAXLEN);
  23. }

  24. // 发送命令给BL0942
  25. void sendCommand(void) {
  26.     bl0942Serial->write((byte)0x58);
  27.     bl0942Serial->write((byte)0xAA);
  28. }

  29. // 接收数据并校验
  30. void receiveData(void) {
  31.     static uint8_t data_index = 0;
  32.     static bool frame_start = false;

  33.     if (!frame_start) {
  34.         memset(serial_data, 0, SERIAL_RX_MAXLEN);
  35.     }

  36.     while (bl0942Serial->available()) {
  37.         char temp_data = bl0942Serial->read();

  38.         if (temp_data == 0x55) { // 判断帧头
  39.             frame_start = true;
  40.             data_index = 0;
  41.         }

  42.         if (frame_start && data_index < SERIAL_RX_MAXLEN) {
  43.             serial_data[data_index++] = temp_data;

  44.             if (data_index >= SERIAL_RX_MAXLEN) {
  45.                 frame_start = false;

  46.                 uint8_t checksum = 0;
  47.                 for (uint8_t i = 0; i < SERIAL_RX_MAXLEN - 1; i++) {
  48.                     checksum += serial_data[i];
  49.                 }
  50.                 checksum = ~checksum & 0xFF;

  51.                 if (checksum!= serial_data[SERIAL_RX_MAXLEN - 1]) {
  52.                     return;
  53.                 }
  54.             }
  55.         }
  56.     }
  57. }

  58. // 获取电流
  59. float getCurrent(void) {
  60.     uint32_t parm = ((uint32_t)serial_data[3] << 16) | ((uint32_t)serial_data[2] << 8) | serial_data[1];
  61.     float current = (float)parm * V_REF * 1000 / (305978 * RL_CURRENT);  // mA
  62.     return current / 1000; // 将mA转换为A
  63. }

  64. // 获取电压
  65. float getVoltage(void) {
  66.     uint32_t parm = ((uint32_t)serial_data[6] << 16) | ((uint32_t)serial_data[5] << 8) | serial_data[4];
  67.     float voltage = (float)parm * V_REF * (R2_VOLTAGE + R1_VOLTAGE) / (73989 * R1_VOLTAGE * 1000);
  68.     return voltage;
  69. }

  70. // 显示电压、电流
  71. void displayVoltageCurrentAndPower() {
  72.     float voltage = getVoltage();
  73.     float current = getCurrent();

  74.     // 设置光标位置并显示电压
  75.     tftlcd_ST7789.set_cursor(70, 22);
  76.     tftlcd_ST7789.set_text_color((0x6679),(0x00FF));
  77.     tftlcd_ST7789.set_text_size(32);
  78.     char bufferV[20];
  79.     sprintf(bufferV, "%.2f V", voltage);
  80.     tftlcd_ST7789.print(bufferV);

  81.     // 设置光标位置并显示电流
  82.     tftlcd_ST7789.set_cursor(70, 99);
  83.     tftlcd_ST7789.set_text_color((0x6679),(0x00FF));
  84.     tftlcd_ST7789.set_text_size(32);
  85.     char bufferC[20];
  86.     sprintf(bufferC, "%.2f A", current);
  87.     tftlcd_ST7789.print(bufferC);
  88. }

  89. int main(void) {
  90.     TW32F0xx_init();
  91.     tftlcd_ST7789.init();
  92.     Serial1.begin(9600); // 初始化串口1
  93.     tftlcd_ST7789.set_direction(2);
  94.     tftlcd_ST7789.clear((0x367F));

  95.     // 设置光标位置并绘制固定文本 "电压"
  96.     tftlcd_ST7789.set_cursor(5, 22);
  97.     tftlcd_ST7789.draw_hanzi_32("电压");

  98.     // 设置光标位置并绘制固定文本 "电流"
  99.     tftlcd_ST7789.set_cursor(5, 99);
  100.     tftlcd_ST7789.draw_hanzi_32("电流");

  101.     Init_BL0942(); // 初始化BL0942芯片

  102.     while (1) {
  103.         sendCommand(); // 发送指令
  104.         delay(100);    // 等待一段时间让BL0942响应
  105.         receiveData(); // 接收数据

  106.         displayVoltageCurrentAndPower(); // 显示电压、电流

  107.         delay(1000); // 延迟一秒后再次更新数据
  108.     }

  109.     return 1;
  110. }
复制代码








补充内容 (2025-1-5 20:42):
放弃了  改用ESP32搭配BL0942轻松实现显示电流电压,这个就不研究了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 2025-1-4 20:05:23 | 显示全部楼层
测试一下是数据有问题还是填充有问题:
(1)在sprintf前填充voltage为固定值,如:
  1.         voltage=12.3456;
  2.         sprintf(bufferV, "%.2f V", voltage);
复制代码
如果可以正常显示,说明voltage的计算值有问题。
(2)注释掉sprintf,手动填充显示缓冲区,如:
  1.         char bufferV[20];
  2.         //sprintf(bufferV, "%.2f V", voltage);
  3.         bufferV[0]='1';
  4.         bufferV[1]='2';
  5.         bufferV[2]='3';
  6.         bufferV[3]='.';
  7.         bufferV[4]='4';
  8.         bufferV[5]='5';
  9.         bufferV[6]='6';
  10.         bufferV[7]='V';
  11.         bufferV[8]=0;
  12.         bufferV[9]=0;
  13.         bufferV[10]=0;
  14.         bufferV[11]=0;
  15.         bufferV[12]=0;
  16.         bufferV[13]=0;
  17.         bufferV[14]=0;
  18.         bufferV[15]=0;
  19.         bufferV[16]=0;
  20.         bufferV[17]=0;
  21.         bufferV[18]=0;
  22.         bufferV[19]=0;
  23.         tftlcd_ST7789.print(bufferV);
复制代码
如果可以正常显示“123.456V”,则是sprintf有问题,如果不能正常显示,可能是tftlcd_ST7789.print有问题。



回复 支持 反对

使用道具 举报

发表于 2025-1-4 21:19:30 | 显示全部楼层
本帖最后由 vip2128 于 2025-1-4 21:36 编辑

液晶显示前先串口调试打印有没数据,或许取得的数据是空的,数据和数组定义改为全局变量
类似Serial.println(parm);     Serial.println(current);  Serial.print(voltage); Serial.println(bufferV); Serial.println(bufferC);
改为天问的串口打印代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-5 10:20:29 | 显示全部楼层
mmxx2015 发表于 2025-1-4 20:05
测试一下是数据有问题还是填充有问题:
(1)在sprintf前填充voltage为固定值,如:
如果可以正常显示,说 ...

感谢您的回复,使用以下代码写入以后仍然没有显示,看来就是你分析的是ST7789的问题了

// 获取电流
float getCurrent(void) {
    // 返回固定的电流值 12.345 A
    return 12.345;
}

// 获取电压
float getVoltage(void) {
    // 返回固定的电压值 12.345 V
    return 12.345;
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-5 10:22:47 | 显示全部楼层
vip2128 发表于 2025-1-4 21:19
液晶显示前先串口调试打印有没数据,或许取得的数据是空的,数据和数组定义改为全局变量
类似Serial.printl ...

感感谢你的回复
为了排查是没有收到数据,用手动填充将数据写入仍然无法显示,同样的BL0942数据用esp32带动同一块显示屏,显示一切正常,就是这个天问的ST7789有点老火,

// 手动填充串口接收数据数组
    const unsigned char testData[] = {0x55, 0x99, 0x00, 0x00, 0x76, 0x06, 0x00, 0xCC, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x4E, 0x00, 0x02, 0x03, 0x00, 0xA9};
    memcpy(serial_data, testData, sizeof(testData));
回复 支持 反对

使用道具 举报

发表于 2025-1-5 18:48:22 来自手机浏览器 | 显示全部楼层
直接  tftlcd_ST7789.print("123456");
看看能不能显示  123456
不能显示 去改这个显示函数
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-1-5 20:44:38 | 显示全部楼层
放弃了  改用ESP32搭配BL0942轻松实现显示电流电压,这个就不研究了

本想修改一下帖子,改不了了,只能在这里留言,如果班主看到,请删除这个帖子
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-6 03:07 , Processed in 0.109200 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表