1.产品概述
HK32F103xCxDxE 系列使用ARM® Cortex®-M3 内核,最高工作频率120 MHz。
HK32F103xCxDxE 内置了大容量存储器:最高512Kbyte Flash、64 KbyteSRAM。此外,可通过FSMC 模块外挂最多1 Gbyte 容量的NOR/PSRAM/NAND/PC Card 存储器,其中有256 Mbyte 的空间可以存放指令,并且可以被片内1 Kbyte 指令Cache 缓存。
HK32F103xCxDxE 内置的CRC 模块提供了数据完整性的检查能力。
HK32F103xCxDxE 内置了丰富的通信接口满足多种通信应用场景:5 路USART/UART、3 路SPI(SPI2/3支持I2S 协议)、1 路SDIO、2 路I2C、1 路CAN 2.0 A/B 和1 路FS USB。
HK32F103xCxDxE 内置2 个高级16 位PWM 计时器(共8 路PWM 输出,其中6 路带死区互补输出),4 个通用16 位PWM 计时器(共16 路PWM 输出),2 个16 位的基本定时器。
HK32F103xCxDxE 提供独立的VBAT 电池电源域,当VDD 主电源掉电时,RTC 模块可在VBAT 供电下继续工作;另外,VBAT 电池电源域提供了84 Byte 的备份寄存器。
HK32F103xCxDxE 内置了丰富的模拟电路:3 个12 位ADC(支持最多16 路外部模拟输入通道同时使用,其中2 路弱驱动信号输入通道和1 路5V 高压信号输入通道)、2 个12 位DAC、1 个温度传感器、1个0.8V 内部参考电压源、1 个可编程电压检测器(PVD)、1 个上电/下电复位(POR/PDR)电路和1 个VBAT电源电阻分压器(分压器输出在片内与ADC 相连)。
HK32F103xCxDxE 支持丰富的功耗模式;在最低功耗模式下,芯片的典型漏电电流小于 100nA。 HK32F103xCxDxE 工作于-40°C 至+105°C 的温度范围,供电电压2.0V 至3 .6V,可满足绝大部分应用环境条件的要求。
完整的HK32F103xC、HK32F103xD 和HK32F103xE 系列产品包括从64 脚至100 脚的两种不同封装。根据不同的封装形式,器件中的外设配置有差异。
由于拥有丰富的外设配置,HK32F103xCxDxE MCU 可适用于多种应用场景:
• 工业应用,如可编程控制器、打印机、扫描仪等
• HMI 人机音视频多媒体交互
• 图形显示设备,如广告显示
• 语音识别设备
• 安全监控设备
• 电机驱动和调速控制
• 物联网低功耗传感器终端,如运动手环等
• 无人机飞控、云台控制
• 玩具产品
• 家用电器
• 智能机器人
• 智能手表
2.产品特性
• ARM® Cortex®-M3 内核
◦ 最高时钟频率:120 MHz
◦ 24 位System Tick 定时器
◦ 支持CPU Event 信号输入至MCU 引脚,实现与板级其它Soc CPU 的联动。
• 工作电压范围
◦ 双电源域:
- 主电源VDD 为2.0 V ~ 3.6 V
- 备份电源VBAT 为1.8 V ~ 3.6 V
◦ 当主电源掉电时,RTC 可继续工作在VBAT 电源下。
◦ VBAT 电源域提供84 byte 备份寄存器。
• 工作温度范围:-40°C ~ +105°C
• VDD 典型工作电流
◦ 运行(Run)模式:19.3 mA@120MHz@3 .3V
◦ 睡眠(Sleep)模式:5.6mA@120MHz@3 .3V(唤醒时间:1 个机器时钟周期)
◦ 停机(Stop)模式
- LDO 低功耗模式:89.4 μA@3 .3V(唤醒时间:10µs)
- LDO 全速工作模式:303 μA@3 .3V
◦ 待机(Standby)模式:3.3 μA@3 .3V(唤醒时间:150µs)
• VBAT 典型工作电流(VDD 掉电)
◦ VBAT RTC 开启模式:2.6 μA@3 .3V
◦ VBAT RTC 关闭模式:2.1 μA@3 .3V
• 存储器
◦ 最高512 Kbyte 的Flash 存储器
- 当CPU 主频不高于24 MHz 时,支持0 等待总线周期。
- 具有代码安全保护功能,可分别设置读保护和写保护。
◦ 64Kbyte 片内SRAM
◦ FSMC 模块可外挂1 Gbyte NOR/PSRAM/NAND/PC Card 存储器(其中,256 Mbyte 的空间可以存放指令,可用于片内Cache 缓存)
• 数据安全
◦ CRC32 校验硬件单元
• 时钟
◦ 外部高速时钟(HSE):支持4 ~ 32 MHz,典型8 MHz
◦ 外部低速时钟(LSE):32.768 kHz
◦ 片内高速时钟(HSI):8 MHz/28 MHz/56 MHz 可配置
◦ 片内低速时钟(LSI):40 kHz
◦ PLL 输出时钟:120MHz(最大值)
◦ GPIO 外部输入时钟:1 ~ 64 MHz
• 复位
◦ 外部管脚复位
◦ 电源复位(POR/PDR)
◦ 软件复位
◦ 看门狗(IWDG和WWDG)复位
◦ 低功耗管理复位
• 可编程电压检测器(PVD)
◦ 8 级检测电压门限可调
◦ 上升沿和下降沿检测可配置
• 通用输入输出端口(GPIO)
◦ 64 脚封装提供51 个GPIO 引脚,100 脚封装提供80 个GPIO 引脚
◦ 所有GPIO 引脚可配置为外部中断输入
◦ 内置可开关的上、下拉电阻
◦ 支持开漏(Open-Drain)输出
◦ 支持施密特(Schmitt)迟滞输入
◦ 输出驱动能力超高、高、中、低四档可选
• 数据通讯接口
◦ 5 路USART/UART(USART1/2/3,UART4/5)
◦ 3 路SPI(SPI2/3 支持I2S 协议)
◦ 2 路I2C
◦ 1 路SDIO
◦ 1 路CAN 2.0 A/2.0B
◦ 1 路全速USB2.0
• 定时器及PWM 发生器
◦ 高级定时器:TIM1/TIM8(带死区互补PWM 输出)
◦ 通用定时器:TIM2/TIM3/TIM4/TIM5
◦ 基本定时器:TIM6/TIM7(支持CPU 中断、DMA 请求和DAC 转换触发)
• 片内模拟电路
◦ 3 个12 位1 MSPS ADC(支持最多16 路外部模拟输入通道同时使用);支持双ADC 模式,采样率最高2 MSPS。
◦ 2 个12 位DAC
◦ 1 个温度传感器
◦ 1 个0.8 V 内部参考电压源
◦ 1 个VBAT 电源电阻分压器(分压器输出在片内与ADC 相连,实现VBAT 电源电压监控)
• DMA 控制器
◦ 2 个独立DMA:DMA1 和DMA2
◦ DMA1 提供7 路通道
◦ DMA2 提供5 路通道
◦ 支持Timer、ADC、SPI、I2C、USART、UART 等多种外设触发
• CPU 调试及跟踪接口
◦ SW-DP 两线调试端口
◦ JTAG 五线调试端口
◦ ARM DWT、FPB、ITM、TPIU 调试追踪模块
◦ 单线异步跟踪数据输出接口(TRACESWO)
◦ 四线同步跟踪数据输出接口(TRACEDO[3:0]、TRACECKO)
◦ 自定义DBGMCU 调试控制器(低功耗模式仿真控制、调试外设时钟控制、调试及跟踪接口分配)
3. 硬件原理图

4. 测评内容
产生6拍无刷电机控制开关波形:

无刷直流电机的换向控制原理
如下图示例 (A+ C-) \text{(A+ C-)}(A+ C-) 极通电导通时, 电流由 A 极流向 C 极, 这样形成了定子合成磁场. 永磁体转子会根据定子合成磁场的方向进行旋转. 下图仅示例一极对, 多极对利用电角度概念类 比实现. (电角度等于机械角度乘以极对数.)

通过对三相交替通电 (A+ C-) \text{(A+ C-)}(A+ C-), (A+ B-) \text{(A+ B-)}(A+ B-), (C+ B-) \text{(C+ B-)}(C+ B-), (C+ A-) \text{(C+ A-)}(C+ A-), (B+ A-) \text{(B+ A-)}(B+ A-), (B+ C-) \text{(B+ C-)}(B+ C-), 完成磁场旋转. 每一步只改变其中一极的导通状态, 共六步来完成定子合成磁场旋转一周, 即每步磁场旋转 60° —— 该方法被称为 “六步换向法”. 如下图所示六步换向法的基本原理:

为了实现定子磁场的旋转 (即六步换向), 需要交替有序地导通定子的三相电极. 而实现三相电极交替导通的驱动电路为三相全桥逆变电路, 控制上按照六步换向时序进行控制.

无刷直流电机的六步换向时序
六步换向法时序, 同一时间只有两相导通 (120° 导通), 另一相不导通 (悬空).
转子每转过 60° 电角度, 定子换向一次, 定子旋转磁场在一次换向后也变化 60° 电角度, 实现同步控制.
(我们这里演示的都是一极对, 电角度和几何角度一致)
每次换向只切换一个桥臂 (只切换一相), 使得切换控制较平稳. 故换向也有人称作换相.
如下所示是转子逆时针旋转时的六步换向时序图 (顺时针旋转时, 雷同).



无刷直流电机要实现六步换向时序控制, 需要通过检测 (反馈) 手段, 进行换向同步驱动控制.这里因为没有无刷电机驱动板,所以只进行了6拍控制波形生成测评;程序使用嘀嗒定时器产生com中断,进而在com中断函数中进行换相切换,切换开关状态如下:
The following Table describes the TIM1 Channels states:
-----------------------------------------------
| Step1 | Step2 | Step3 | Step4 | Step5 | Step6 |
----------------------------------------------------------
|Channel1 | 1 | 0 | 0 | 0 | 0 | 1 |
----------------------------------------------------------
|Channel1N | 0 | 0 | 1 | 1 | 0 | 0 |
----------------------------------------------------------
|Channel2 | 0 | 0 | 0 | 1 | 1 | 0 |
----------------------------------------------------------
|Channel2N | 1 | 1 | 0 | 0 | 0 | 0 |
----------------------------------------------------------
|Channel3 | 0 | 1 | 1 | 0 | 0 | 0 |
----------------------------------------------------------
|Channel3N | 0 | 0 | 0 | 0 | 1 | 1 |
定时器配置代码如下:
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 4095;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Channel 1, 2,3 and 4 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 2047;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = 1023;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = 511;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 1;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_CCPreloadControl(TIM1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE);
/* TIM1 counter enable */
TIM_Cmd(TIM1, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
Com中断函数如下:
void TIM1_TRG_COM_IRQHandler(void)
{
/* Clear TIM1 COM pending bit */
TIM_ClearITPendingBit(TIM1, TIM_IT_COM);
if (step == 1)
{
/* Next step: Step 2 Configuration ---------------------------- */
/* Channel3 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/* Channel1 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1 );
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
step++;
}
else if (step == 2)
{
/* Next step: Step 3 Configuration ---------------------------- */
/* Channel2 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
/* Channel3 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/* Channel1 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
step++;
}
else if (step == 3)
{
/* Next step: Step 4 Configuration ---------------------------- */
/* Channel3 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/* Channel2 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/* Channel1 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
step++;
}
else if (step == 4)
{
/* Next step: Step 5 Configuration ---------------------------- */
/* Channel3 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/* Channel1 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
/* Channel2 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
step++;
}
else if (step == 5)
{
/* Next step: Step 6 Configuration ---------------------------- */
/* Channel3 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
/* Channel1 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
step++;
}
else
{
/* Next step: Step 1 Configuration ---------------------------- */
/* Channel1 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/* Channel3 configuration */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
/* Channel2 configuration */
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
step = 1;
}
}
下面是逻辑分析仪显示的部分6拍波形(PA8/9/10引脚波形):


