[CW32F030系列] 【CW32F030FxPx StartKit开发板】+挂接电流传感器模块以及OLED

[复制链接]
 楼主| suncat0504 发表于 2024-6-8 20:48 | 显示全部楼层 |阅读模式
本帖最后由 suncat0504 于 2024-6-8 20:50 编辑

本次实验使用现成的电流传感器模块获取电流数据。模块用的是ACS758LCB霍尔电流模块,体积小。这个模块我买了很久,都没有做过实验,属于那种看了喜欢,想用了试试的那种。
图片1.png
提供以下几个接口:
1、5V
2、GND
3、TXD
4、VOUT
5、D-CMP
TXD是以9600波特率输出的数据。发送的两个字节的数据帧,BCD码模式。第一个字节的高四位,表示正负,A表示为正,B表示为负。低四位和第二个字节的高四位用来表示电流值的整数。第二个字节的低四位表示电流的小数位。
D-CMP用来接外部比较基准电压,VOUT是比较结果的输出。通过比较外部基准电压和采样电流模块的电压,来判断我们收集的电流是否超出了范围。如果超出范围,Vout会输出高电平,作为报警信号。
很明显,这个模块是用来测试直流更合适。考虑到用来控制可充电电池的充电的,因此用起来没问题。问题是这个模块的电流上限是30A,普通充电电池的电流不会这么大。能否适用于小电流的采样,只能通过实验来试试了。
因为暂时用不到4、5的比较输出功能,实际接线只需要1、2、3即可。在配合单片机操作之前,先看看模块的工作情况,只需要接入电源、地,连上串口接收模块。
图片2.png
板子上有一个发光管坏掉了,导致缺笔段,不影响观感。串口得到的结果:
图片3.png
A000,表示结果为正的0.0A;B001,表示为-0.1A,还不错。
使用芯源开发板的话,需要额外准备一个串口接收来自电流模块的数据。
根据手册和开发板的IO排针输出状况,
图片4.png
图片5.png
使用PA09作为串口接收用。为了调试程序以及显示测量结果,这里先接入一个OLED屏。为此建立一个工程,导入OLED的处理程序。
接下来,引入串口处理程序。串口使用中断方式,每采集到完整的两个字节的数据后,处理并显示到OLED上。
图片6.png
主程序中主要处理代码:
  1. uint8_t readbuff[32] = {'\0'};       // 串口接收缓冲区

  2. uint8_t procflag = 0;                // 处理中标志,遇到该标志,串口接收的数据暂时不保存到缓冲区中

  3. uint8_t readpos = 0;                 // 串口数据接收用指针





  4. void getTestResult(void) {

  5.     int8_t isok = 0;

  6.     uint8_t v1 = 0; // 整数部分

  7.     uint8_t v2 = 0; // 小数部分

  8.     char numstr[10]={'\0'};

  9.    



  10.     readbuff[2] = '\0';

  11.     if ((readbuff[0] & 0xA0) > 0) {

  12.         numstr[0]='A';

  13.         isok=1;

  14.     } else if ((readbuff[0] & 0xB0) > 0) {

  15.         // 负数

  16.         numstr[0]='B';

  17.         isok=-1;

  18.     }



  19.     if (isok != 0) {

  20.         numstr[1]=(readbuff[0]  & 0x0f)+48;

  21.         numstr[2]=((readbuff[1] &0xf0)>>4)+48;

  22.         numstr[3]=(readbuff[1]  & 0x0f)+48;

  23.         numstr[4]='\0';

  24.         GUI_ShowString(0, 0, (uint8_t*)numstr, 16, 1);

  25.         

  26.         // 正数

  27.         v1 = (readbuff[0]  & 0x0f) * 10;

  28.         v1 = v1+((readbuff[1] & 0xf0)>>4);

  29.         v2 = readbuff[1] & 0x0f;

  30.         

  31.         sprintf(numstr, "%2.1f", ((float)v1+0.1*v2) * isok);

  32.         GUI_ShowString(0, 16, (uint8_t*)numstr, 16, 1);

  33.     }

  34. }



  35. /**

  36. ******************************************************************************

  37. ** \brief  Main function of project

  38. **

  39. ** \return uint32_t return value, if needed

  40. **

  41. ******************************************************************************/

  42. int32_t main(void) {

  43.    

  44.    

  45.     //配置RCC

  46.     RCC_Configuration();



  47.     //配置GPIO

  48.     GPIO_Configuration();



  49.     //配置UART

  50.     UART_Configuration();



  51.     //配置NVIC

  52.     NVIC_Configuration();



  53.     //使能UARTx RC中断

  54.     USART_ITConfig(DEBUG_USARTx, USART_IT_RC, ENABLE);



  55.     //USART_SendString(DEBUG_USARTx, "\r\nCW32F030 UART Interrupt\r\n");



  56.     OLED_Init();

  57.     OLED_Clear(0);

  58.     //GUI_ShowString(0, 0, (uint8_t*)"Start test...", 8, 1);



  59.     while(1) {   

  60.         //中断收发

  61.         if (procflag == 1) {

  62.             // 收到两个自己字节的数据

  63.             getTestResult();

  64.             procflag=0;

  65.         

  66.         }

  67.     }

  68. }

串口的初始化代码:
  1. /**

  2. * [url=home.php?mod=space&uid=247401]@brief[/url] 配置GPIO

  3. *

  4. */

  5. void GPIO_Configuration(void) {

  6.     GPIO_InitTypeDef GPIO_InitStructure;



  7.     //UART TX RX 复用

  8.     DEBUG_USART_AFTX;                     

  9.     DEBUG_USART_AFRX;                     



  10.     GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN;

  11.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

  12.     GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;

  13.     GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);



  14.     GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN;

  15.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;

  16.     GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

  17.    

  18. }



  19. /**

  20. * [url=home.php?mod=space&uid=247401]@brief[/url] 配置UART

  21. *

  22. */

  23. void UART_Configuration(void) {

  24.   USART_InitTypeDef USART_InitStructure;



  25.   USART_InitStructure.USART_BaudRate = DEBUG_USART_BaudRate;

  26.   USART_InitStructure.USART_Over = USART_Over_16;

  27.   USART_InitStructure.USART_Source = USART_Source_PCLK;

  28.   USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq;

  29.   USART_InitStructure.USART_StartBit = USART_StartBit_FE;

  30.   USART_InitStructure.USART_StopBits = USART_StopBits_1;

  31.   USART_InitStructure.USART_Parity = USART_Parity_No ;

  32.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  33.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  34.   USART_Init(DEBUG_USARTx, &USART_InitStructure);         

  35. }



  36. /**

  37. * @brief 配置NVIC

  38. *

  39. */

  40. void NVIC_Configuration(void) {

  41.   //优先级,无优先级分组

  42.   NVIC_SetPriority(DEBUG_USART_IRQ, 0);

  43.   //UARTx中断使能

  44.   NVIC_EnableIRQ(DEBUG_USART_IRQ);

  45. }



  46. /**

  47. * @brief 发送字符串

  48. *

  49. * @param USARTx :USARTx外设

  50. *        参数可以是:

  51. *           CW_UART1、CW_UART2、CW_UART3

  52. * @param String :待发送的字符串

  53. */

  54. void USART_SendString(UART_TypeDef* USARTx, char *String) {

  55.   while(*String != '\0') {

  56.     USART_SendData_8bit(USARTx, *String);

  57.     while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

  58.     String++;

  59.   }

  60.   while(USART_GetFlagStatus(USARTx, USART_FLAG_TXBUSY) == SET);

  61. }


中断处理中的处理代码:
  1. /**

  2. * @brief This funcation handles UART1

  3. * 串口中断

  4. */

  5. void UART1_IRQHandler(void) {

  6.     /* USER CODE BEGIN */

  7.     uint8_t TxRxBuffer;

  8.     if(USART_GetITStatus(CW_UART1, USART_IT_RC) != RESET) {

  9.         // 接收串口数据

  10.         TxRxBuffer = USART_ReceiveData_8bit(CW_UART1);

  11.         if (procflag == 0) {

  12.             //USART_SendData_8bit(CW_UART1, TxRxBuffer);

  13.             if ((TxRxBuffer & 0xA0) > 0 || (TxRxBuffer & 0xB0) > 0) {

  14.                 readpos = 0;

  15.             }

  16.             readbuff[readpos] = TxRxBuffer;

  17.             readpos=(readpos+1)%2;

  18.             if (readpos == 0) {

  19.                 // 完成两个字节的接收, 建立接收完成标志

  20.                 procflag = 1;

  21.             }

  22.         }

  23.         //

  24.         USART_ClearITPendingBit(CW_UART1, USART_IT_RC);   

  25.     }

  26.   /* USER CODE END */

  27. }

下一步将接入实际测试电流做测试。


yangxiaor520 发表于 2024-6-10 09:21 来自手机 | 显示全部楼层
霍尔电流传感器的精度还是很高
 楼主| suncat0504 发表于 2024-6-10 10:19 | 显示全部楼层
就是不知道这个30A的量程,对于1A以下的测量是否精确。
小小蚂蚁举千斤 发表于 2024-6-11 15:57 | 显示全部楼层
确实30A的对于1A来比较确实比较大,但一般能测量出来有一定误差正常
AdaMaYun 发表于 2024-6-14 08:28 | 显示全部楼层
很不错的读取设计其实应该就是ADC读取转换
OKAKAKO 发表于 2024-6-21 21:18 | 显示全部楼层
电流传感器分辨率是多大?
 楼主| suncat0504 发表于 2024-6-22 10:31 | 显示全部楼层
OKAKAKO 发表于 2024-6-21 21:18
电流传感器分辨率是多大?

这个没注意。得查查那个电流传感器的芯片资料才行。我这里的测试上看,大概在100mA时产生0.02V的变化。
 楼主| suncat0504 发表于 2024-6-22 10:38 | 显示全部楼层
OKAKAKO 发表于 2024-6-21 21:18
电流传感器分辨率是多大?

从资料上看,给出的信息为:
Typical Sensitivity (mV/A) :264
和我实际测试结果来看,还是比较吻合的
中国龙芯CDX 发表于 2024-6-26 15:33 | 显示全部楼层
非常棒的应用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

158

主题

4504

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部
认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

158

主题

4504

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部