# 前言
做之前信誓旦旦,这个小玩意,还不是分分钟拿捏???
做之后呢,分分钟被拿捏,真的是赢了李工那句话,这个东西说难不难,做好了却不容易。
真的是想做的很精确,的确真的是太难了,尤其电流测量,此话后说。
总之,越是看着简单的东西,做起来反而不是得心应手。
最后感谢各位大佬哦,感谢立创给我这个机会。这次是我最让我印象深刻的,坑太多了。
# 原理介绍
所谓功率计,就是计算电子产品的功耗。一般以瓦,毫瓦为单位。
需要测量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:控制显示屏幕
原理图如下:
![image.png](//image.lceda.cn/pullimage/mnzN2hjF6HlrDS7FSe1UyJpHD7EjADO9jj1lyqhn.png)
## 电源部分
虽然是USB功率计,想了想,万一需要测量电压更大的,所以选用LDO是也考虑了一下,选择了如下LDO
![image.png](//image.lceda.cn/pullimage/Ne2VcyXabTmqgPoHSMKmZO85hBBBz48YI9dup8zs.png)
最大支持12V输入。一般够用了。输出3.3V,最大800mA。这里也是为了以后自己多个固定输出3.3V的电压模块。
因此整体测量电压不要超过12V哦。
具体实现原理图如下:
![image.png](//image.lceda.cn/pullimage/GsNyH0BBFySTsCEmqVoivbFRi44wLhWHU1j27j06.png)
## 显示屏
显示屏选用了0.91寸的白字屏。128X32,可以显示四行。
接口和尺寸如下:
![image.png](//image.lceda.cn/pullimage/ZAXIjxLb0B6xgyD0G9jtv3NunNrUotpwasVIJAew.png)
这个是模块化的,内部电路如下,IIC不用上拉电阻了,模块自带。非常好用的。
![image.png](//image.lceda.cn/pullimage/EVtdHDuQep3xm7rygOloIyDLCslnIdBveQAX7jpa.png)
因此本项目原理图设计只需要预留接口即可,如下所示:
![image.png](//image.lceda.cn/pullimage/JHhfSN1HAO3UPkHzvvTgMaJpuYn0WTRdVBqrfxfK.png)
## 电压采集电路
这里为了节省成本,直接采用了分压电路,如下图所示
![image.png](//image.lceda.cn/pullimage/FaUzgSucAzaRzGnZPJvTAChf74MRTFoZBIZoBoDl.png)
注意:CW32社区建议VADC再接个电阻,我个人觉得有钱的话,自己用个运放电路就好,或者电压跟随电路,可以提高驱动能力,降低阻抗。这是个人建议。
VADC使用了PA1采样。
## 电流采集电路
这里通过串联小电阻的方式进行产生压降。然后使用TI的芯片INA199A3DCKR专门做电流感应放大器。这个有三种可选,我选择了200倍的。大家若是测量小电流的选择50或100倍的。对应的型号如下
![image.png](//image.lceda.cn/pullimage/zIemHPGgzSpQqUweeSE1OyK5YoPHW5fI6T6Lt57g.png)
我选择的这个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。千万不能再大。再大可能冒烟了。**
原理设计如下:
![image.png](//image.lceda.cn/pullimage/ayw5vwzyghzaDbNfhkAN5aFj2UrEyJA88Zq1BYnu.png)
## 指示灯
这里使用了彩灯,ws2812,最近比较流行个,比较炫酷,电路很简单,如下。
程序还没来得及写驱动,等第二版再更新软件吧。
![image.png](//image.lceda.cn/pullimage/5iexcBRABQGSKcnHpAbO4op5UryJsAHhcDODMuCO.png)
## 其它下载、复位、模式电路
这里只说一下复位电路,由于DAP调试,不能软复位,还是最好留下个复位硬件接口,或者直接跟下载器的RST连接,否则比较麻烦啊。
具体原理图如下:
![image.png](//image.lceda.cn/pullimage/eKHZ9T7RHJJQXWge8DamjrvsTMqj1300FsmmkE9A.png)
# 软件实现
也分成几个部分说明一下吧
## 显示部分
主要是IIC的驱动,SSD106直接参考官方初始化函数即可。
流程图如下
![image.png](//image.lceda.cn/pullimage/geMgEWAyYLCfHs04qDM1t3YdLHMOgqAkX5LrqJ1d.png)
![image.png](//image.lceda.cn/pullimage/3jrLzPnVdYDjrKMxEU1r9Fmw1B8fT64XjE7aYKb5.png)
OLED初始化函数如下:
![image.png](//image.lceda.cn/pullimage/mmnjFcxDELKvw4HQslSfD8DbUnHr0IkGNjC0cJ7g.png)
至于我们使用需要文字或图片,采用取模软件即可。
详细代码太长了,这里就不贴了。相关函数可以看下
![image.png](//image.lceda.cn/pullimage/aHaGERCPKYN5VCHOk43uJVEAHYlMr3pPzj28sHgP.png)
## ADC采集部分
这里使用了管脚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'\)
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
/\*\*
\* @brief ADC I/O初始化
\*
\*/
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;
\}
/\*\*
\* @brief 配置GPIO
\*
\*/
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\);
\}
/\*\*
\* @brief 配置UART
\*
\*/
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位数组
\*
\* @param 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
\* @return 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;
\}
效果如下:
![image.png](//image.lceda.cn/pullimage/8aIbB9JnXauVlIdo439D4ZtscI9Z9xgeP1QY0pXa.png)
## 主控函数
按照如下顺序执行
首先,初始化各种配置。时钟、GPIO、串口、屏幕配置等。
然后是数据采集和屏幕刷新循环进行,中间加了500ms的延时函数。
具体代码如下:
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
/\*\* \file main\.c
\*\*
\*\* A detailed description is available at
\*\* @link 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\);
\}
\}
/\*\*
\* @brief 配置RCC
\*
\*/
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 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%以上,各种不等吧。欢迎大家复刻然后进行电子负载进行对比实验。
关于功率整体还是比较准确的,用了进行大致的定量分析,还是比较方便的。
实际效果如下:
![image.png](//image.lceda.cn/pullimage/whNG7g4rPhmHqJNw8jadKhtPBrWzqV6fyidGa49Z.png)
由于文章长度有限制,只能贴核心代码了。不过第二版应该很快就出了。
着急复刻的,可以先使用附件的.hex文件。着急需要源码的联系我吧,不着急的请耐心等我更新第二版哦。
# 总结
第一次接触CW32的芯片,对CW32的芯片有了初步认识,后续的工作学习中会进一步学习和运用国产芯片。感谢这个平台,感谢CW32,希望国产芯片越做越好。
由于明天就要出差了,赶在今天弄完了(2023年11月18日19:18:00)。
第二板硬件已经到了了,来不及截止日前搞好第二板了,不管软件还是硬件都还有提升的空间,有兴趣的一起来DIY吧。
第二版直接做了PCB盖板效果应该好一些。为啥不打印壳?这还用问,都是太穷了哦。
![image.png](//image.lceda.cn/pullimage/VZOP4BUiGWXB2HWXVl8gkeZw52qb5j8pIIOf6HX6.png)
PCB盖板还没有到,先看个效果图吧
![image.png](//image.lceda.cn/pullimage/OogWLuo94DN7Rq5AoEz2eSIwJFdTz2CiV06fx7AJ.png)
![image.png](//image.lceda.cn/pullimage/yEWD4wLnqXNMGSiFLbWjOsv5xUyB6zdPmVHIaJQF.png)
# B站链接
## 空载效果
[https://www\.bilibili\.com/video/BV1T94y1H7KJ/?pop\_share=1&vd\_source=e36622a05269c0356d6cd566056a2488](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/BV1MH4y1q7Wp/?pop_share=1&vd_source=e36622a05269c0356d6cd566056a2488)
## 负载加湿器效果
[https://www\.bilibili\.com/video/BV1La4y1U74q/?pop\_share=1&vd\_source=e36622a05269c0356d6cd566056a2488](https://www.bilibili.com/video/BV1La4y1U74q/?pop_share=1&vd_source=e36622a05269c0356d6cd566056a2488)