AT32F423芯片系列
雅特力科技AT32F423系列超值型ARM®Cortex®-M4F微控制器,高达150MHz的CPU运算速度与内建的单精度浮点运算单元(FPU)、数字信号处理器(DSP),多达256KB闪存存储器(Flash)及48KB随机存取存储器(SRAM),而系统存储器(20KB)除可作启动加载程序(Bootloader)外,也可一次性配置成一般用户程序和数据区,达到256+20KB的最大空间使用。片上丰富的外设资源,用以加强连接性,集成XMC接口(拓展PSRAM,NOR存储器,或8080/6800模式并行LCD)、1个OTG控制器(设备模式支持无晶振Xtal-less)、2组CAN总线、8个UART、3个SPI/I²S(可组合全双工模式)、3个I²C、1个16位高级定时器、8个16位通用定时器、1个32位通用定时器、2个16位基本定时器。1个采样率高达5.33Msps的12位24通道高速ADC与2个12位DAC,为支持混合信号控制提供更高的性价比。几乎所有I/O口可容忍5V输入信号,且所有I/O口均为快速I/O,具有多种可选功能还支持端口重映射,提供绝佳性能和成本竞争力优势。
AT32F423可运行于工业级温度范围-40~105°C,并因应多样的内存需求,提供一系列不同的封装类型选择。其丰富的片上资源分配、高集成及高性价比展现极佳灵活性,提供安全且先进的应用服务,以满足各类需求,特别适用于工业自动化(Industrial Automation)、电机控制(Motor Control)、物联网(IoT)及消费性电子(Consumer Electronics)等。
开发板资源
官网资料 https://www.arterytek.com/cn/product/AT32F423.jsp
主要使用到就是 AT32F423数据手册,AT32F423用户参考手册,AT32F423开发板硬件原理图
环境搭建流程参考
基本上大多数的工程模板都是采用MDK-KEIL开发的,一般开发人员都安装好了,基本上没有啥子好说的。
基本上只要安装这个pack包就可以了。ArteryTek.AT32F423_DFP.pack
- at_start_f423 包含大量开发例程,其中examples是各个外设案例demo,template是各个开发工具的工程模板,而且支持工具版本比较多,这一点是在其他国产mcu例程资料比较少的,绝大多数都是清一色的MDK-KEIL,其次就是IAR工程,像官方的at32_ide,gcc工程模板是比较有特色的。
2. 学习外设参考案例 (adc,dac,gpio,timer,i2c,spi,can等) 在这里我们选择了uart的串口打印printf工程作为开发模板
3. 打开uart_printf工程,编译代码,编译0错误0警告。
at32的uart_printf工程模板的整体命名风格其实和我个人的风格比较相似,所以好感度比较高。
工程模板架构修改如下:
application 主函数,应用层代码
bspdrivers 板级模块动文件
librarys 底层驱动库文件 Firmware Library
middlewares 中间件库文件(FreeRTOS,fatfs等)
module drivers 模块驱动文件
project 工程文件
准备下载代码
板子板载了AT-link(本质上就是DAP),不需要其他的工具,很方便的就下载程序了。
板载AT-link原理图,直接Type-C数据线接上就行了,就可以直接下载程序了观察开发板现象.
4. 打开usart_printf工程,测试串口打印功能
/**
**************************************************************************
* @file main.c
* @brief main program
**************************************************************************
**/
#include "main.h"
static void hardware_init(void)
{
system_clock_config();
at32_board_init();
uart_print_init(115200);
}
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
hardware_init();
printf("Hardware_Init [ok] \r\n");
printf("at_start_f423 board testing 2024-08-03 [ok] \r\n");
printf("at_start_f423 board usart-printf [ok] \r\n");
while(1)
{
at32_led_toggle(LED2);
printf("at_start_f423 board at32_led_toggle [ok] \r\n");
}
}
#include "at32f423_board.h"
/* delay macros */
#define STEP_DELAY_MS 50
/* at-start led resouce array */
gpio_type *led_gpio_port[LED_NUM] = {LED2_GPIO, LED3_GPIO, LED4_GPIO};
uint16_t led_gpio_pin[LED_NUM] = {LED2_PIN, LED3_PIN, LED4_PIN};
crm_periph_clock_type led_gpio_crm_clk[LED_NUM] = {LED2_GPIO_CRM_CLK, LED3_GPIO_CRM_CLK, LED4_GPIO_CRM_CLK};
/* delay variable */
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
/* support printf function, usemicrolib is unnecessary */
#if (__ARMCC_VERSION > 6000000)
__asm (".global __use_no_semihosting\n\t");
void _sys_exit(int x)
{
x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{
ch = ch;
}
FILE __stdout;
#else
#ifdef __CC_ARM
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{
ch = ch;
}
#endif
#endif
#if defined (__GNUC__) && !defined (__clang__)
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/**
* @brief retargets the c library printf function to the usart.
* @param none
* @retval none
*/
PUTCHAR_PROTOTYPE
{
while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);
usart_data_transmit(PRINT_UART, (uint16_t)ch);
while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET);
return ch;
}
#if (defined (__GNUC__) && !defined (__clang__)) || (defined (__ICCARM__))
#if defined (__GNUC__) && !defined (__clang__)
int _write(int fd, char *pbuffer, int size)
#elif defined ( __ICCARM__ )
#pragma module_name = "?__write"
int __write(int fd, char *pbuffer, int size)
#endif
{
for(int i = 0; i < size; i ++)
{
while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);
usart_data_transmit(PRINT_UART, (uint16_t)(*pbuffer++));
while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET);
}
return size;
}
#endif
/**
* @brief initialize uart
* @param baudrate: uart baudrate
* @retval none
*/
void uart_print_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
#if defined (__GNUC__) && !defined (__clang__)
setvbuf(stdout, NULL, _IONBF, 0);
#endif
/* enable the uart and gpio clock */
crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE);
crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE);
gpio_default_para_init(&gpio_init_struct);
/* condiv the uart tx pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct);
gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM);
/* condiv uart param */
usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(PRINT_UART, TRUE);
usart_enable(PRINT_UART, TRUE);
}
/**
* @brief board initialize interface init led and button
* @param none
* @retval none
*/
void at32_board_init()
{
/* initialize delay function */
delay_init();
/* condiv led in at_start_board */
at32_led_init(LED2);
at32_led_init(LED3);
at32_led_init(LED4);
at32_led_off(LED2);
at32_led_off(LED3);
at32_led_off(LED4);
/* condiv button in at_start board */
at32_button_init();
}
/**
* @brief condiv button gpio
* @param button: specifies the button to be condivd.
* @retval none
*/
void at32_button_init(void)
{
gpio_init_type gpio_init_struct;
/* enable the button clock */
crm_periph_clock_enable(USER_BUTTON_CRM_CLK, TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* condiv button pin as input with pull-up/pull-down */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = USER_BUTTON_PIN;
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
gpio_init(USER_BUTTON_PORT, &gpio_init_struct);
}
/**
* @brief returns the selected button state
* @param none
* @retval the button gpio pin value
*/
uint8_t at32_button_state(void)
{
return gpio_input_data_bit_read(USER_BUTTON_PORT, USER_BUTTON_PIN);
}
/**
* @brief returns which button have press down
* @param none
* @retval the button have press down
*/
button_type at32_button_press()
{
static uint8_t pressed = 1;
/* get button state in at_start board */
if((pressed == 1) && (at32_button_state() != RESET))
{
/* debounce */
pressed = 0;
delay_ms(10);
if(at32_button_state() != RESET)
return USER_BUTTON;
}
else if(at32_button_state() == RESET)
{
pressed = 1;
}
return NO_BUTTON;
}
/**
* @brief condiv led gpio
* @param led: specifies the led to be condivd.
* @retval none
*/
void at32_led_init(led_type led)
{
gpio_init_type gpio_init_struct;
/* enable the led clock */
crm_periph_clock_enable(led_gpio_crm_clk[led], TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* condiv the led gpio */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pins = led_gpio_pin[led];
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(led_gpio_port[led], &gpio_init_struct);
}
/**
* @brief turns selected led on.
* @param led: specifies the led to be set on.
* this parameter can be one of following parameters:
* @arg LED2
* @arg LED3
* @arg LED4
* @retval none
*/
void at32_led_on(led_type led)
{
if(led > (LED_NUM - 1))
return;
if(led_gpio_pin[led])
led_gpio_port[led]->clr = led_gpio_pin[led];
}
/**
* @brief turns selected led off.
* @param led: specifies the led to be set off.
* this parameter can be one of following parameters:
* @arg LED2
* @arg LED3
* @arg LED4
* @retval none
*/
void at32_led_off(led_type led)
{
if(led > (LED_NUM - 1))
return;
if(led_gpio_pin[led])
led_gpio_port[led]->scr = led_gpio_pin[led];
}
/**
* @brief turns selected led toggle.
* @param led: specifies the led to be set off.
* this parameter can be one of following parameters:
* @arg LED2
* @arg LED3
* @arg LED4
* @retval none
*/
void at32_led_toggle(led_type led)
{
if(led > (LED_NUM - 1))
return;
if(led_gpio_pin[led])
led_gpio_port[led]->togr = led_gpio_pin[led];
}
/**
* @brief initialize delay function
* @param none
* @retval none
*/
void delay_init()
{
/* condiv systick */
systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
fac_us = system_core_clock / (1000000U);
fac_ms = fac_us * (1000U);
}
/**
* @brief inserts a delay time.
* @param nus: specifies the delay time length, in microsecond.
* @retval none
*/
void delay_us(uint32_t nus)
{
uint32_t temp = 0;
SysTick->LOAD = (uint32_t)(nus * fac_us);
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
/**
* @brief inserts a delay time.
* @param nms: specifies the delay time length, in milliseconds.
* @retval none
*/
void delay_ms(uint16_t nms)
{
uint32_t temp = 0;
while(nms)
{
if(nms > STEP_DELAY_MS)
{
SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms);
nms -= STEP_DELAY_MS;
}
else
{
SysTick->LOAD = (uint32_t)(nms * fac_ms);
nms = 0;
}
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
}
/**
* @brief inserts a delay time.
* @param sec: specifies the delay time, in seconds.
* @retval none
*/
void delay_sec(uint16_t sec)
{
uint16_t index;
for(index = 0; index < sec; index++)
{
delay_ms(500);
delay_ms(500);
}
}
#ifndef __AT32F423_BOARD_H
#define __AT32F423_BOARD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "at32f423.h"
/**
* this header include define support list:
* 1. at-start-f423 v1.x board
* if define AT_START_F423_V1, the header file support at-start-f423 v1.x board
*/
#if !defined (AT_START_F423_V1)
#error "please select first the board at-start device used in your application (in at32f423_board.h file)"
#endif
/******************** define led ********************/
typedef enum
{
LED2 = 0,
LED3 = 1,
LED4 = 2
}led_type;
#define LED_NUM 3
#if defined (AT_START_F423_V1)
#define LED2_PIN GPIO_PINS_13
#define LED2_GPIO GPIOD
#define LED2_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#define LED3_PIN GPIO_PINS_14
#define LED3_GPIO GPIOD
#define LED3_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#define LED4_PIN GPIO_PINS_15
#define LED4_GPIO GPIOD
#define LED4_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#endif
/**************** define print uart ******************/
#define PRINT_UART USART1
#define PRINT_UART_CRM_CLK CRM_USART1_PERIPH_CLOCK
#define PRINT_UART_TX_PIN GPIO_PINS_9
#define PRINT_UART_TX_GPIO GPIOA
#define PRINT_UART_TX_GPIO_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
#define PRINT_UART_TX_PIN_SOURCE GPIO_PINS_SOURCE9
#define PRINT_UART_TX_PIN_MUX_NUM GPIO_MUX_7
/******************* define button *******************/
typedef enum
{
USER_BUTTON = 0,
NO_BUTTON = 1
} button_type;
#define USER_BUTTON_PIN GPIO_PINS_0
#define USER_BUTTON_PORT GPIOA
#define USER_BUTTON_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
/**
* @}
*/
/** @defgroup BOARD_exported_functions
* @{
*/
/******************** functions ********************/
void at32_board_init(void);
/* led operation function */
void at32_led_init(led_type led);
void at32_led_on(led_type led);
void at32_led_off(led_type led);
void at32_led_toggle(led_type led);
/* button operation function */
void at32_button_init(void);
button_type at32_button_press(void);
uint8_t at32_button_state(void);
/* delay function */
void delay_init(void);
void delay_us(uint32_t nus);
void delay_ms(uint16_t nms);
void delay_sec(uint16_t sec);
/* printf uart init function */
void uart_print_init(uint32_t baudrate);
#ifdef __cplusplus
}
#endif
#endif
测试效果
开源工具链环境搭建
具体搭建过程参考 https://gitee.com/End-ING/embedded-gcc-template
主要使用到 GNU Arm Embedded Toolchain交叉编译器 GCC
需要修改启动文件,需要从libraries/cmsis/cm4/device_support/startup/gcc选择合适的文件,复制一份重新建立tools文件夹。
编写Makefile脚本
######################################
# target
######################################
TARGET = at32f423_template
######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization for size
OPT = -Os
#######################################
# paths
#######################################
# Build path
BUILD_DIR = build
######################################
# source
######################################
# C sources
C_SOURCES = \
libraries/cmsis/cm4/device_support/system_at32f423.c \
libraries/drivers/src/at32f423_acc.c \
libraries/drivers/src/at32f423_adc.c \
libraries/drivers/src/at32f423_can.c \
libraries/drivers/src/at32f423_crc.c \
libraries/drivers/src/at32f423_crm.c \
libraries/drivers/src/at32f423_dac.c \
libraries/drivers/src/at32f423_debug.c \
libraries/drivers/src/at32f423_dma.c \
libraries/drivers/src/at32f423_ertc.c \
libraries/drivers/src/at32f423_exint.c \
libraries/drivers/src/at32f423_flash.c \
libraries/drivers/src/at32f423_gpio.c \
libraries/drivers/src/at32f423_i2c.c \
libraries/drivers/src/at32f423_misc.c \
libraries/drivers/src/at32f423_pwc.c \
libraries/drivers/src/at32f423_scfg.c \
libraries/drivers/src/at32f423_spi.c \
libraries/drivers/src/at32f423_tmr.c \
libraries/drivers/src/at32f423_usart.c \
libraries/drivers/src/at32f423_usb.c \
libraries/drivers/src/at32f423_wdt.c \
libraries/drivers/src/at32f423_wwdt.c \
libraries/drivers/src/at32f423_xmc.c \
application/main.c \
application/at32f423_int.c \
application/at32f423_clock.c \
bspdriver/at32f423_board.c \
# ASM sources
ASM_SOURCES = \
tools/startup_at32f423.s \
#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
GCC_PATH = /SoftwareApplication/gcc-arm-none-eabi/bin
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m4
# fpu
FPU = -mfpu=fpv4-sp-d16
# float-abi
FLOAT-ABI = -mfloat-abi=hard
# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
# macros for gcc
# AS defines
AS_DEFS =
# C defines
C_DEFS = \
-D USE_STDPERIPH_DRIVER \
-D AT32F423VCT7 \
-D AT_START_F423_V1 \
# AS includes
AS_INCLUDES =
# C includes
C_INCLUDES = \
-I libraries/cmsis/cm4/core_support \
-I libraries/cmsis/cm4/device_support \
-I libraries/drivers/inc \
-I application \
-I bspdriver \
-I middlewares \
-I moduledriver \
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = tools/AT32F423xC_FLASH.ld
# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -u_printf_float -specs=nosys.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
# #######################################
# # build the application
# #######################################
# # list of objects
# OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
# vpath %.c $(sort $(dir $(C_SOURCES)))
# # list of ASM program objects
# OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o)))
# vpath %.S $(sort $(dir $(ASM_SOURCES)))
# $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
# @echo "[CC] $<"
# @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
# $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
# @echo "[AS] $<"
# @$(AS) -c $(CFLAGS) $< -o $@
# $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
# @echo "[HEX] $< -> $@"
# @$(CC) $(OBJECTS) $(LDFLAGS) -o $@
# @$(SZ) $@
# $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
# @echo "[HEX] $< -> $@"
# @$(HEX) $< $@
# $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
# @echo "[BIN] $< -> $@"
# @$(BIN) $< $@
# $(BUILD_DIR):
# @mkdir $@
#
#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
@echo "[CC] $<"
@$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
@echo "[AS] $<"
@$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
@echo "[HEX] $< -> $@"
@$(CC) $(OBJECTS) $(LDFLAGS) -o $@
@$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
@echo "[HEX] $< -> $@"
@$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
@echo "[BIN] $< -> $@"
@$(BIN) $< $@
$(BUILD_DIR):
@mkdir $@
#######################################
# program
#######################################
flash:
# openocd -f atlink.cfg -f at32f403axx.cfg -c init -c halt -c "program build/$(TARGET).elf verify reset exit"
# pyocd erase -c -t _at32a403vgt7 --config pyocd.yaml
# pyocd load build/$(TARGET).hex -t at32a403vgt7 --config pyocd.yaml
#######################################
# clean up
#######################################
clean:
-del /q $(BUILD_DIR)
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***
make编译效果
gcc串口打印问题
在gcc下面使用_write进行定向printf。(如果是从KEIL的例程printf打印无法在gcc工程中使用,因此需要修改,雅特力官方提供的工程模板就很好的兼容了两者,不需要我们去进行如何的操作,具体实现在at32f423_board.c中)
/* support printf function, usemicrolib is unnecessary */
#if (__ARMCC_VERSION > 6000000)
__asm (".global __use_no_semihosting\n\t");
void _sys_exit(int x)
{
x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{
ch = ch;
}
FILE __stdout;
#else
#ifdef __CC_ARM
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{
ch = ch;
}
#endif
#endif
#if defined (__GNUC__) && !defined (__clang__)
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/**
* @brief retargets the c library printf function to the usart.
* @param none
* @retval none
*/
PUTCHAR_PROTOTYPE
{
while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);
usart_data_transmit(PRINT_UART, (uint16_t)ch);
while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET);
return ch;
}
#if (defined (__GNUC__) && !defined (__clang__)) || (defined (__ICCARM__))
#if defined (__GNUC__) && !defined (__clang__)
int _write(int fd, char *pbuffer, int size)
#elif defined ( __ICCARM__ )
#pragma module_name = "?__write"
int __write(int fd, char *pbuffer, int size)
#endif
{
for(int i = 0; i < size; i ++)
{
while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET);
usart_data_transmit(PRINT_UART, (uint16_t)(*pbuffer++));
while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET);
}
return size;
}
#endif
MCUProg开源下载工具
下载器使用板载的DAP-Link,在MDK-ARM 里面配置好下载器可以直接下载,由于本次使用的GCC工具链编译的,可以使用官方hex/bin文件下载工具,也可以使用Openocd或者Pyocd,由于官方的openocd我没有找到,因此使用的pyocd进行下载。
使用pyocd下载一般是进行命令行输入,但是我们这一次选择了一个开源的DAP-Link,Pyocd可视化下载工具,主要太方便了,简单明了。
MCUProg是一款基于pyocd+PySide6的MUC烧录上位机软件。
软件架构
pyocd: 0.36.0 PySide6: 6.7.0
支持平台
windows linux
支持功能
支持Daplink V1、Daplink V2、stlink、Jlink烧录器
支持windows10以上系统,支持linux系统(ubuntu测试)
支持自定义本地pack文件以支持自定义芯片
支持读取芯片数据
支持读取烧录固件数据(目前支持bin、hex,elf、axf后续支持)
支持烧录时可选擦除芯片
支持bin固件自定义烧录地址
LINUX使用说明
linux下要安装驱动, 驱动在仓库udev目录下,使用说明参考pyocd linux驱动安装
注意事项
如烧录失败请检查一下几点
烧录器与芯片是否连接正常
目标芯片是否选择正确
芯片是否支持选择的烧录速度
是否有中断下载比如拔出usb操作
其他情况请尝试重启软件,如无法解决请及时反馈
下载流程
选择pack文件
选择目标芯片
选择目标固件
连接下载器
进行下载
观察测试现象
总结
以上主要介绍了雅特力AT32F423开发板的开发环境的搭建与基本案例的测试,接下来进行各种中间件的移植与测试。
全部评论