最近的项目中用到了DAP_Link,但是原版STM32F103CBT6的Demo不太适用,于是基于该主控进行了一点修改。
操作系统:Windows 10
IDE:MDK 5.38
新建工程
自选一个路径,建议不要有中文和空格。
git clone https://github.com/ARMmbed/DAPLink #从github获取源码,需要先安装git,或者直接从github打包下载。
cd DAPLink
pip install virtualenv #此处需要Python3。
virtualenv venv
venv/Scripts/activate.bat #此处会进入venv环境。
pip install -r requirements.txt #安装需要的Python包。
progen generate -f projects.yaml -p stm32f103xb_bl -t uvision #生成BL的MDK工程。
progen generate -f projects.yaml -p stm32f103xb_if -t uvision #生成APP的MDK工程。
然后在 DAPLink\projectfiles\uvision 里面可以找到这两个工程。
分配IO
使用MDK打开工程,在左边”Project“栏里,打开 stm32f103xb_bl/default/IO_Config.h,该文件里定义了SWD、UART、LED的引脚。
//USB control pin
#define USB_CONNECT_PORT_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USB_CONNECT_PORT_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
#define USB_CONNECT_PORT GPIOA
#define USB_CONNECT_PIN GPIO_PIN_15
#define USB_CONNECT_ON() (USB_CONNECT_PORT->BSRR = USB_CONNECT_PIN)
#define USB_CONNECT_OFF() (USB_CONNECT_PORT->BRR = USB_CONNECT_PIN)
该段定义了USB的使能和失能,USB2.0有1.5Mbps、12Mbps、480Mbps三种速率,也分别称为低俗、全速和高速,对于低速模式,需要在D-信号线上接上拉电阻,对于全速模式,需要在D+信号线上接上拉电阻。该上拉电阻可以直接连接到3.3V,也可以连接到单片机的IO口上,通过IO控制上拉。从该处源码的定义来看,设计的是使用PA15控制上拉。但是实际上,查看很多DAP_Link的设计并未使用IO上拉而是直接上拉到3.3V。
//Connected LED
#define CONNECTED_LED_PORT GPIOB
#define CONNECTED_LED_PIN GPIO_PIN_6
#define CONNECTED_LED_PIN_Bit 6
//USB status LED
#define RUNNING_LED_PORT GPIOA
#define RUNNING_LED_PIN GPIO_PIN_9
#define RUNNING_LED_Bit 9
#define PIN_HID_LED_PORT GPIOA
#define PIN_HID_LED GPIO_PIN_9
#define PIN_HID_LED_Bit 9
#define PIN_CDC_LED_PORT GPIOA
#define PIN_CDC_LED GPIO_PIN_9
#define PIN_CDC_LED_Bit 9
#define PIN_MSC_LED_PORT GPIOA
#define PIN_MSC_LED GPIO_PIN_9
#define PIN_MSC_LED_Bit 9
以上是LED的定义部分,这个没有什么可讲的,可以任意分配,当不需要使用LED的时候,可以将其分配到无关的引脚上面。或者删减源码去掉LED功能。
//When bootloader, disable the target port(not used)
#define POWER_EN_PIN_PORT GPIOB
#define POWER_EN_PIN GPIO_PIN_15
#define POWER_EN_Bit 15
该段是定义了一个电源使能,意识是说当DAP处于Bootloader时关掉目标板的供电,但该功能只有定义,并没有实现。
// nRESET OUT Pin
#define nRESET_PIN_PORT GPIOB
#define nRESET_PIN GPIO_PIN_0
#define nRESET_PIN_Bit 0
这是DAP_Link对目标板的复位信号,可以使用任意IO,另外需要注意该引脚需要在板子上添加上拉电阻,因为DAP_Link上电检测到该引脚是低电平的话就会进入固件升级模式。
//SWD
#define SWCLK_TCK_PIN_PORT GPIOB
#define SWCLK_TCK_PIN GPIO_PIN_13
#define SWCLK_TCK_PIN_Bit 13
#define SWDIO_OUT_PIN_PORT GPIOB
#define SWDIO_OUT_PIN GPIO_PIN_14
#define SWDIO_OUT_PIN_Bit 14
#define SWDIO_IN_PIN_PORT GPIOB
#define SWDIO_IN_PIN GPIO_PIN_12
#define SWDIO_IN_PIN_Bit 12
最主要的部分,SWDIO和SWCLK,它是将SWDIO拆分成SWDIN和SWDOUT,分别作为数据输入输出。需要注意的是,很多DAP_Link将SWCLK同时接到了PA5和PB13,实际上PA5完全没用。因为SWD工作速度可以达到很高,所以只能使用PA和PB,不要使用PC的引脚。
修改RCC
原版工程使用的是8MHz的晶振,但是在我的工程中为了减少晶振数量,和别的IC共用了一个12MHz的有源晶振。在 stm32f103xb_bl/hic_hal/sdk.c 中可以修改RCC,在34行注释中标出了时钟配置:
/**
* @brief Switch the PLL source from HSI to HSE bypass, and select the PLL as SYSCLK
* source.
* The system Clock is configured as follow :
* System Clock source = PLL (HSE bypass)
* SYSCLK(Hz) = 72000000
* HCLK(Hz) = 72000000
* AHB Prescaler = 1
* APB1 Prescaler = 2
* APB2 Prescaler = 1
* HSE Frequency(Hz) = 8000000
* HSE PREDIV1 = 1
* PLLMUL = 9
* Flash Latency(WS) = 2
* @param None
* @retval None
*/
它是将8MHz的HSE通过PLLMUL之后x9得到72MHz的SYSCLK。若是将HSE换成12MHz,那么只需要将PLLMUL改为x6即可。修改 sdk.c 中的73行,将 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; 改为 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
串口
串口的定义和初始化在 stm32f103xb_bl/hic_hal/uart.c 中。
// For usart
#define CDC_UART USART2
#define CDC_UART_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
#define CDC_UART_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
#define CDC_UART_IRQn USART2_IRQn
#define CDC_UART_IRQn_Handler USART2_IRQHandler
#define UART_PINS_PORT_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define UART_PINS_PORT_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
#define UART_TX_PORT GPIOA
#define UART_TX_PIN GPIO_PIN_2
#define UART_RX_PORT GPIOA
#define UART_RX_PIN GPIO_PIN_3
#define UART_CTS_PORT GPIOA
#define UART_CTS_PIN GPIO_PIN_0
#define UART_RTS_PORT GPIOA
#define UART_RTS_PIN GPIO_PIN_1
原版中使用的USART2,PA2用作TXD,PA3用作RXD,不需要Remap,如果要使用别的引脚来作为UART2的TXD、RXD则不仅需要修改引脚号,还需要加上Remap。以上还定义并初始化了流控制的引脚,但源码中并没有启用流控制的功能,有需要的话可以自行修改。
串口我是使用的USART1,TXD是PB6,RXD是PB7,需要使用Remap。
// For usart
#define CDC_UART USART1
#define CDC_UART_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
#define CDC_UART_DISABLE() __HAL_RCC_USART1_CLK_DISABLE()
#define CDC_UART_IRQn USART1_IRQn
#define CDC_UART_IRQn_Handler USART1_IRQHandler
#define UART_PINS_PORT_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define UART_PINS_PORT_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
#define UART_TX_PORT GPIOB
#define UART_TX_PIN GPIO_PIN_6
#define UART_RX_PORT GPIOB
#define UART_RX_PIN GPIO_PIN_7
若是使用PA9 PA10作为USART1的TXD和RXD,仅需要修改以上部分,若是使用PB7、PB7,那么久需要在 114 行额外写上:
__HAL_AFIO_REMAP_USART1_ENABLE();
有时候画板子省事会懒得连复位引脚,使用软复位进行复位,但是在MDK中勾选了reset and run之后DAP的软复位似乎不起效,可以通过修改PIN_nRESET_OUT函数,使DAP输出复位信号时并进行软复位操作。在DAP_config.h中的430行:
/** nRESET I/O pin: Set Output.
\param bit target device hardware reset pin status:
- 0: issue a device hardware reset.
- 1: release device hardware reset.
*/
// TODO - sw specific implementation should be created
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
if (bit & 1)
nRESET_PIN_PORT->BSRR = nRESET_PIN;
else
nRESET_PIN_PORT->BRR = nRESET_PIN;
}
改为如下:
/** nRESET I/O pin: Set Output.
\param bit target device hardware reset pin status:
- 0: issue a device hardware reset.
- 1: release device hardware reset.
*/
// TODO - sw specific implementation should be created
extern uint8_t swd_write_word(uint32_t addr, uint32_t val);
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
if (bit & 1)
nRESET_PIN_PORT->BSRR = nRESET_PIN;
else
nRESET_PIN_PORT->BRR = nRESET_PIN;
swd_write_word((uint32_t)&SCB->AIRCR, ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk));
}
生成
DAP_Link的固件分为BL和APP两个部分,需要先给MCU烧录BL,然后再通过BL写入APP。BL和APP的配置的源文件都是同一个,所以在BL中修改了IO和RCC就不用在APP的工程中修改了。
编译 stm32f103xb_bl 工程,可以得到 stm32f103xb_bl.bin 。可以使用SWD或者UART烧录到MCU中。但是脚本生成的工程是旧版的,无法在MDK中点击Download按钮,需要点击”Project“-”Manage“-”Migrate to version 5 format“才行。
编译 stm32f103xb_if 工程,可以得到 stm32f103xb_if.bin 。此文件是APP,不能够直接用MDK中的Download,在MCU烧录 stm32f103xb_bl.bin 之后,会在资源管理器中出现一个”MAINTENANCE“的USB储存设备,将 stm32f103xb_if.bin 复制到该设备里面,几秒钟之后APP就写入完成。
注意事项
github上的DAP_link现在是V2的,MDK5.26及更新版本才能识别到V2的DAP_Link。
如果写入APP之后制作成功,但是重新连接之后又变成了MAINTENANCE,那就说明nRESET引脚被错误拉低了,检查是否有短路,或者缺失了上拉电阻。
参考图

参与讨论
(Participate in the discussion)
参与讨论
没有发现评论
暂无评论