做之前信誓旦旦,这个小玩意,还不是分分钟拿捏???
做之后呢,分分钟被拿捏,真的是赢了李工那句话,这个东西说难不难,做好了却不容易。
真的是想做的很精确,的确真的是太难了,尤其电流测量,此话后说。
总之,越是看着简单的东西,做起来反而不是得心应手。
最后感谢各位大佬哦,感谢立创给我这个机会。这次是我最让我印象深刻的,坑太多了。
所谓功率计,就是计算电子产品的功耗。一般以瓦,毫瓦为单位。
需要测量2个数据,第一是电压u,也就是电压降。
需要测量的第二个数据就是电流i.
那么功率P=u*i。原理就是这么简单哦。
看起来简单,做起来可不简单哦。
下面将整个电路进行分部介绍
这次选择是CW32F030C8T6。这个ARM M0内核的芯片有如下特点:
• 内核:ARM® Cortex®-M0+
最高主频 64MHz
• 工作温度:-40℃ 至 105℃;工作电压:1.65V 至 5.5V
• 存储容量
最大 64K 字节 FLASH,数据保持 25 年 @85℃
最大 8K 字节 RAM,支持奇偶校验
128 字节 OTP 存储器•
CRC 硬件计算单元
复位和电源管理
低功耗模式(Sleep,DeepSleep)
上电和掉电复位(POR/BOR)
可编程低电压检测器(LVD)
• 时钟管理
4 ~ 32MHz 晶体振荡器
32kHz 低速晶体振荡器
内置 48MHz RC 振荡器
内置 32kHz RC 振荡器
内置 10kHz RC 振荡器
内置 150kHz RC 振荡器
内置 PLL 锁相环
时钟监测系统
允许独立关断各外设时钟
• 支持最多 39 路 I/O 接口
所有 I/O 口支持中断功能
所有 I/O 支持中断输入滤波功能•
五通道 DMA 控制器
模数转换器
12 位精度,±1 LSB
最高 1M SPS 转换速度
内置电压参考
模拟看门狗功能
内置温度传感器
• 双路电压比较器
• 实时时钟和日历
支持由 Sleep/DeepSleep 模式唤醒
定时器
16 位高级控制定时器,支持 6 路捕获 / 比较通道和 3 对互补 PWM 输出,死区时间和灵活的同步功能
四组 16 位通用定时器
三组 16 位基本定时器
窗口看门狗定时器
独立看门狗定时器
• 通信接口
三路低功耗 UART,支持小数波特率
两路 SPI 接口 12Mbit/s
两路 I2C 接口 1Mbit/s
IR 调制器
串行调试接口 (SWD)
该芯片功耗低,封装多样,也是国产的,价格优惠,大家可以优先选用哦。
本项目使用管脚不多,主要是控制如下接口
ADC:采用电源、电流
串口:调试打印:
IIC:控制显示屏幕
原理图如下:
虽然是USB功率计,想了想,万一需要测量电压更大的,所以选用LDO是也考虑了一下,选择了如下LDO
最大支持12V输入。一般够用了。输出3.3V,最大800mA。这里也是为了以后自己多个固定输出3.3V的电压模块。
因此整体测量电压不要超过12V哦。
具体实现原理图如下:
显示屏选用了0.91寸的白字屏。128X32,可以显示四行。
接口和尺寸如下:
这个是模块化的,内部电路如下,IIC不用上拉电阻了,模块自带。非常好用的。
因此本项目原理图设计只需要预留接口即可,如下所示:
这里为了节省成本,直接采用了分压电路,如下图所示
注意:CW32社区建议VADC再接个电阻,我个人觉得有钱的话,自己用个运放电路就好,或者电压跟随电路,可以提高驱动能力,降低阻抗。这是个人建议。
VADC使用了PA1采样。
这里通过串联小电阻的方式进行产生压降。然后使用TI的芯片INA199A3DCKR专门做电流感应放大器。这个有三种可选,我选择了200倍的。大家若是测量小电流的选择50或100倍的。对应的型号如下
我选择的这个A3的200倍,配合CW32的ADC采用参考电压2.5V的,这个是CWF030内部配置,其实还有3.3V、1.5V供选择,那么我选择了2.5V。则最大电流
Imax=2.5/200/0.01=1.25A。对于常用的电脑USB口,这个值足够了。
若是大家觉得太大或者太小,可以选择不同的放大器配合不同的电压基准。比如我若选择3.3V,则Imax=1.65A了,那么测试小电流就没有准确了。范围越小测量越准,大家参考这个准则吧。
**根据之前的最大电压12V,因此这个带负载功率Pmax=12*1.25=15W。千万不能再大。再大可能冒烟了。**
原理设计如下:
这里使用了彩灯,ws2812,最近比较流行个,比较炫酷,电路很简单,如下。
程序还没来得及写驱动,等第二版再更新软件吧。
这里只说一下复位电路,由于DAP调试,不能软复位,还是最好留下个复位硬件接口,或者直接跟下载器的RST连接,否则比较麻烦啊。
具体原理图如下:
也分成几个部分说明一下吧
主要是IIC的驱动,SSD106直接参考官方初始化函数即可。
流程图如下
OLED初始化函数如下:
至于我们使用需要文字或图片,采用取模软件即可。
详细代码太长了,这里就不贴了。相关函数可以看下
这里使用了管脚PA1和PA2分别采集电压和电流,相关文件若需要修改的,最好看对着手册自己写吧,这里适合直接复刻。
在这部分,卡的太久了,各种不对,各种坑。总之,大家认真的对待吧。
相关配置函数如下:
#ifndef __ADC_H
#define __ADC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "base_types.h"
#include "cw32f030.h"
#include "system_cw32f030.h"
#include "interrupts_cw32f030.h"
#include "cw32f030_systick.h"
#include "cw32f030_rcc.h"
#include "cw32f030_gpio.h"
#include "cw32f030_adc.h"
extern uint16_t gAdcResult[4];
void ADC_Config(void);
uint8_t Gain_Value(void);
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H */
adc.c实现文件如下:
/******************************************************************************
Include files
******************************************************************************/
#include "adc.h"
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* USER CODE BEGIN EM */
/* 序列通道连续采样模式 */
//#define SQR_CONTINUOUS_MODE_EN
/* 序列通道扫描采样模式 */
#define SQR_SCAN_MODE_EN
/* 序列通道多次采样模式 */
//#define SQR_MORE_MODE_EN
/* 序列通道断续采样模式 */
//#define SQR_BREAK_MODE_EN
/* USER CODE END EM */
/******************************************************************************
Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/******************************************************************************
Local type definitions ('typedef')
******************************************************************************/
/******************************************************************************
Local function prototypes ('static')
******************************************************************************/
/******************************************************************************
Local variable definitions ('static') *
******************************************************************************/
uint16_t valueAdc;
uint16_t gAdcResult[4];
uint32_t valueAdcAcc;
volatile uint8_t gFlagIrq;
uint16_t gCntEoc = 0;
uint8_t cntSample;
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*****************************************************************************
Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*/
void ADC_PortInit(void)
{
//打开GPIO时钟
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk);
//打开ADC时钟
REGBITS_SET(CW_SYSCTRL->APBEN2, SYSCTRL_APBEN2_ADC_Msk);
//set PA01 as AIN1 INPUT
PA01_ANALOG_ENABLE();
//set PA02 as AIN2 INPUT
PA02_ANALOG_ENABLE();
// //set PA05 as AIN5 INPUT
// PA06_ANALOG_ENABLE();
// //set PA07 as AIN7 INPUT
// PA07_ANALOG_ENABLE();
}
void ADC2_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_SerialChTypeDef ADC_SerialChStructure;
//配置ADC测试IO口
ADC_PortInit();
//ADC初始化
// ADC_InitStructure.ADC_SampleTime=ADC_SampTime10Clk;
// ADC_InitStructure.ADC_VrefSel=ADC_Vref_BGR1p5;
ADC_StructInit(&ADC_InitStructure);
//ADC工作时钟配置
#ifdef SQR_BREAK_MODE_EN
ADC_InitStructure.ADC_ClkDiv = ADC_Clk_Div1;
#else
ADC_InitStructure.ADC_ClkDiv = ADC_Clk_Div16;
#endif
//ADC序列扫描转换模式配置
ADC_SerialChStructure.ADC_Sqr0Chmux = ADC_SqrCh1;//ADC_SqrVddaDiV3; //ADC_SqrCh1;
ADC_SerialChStructure.ADC_Sqr1Chmux = ADC_SqrCh2; //ADC_SqrCh2; //
// ADC_SerialChStructure.ADC_Sqr2Chmux = ADC_SqrCh6; //ADC_SqrCh5;
// ADC_SerialChStructure.ADC_Sqr3Chmux = ADC_SqrCh7;
ADC_SerialChStructure.ADC_SqrEns = ADC_SqrEns01;
ADC_SerialChStructure.ADC_InitStruct = ADC_InitStructure;
#ifdef SQR_CONTINUOUS_MODE_EN
/* 序列通道连续采样模式 */
ADC_SerialChContinuousModeCfg(&ADC_SerialChStructure);
ADC_ITConfig(ADC_IT_EOS, ENABLE);
#elif defined (SQR_SCAN_MODE_EN)
/* 序列通道扫描采样模式 */
ADC_SerialChScanModeCfg(&ADC_SerialChStructure);
ADC_ITConfig(ADC_IT_EOS, ENABLE);
#elif defined (SQR_MORE_MODE_EN)
/* 序列通道多次采样模式 */
cntSample = 0xFF; //转换次数为0xFF + 1次.
ADC_SerialChMoreModeCfg(&ADC_SerialChStructure, cntSample);
ADC_ITConfig(ADC_IT_EOC | ADC_IT_EOA, ENABLE);
#elif defined (SQR_BREAK_MODE_EN)
/* 序列通道断续采样模式 */
ADC_SerialChBreakModeCfg(&ADC_SerialChStructure);
ADC_ITConfig(ADC_IT_EOC | ADC_IT_EOS, ENABLE);
#else
#error "Please select ADC's running mode first in main.h!"
#endif
//ADC_ITConfig(ADC_IT_EOC | ADC_IT_EOS | ADC_IT_EOA, ENABLE);
ADC_EnableIrq(ADC_INT_PRIORITY);
ADC_ClearITPendingAll();
//ADC使能
ADC_Enable();
ADC_SoftwareStartConvCmd(ENABLE);
}
uint8_t Gain2_Value(void)
{
uint8_t temp=0;
#ifdef SQR_CONTINUOUS_MODE_EN
/* 序列通道连续采样模式 */
while (!(gFlagIrq & ADC_ISR_EOS_Msk));
gFlagIrq = 0u;
//while(!(gFlagIrq & ADC_ISR_EOS_Msk));
ADC_GetSqr0Result(gAdcResult);
ADC_GetSqr1Result(&gAdcResult[1]);
// ADC_GetSqr2Result(&gAdcResult[2]);
// ADC_GetSqr3Result(&gAdcResult[3]);
//printf("ch1:%5d-ch2:%5d-ch6:%5d-ch7:%5d\r\n",gAdcResult[0],gAdcResult[1],gAdcResult[2],gAdcResult[3]);
#elif defined (SQR_SCAN_MODE_EN)
/* 序列通道扫描采样模式 */
while (!(gFlagIrq & ADC_ISR_EOS_Msk));
gFlagIrq = 0u;
ADC_GetSqr0Result(gAdcResult);
ADC_GetSqr1Result(&gAdcResult[1]);
// ADC_GetSqr2Result(&gAdcResult[2]);
// ADC_GetSqr3Result(&gAdcResult[3]);
//printf("ch1:%5d-ch2:%5d-ch6:%5d-ch7:%5d\r\n",gAdcResult[0],gAdcResult[1],gAdcResult[2],gAdcResult[3]);
#elif defined (SQR_MORE_MODE_EN)
/* 序列通道多次采样模式 */
while (!(gFlagIrq & ADC_ISR_EOA_Msk));
gFlagIrq = 0u;
ADC_GetSqr0Result(gAdcResult); //Get data.
ADC_GetSqr1Result(&gAdcResult[1]);
// ADC_GetSqr2Result(&gAdcResult[2]);
// ADC_GetSqr3Result(&gAdcResult[3]);
ADC_GetAccResult(&valueAdcAcc);
if (gCntEoc != (cntSample + 1))
{
temp=1;
}
//printf("ch1:%5d-ch2:%5d-ch6:%5d-ch7:%5d\r\n",gAdcResult[0],gAdcResult[1],gAdcResult[2],gAdcResult[3]);
gCntEoc = 0u;
#elif defined (SQR_BREAK_MODE_EN)
/* 序列通道断续采样模式 */
while (!(gFlagIrq & ADC_ISR_EOC_Msk));
gFlagIrq &= (~ADC_ISR_EOC_Msk);
if (gFlagIrq & ADC_ISR_EOS_Msk)
{
gFlagIrq = 0u;
ADC_GetSqr0Result(gAdcResult);
ADC_GetSqr1Result(&gAdcResult[1]);
// ADC_GetSqr2Result(&gAdcResult[2]);
// ADC_GetSqr3Result(&gAdcResult[3]);
//printf("ch1:%5d-ch2:%5d-ch6:%5d-ch7:%5d\r\n",gAdcResult[0],gAdcResult[1],gAdcResult[2],gAdcResult[3]);
}
#endif
#ifndef SQR_CONTINUOUS_MODE_EN
ADC_SoftwareStartConvCmd(ENABLE); //启动下一次ADC转换
#endif
return temp;
}
为了实现调试方便,实现串口1,print输出等。
实现函数如下
/******************************************************************************
Include files
******************************************************************************/
#include "uart1.h"
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
//UARTx
#define DEBUG_USARTx CW_UART1
#define DEBUG_USART_CLK RCC_APB2_PERIPH_UART1
#define DEBUG_USART_APBClkENx RCC_APBPeriphClk_Enable2
#define DEBUG_USART_UclkFreq 8000000
//UARTx GPIO
#define DEBUG_USART_GPIO_CLK RCC_AHB_PERIPH_GPIOA
#define DEBUG_USART_TX_GPIO_PORT CW_GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_PIN_8
#define DEBUG_USART_RX_GPIO_PORT CW_GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_PIN_9
//GPIO AF
#define DEBUG_USART_AFTX PA08_AFx_UART1TXD()
#define DEBUG_USART_AFRX PA09_AFx_UART1RXD()
/******************************************************************************
Local variable definitions ('static') *
******************************************************************************/
#ifdef GNUC
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* GNUC */
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
/**
@brief Retargets the C library printf function to the USART.
*/
PUTCHAR_PROTOTYPE
{
USART_SendData_8bit(DEBUG_USARTx, (uint8_t)ch);
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return ch;
}
/**
*/
void UART1_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC\\_AHBPeriphClk\\_Enable\\(DEBUG\\_USART\\_GPIO\\_CLK\\, ENABLE\\);
DEBUG_USART_APBClkENx(DEBUG_USART_CLK, ENABLE);
//UART TX RX 复用
DEBUG_USART_AFTX;
DEBUG_USART_AFRX;
GPIO_InitStructure.Pins = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pins = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
}
/**
*/
void UART1_Configuration(uint32_t BaudRate)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = BaudRate;
USART_InitStructure.USART_Over = USART_Over_16;
USART_InitStructure.USART_Source = USART_Source_PCLK;
USART_InitStructure.USART_UclkFreq = DEBUG_USART_UclkFreq;
USART_InitStructure.USART_StartBit = USART_StartBit_FE;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(DEBUG_USARTx, &USART_InitStructure);
}
/**
@brief 发送8位数组
[url=home.php?mod=space&uid=3142012]@param[/url] USARTx :USARTx外设
参数可以是:
CW_UART1、CW_UART2、CW_UART3
@param TxBuf :待发送的数组
@param TxCnt :待发送的数组元素个数
*/
void UART1_SendBuf_Polling(uint8_t *TxBuf, uint8_t TxCnt)
{
while (TxCnt)
{
USART_SendData_8bit(CW_UART1, *TxBuf);
while (USART_GetFlagStatus(CW_UART1, USART_FLAG_TXE) == RESET);
TxBuf++;
TxCnt--;
}
while (USART_GetFlagStatus(CW_UART1, USART_FLAG_TXBUSY) == SET);
}
/**
@brief 接收8位数组
@param USARTx :USARTx外设
参数可以是:
CW_UART1、CW_UART2、CW_UART3
@param RxBuf :接收Buf
[url=home.php?mod=space&uid=1141835]@Return[/url] uint8_t :接收的字符个数
*/
uint8_t UART1_RecvBuf_Polling(uint8_t *RxBuf)
{
uint8_t RxCnt = 0;
do
{
//等待RC
while (USART_GetFlagStatus(CW_UART1, USART_FLAG_RC) == RESET);
//清RC
USART_ClearFlag(CW_UART1, USART_FLAG_RC);
//ERROR: PE or FE
if (USART_GetFlagStatus(CW_UART1, USART_FLAG_PE | USART_FLAG_FE))
{
USART_ClearFlag(CW_UART1, USART_FLAG_PE | USART_FLAG_FE);
RxCnt = 0x00;
}
else
{
RxBuf[RxCnt] = USART_ReceiveData_8bit(CW_UART1);
RxCnt++;
}
}
while (RxBuf[RxCnt - 1] != '\n');
return RxCnt;
}
效果如下:
按照如下顺序执行
首先,初始化各种配置。时钟、GPIO、串口、屏幕配置等。
然后是数据采集和屏幕刷新循环进行,中间加了500ms的延时函数。
具体代码如下:
/******************************************************************************/
/** \file main.c
**
** A detailed description is available at
** [url=home.php?mod=space&uid=41289]@Link[/url] Sample Group Some description @endlink
**
** - 2021-03-12 1.0 xiebin First version for Device Driver Library of Module.
**
******************************************************************************/
/*******************************************************************************
*******************************************************************************/
/******************************************************************************
Include files
******************************************************************************/
#include "main.h"
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
/******************************************************************************
Global variable definitions (declared in header file with 'extern')
******************************************************************************/
extern uint16_t gAdcResult[4];
/******************************************************************************
Local type definitions ('typedef')
******************************************************************************/
/******************************************************************************
Local function prototypes ('static')
******************************************************************************/
/******************************************************************************
Local variable definitions ('static') *
******************************************************************************/
uint8_t TxRxBufferSize;
uint8_t TxRxBuffer[] = "\r\nCW32F030 UART Polling\r\n";
/******************************************************************************
Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*****************************************************************************
Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
** \brief Main function of project
**
** \return uint32_t return value, if needed
**
******************************************************************************/
int32_t main(void)
{
uint8_t flag=0;
float x,y,z;
//char s[20];
//SYSCLK = HSI = 8MHz = HCLK = PCLK
RCC_HSI_Enable(RCC_HSIOSC_DIV6);
//配置GPIO
UART1_GPIO_Configuration();
//配置UART
UART1_Configuration(9600);
OLED_Init(); //初始化OLED
OLED_Clear();
OLED\\_ShowString\\(20\\,1\\,"My Power Calc"\\,8\\,1\\);//6\\*8
UART1_SendBuf_Polling(TxRxBuffer, ARRAY_SZ(TxRxBuffer) - 1);
for(uint8_t i=0;i<3;i++)
{
delay1ms(500);
printf("hello kwin\r\n");
}
ADC2_Config();
while (1)
{
char s[20];
flag=Gain2_Value();
if(!flag)
{
printf\\("\\r\\nch1:%5d\\-ch2:%5d\\-ch6:%5d\\-ch7:%5d\\r\\n"\\,gAdcResult\\[0\\]\\,gAdcResult\\[1\\]\\,gAdcResult\\[2\\]\\,gAdcResult\\[3\\]\\);
//printf\\("ch1:%5d\\r\\n"\\,gAdcResult\\[0\\]\\);
x=gAdcResult\\[0\\]/4095\\.0\\*25;
sprintf\\(s\\,"U=%6\\.3fV"\\,x\\);
printf\\("\\r\\nU=%6\\.3fV\\n"\\,x\\);
OLED\\_ShowString\\(40\\,9\\,s\\,8\\,1\\);//6\\*8
//printf\\("ch2=%5d\\r\\n"\\,gAdcResult\\[1\\]\\);
y=gAdcResult\\[1\\]/4095\\.0\\*1\\.25;
sprintf\\(s\\,"I=%6\\.3fA"\\,y\\);
printf\\("I=%6\\.3fA\\r\\n"\\,y\\);
OLED\\_ShowString\\(40\\,17\\,s\\,8\\,1\\);//6\\*8
z=x\\*y;
sprintf\\(s\\,"P=%6\\.3fW"\\,z\\);
OLED\\_ShowString\\(40\\,25\\,s\\,8\\,1\\);//6\\*8
\\}else\\{printf\\("Get Value failed \\r\\n"\\);\\}
OLED\\_DrawLine\\(0\\,0\\,127\\,0\\,1\\);
OLED\\_DrawLine\\(127\\,0\\,127\\,31\\,1\\);
OLED\\_DrawLine\\(0\\,0\\,0\\,31\\,1\\);
OLED\\_DrawLine\\(0\\,31\\,127\\,31\\,1\\);
OLED\\_DrawLine\\(0\\,31\\,127\\,31\\,1\\);
//OLED\\_DrawCircle\\(63\\,31\\,16\\);
OLED_Refresh();
delay1ms(500);
}
}
/**
*/
/******************************************************************************
EOF (not truncated)
******************************************************************************/
#ifdef USE_FULL_ASSERT
/**
@brief Reports the name of the source file and the source line number
where the assert_param error has occurred.
@param file: pointer to the source file name
@param line: assert_param error line source number
@retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
测试效果:
首先电压部分:测量比较准确,我这里采用单次测量,多次平均效果会更好,能稳定在mV级别的,别问我是怎么知道的,除了上面展示的代码,我还有各种残缺版本的,反正对精度进行了很深入的对比。
其次电流部分:这个在10个mA的情况下不是很准,100ma以上可以到1%的误差,100mA以下,可能在5%以上,各种不等吧。欢迎大家复刻然后进行电子负载进行对比实验。
关于功率整体还是比较准确的,用了进行大致的定量分析,还是比较方便的。
实际效果如下:
由于文章长度有限制,只能贴核心代码了。不过第二版应该很快就出了。
着急复刻的,可以先使用附件的.hex文件。着急需要源码的联系我吧,不着急的请耐心等我更新第二版哦。
第一次接触CW32的芯片,对CW32的芯片有了初步认识,后续的工作学习中会进一步学习和运用国产芯片。感谢这个平台,感谢CW32,希望国产芯片越做越好。
由于明天就要出差了,赶在今天弄完了(2023年11月18日19:18:00)。
第二板硬件已经到了了,来不及截止日前搞好第二板了,不管软件还是硬件都还有提升的空间,有兴趣的一起来DIY吧。
第二版直接做了PCB盖板效果应该好一些。为啥不打印壳?这还用问,都是太穷了哦。
PCB盖板还没有到,先看个效果图吧
空载效果
https://www.bilibili.com/video/BV1T94y1H7KJ/?pop_share=1&vd_source=e36622a05269c0356d6cd566056a2488
负载梁山派效果
https://www.bilibili.com/video/BV1MH4y1q7Wp/?pop_share=1&vd_source=e36622a05269c0356d6cd566056a2488
负载加湿器效果
https://www.bilibili.com/video/BV1La4y1U74q/?pop_share=1&vd_source=e36622a05269c0356d6cd566056a2488
更多回帖