导图社区 GD32处理器知识图谱
兆易创新处理器,GD32处理器是一款高性能、低功耗的32位微控制器系列,具有广泛的应用前景和强大的开发支持。
编辑于2024-11-30 07:30:42GD32
GD32F307C
从SRAM启动
Reset_Handler的地址必须是0x200001e1
检查 map 文件
调整 .s 文件中的向量表
在 __Vectors_End 之前添加
Skip_Mem SPACE 0x78
数字具体多少需要看情况
调整Target中的IROM1 IRAM1
调整Flash Download
修改main 函数开始
nvic_vector_table_set(NVIC_VECTTAB_RAM, 0x00)
配置NVIC中断向量表基地址
STM32
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x00);
说明:STM32有宏 VECT_TAB_SRM 控制
SystemInit();
NVIC中断
NVIC 负责管理中断请求,支持中断优先级管理、中断嵌套和使能/禁用控制。 系统提供的 中断处理Handler 实现 stm32f10x_it.c
负责管理中断请求(IRQ)
中断优先级管理
:NVIC 支持多达 256 个中断优先级,但 GD32F307C 通常只使用其中的 16 个优先级。每个中断都可以分配一个优先级,优先级值越低,优先级越高。
中断向量表
:NVIC 使用中断向量表来存储中断服务例程(ISR)的地址。当一个中断发生时,NVIC 会根据中断号从向量表中获取相应的 ISR 地址,并跳转到该地址执行 ISR。
中断嵌套
:NVIC 支持中断嵌套,即高优先级的中断可以打断低优先级的中断处理。
中断使能和禁用
:NVIC 允许通过寄存器控制每个中断的使能和禁用状态。
NVIC 寄存器
ISER(Interrupt Set-Enable Register):用于使能中断。
ICER(Interrupt Clear-Enable Register):用于禁用中断。
ISPR(Interrupt Set-Pending Register):用于设置中断为挂起状态。
ICPR(Interrupt Clear-Pending Register):用于清除中断的挂起状态。
IPR(Interrupt Priority Register):用于设置中断的优先级。
SysTick
SysTick 是一个简单的 24 位递减计数器,通常用于操作系统的时钟节拍或简单的延时功能。 SysTick 中断是 NVIC 管理的一个特定中断,其中断号为 SysTick_IRQn。
24 位的递减计数器
通常用于实现操作系统的时钟节拍(tick)或简单的延时功能
特点
自动重装载:SysTick 可以配置为在计数器递减到零时自动重装载一个预设值,从而实现周期性的中断。
中断生成:当 SysTick 计数器递减到零时,可以触发一个 SysTick 中断,这个中断通常用于操作系统的任务调度或时间片轮转。
简单易用:SysTick 的配置和使用非常简单,通常只需要设置几个寄存器即可。
寄存器
CTRL(Control and Status Register):用于控制 SysTick 的工作模式和状态。
LOAD(Reload Value Register):用于设置 SysTick 计数器的重装载值。
VAL(Current Value Register):用于读取当前 SysTick 计数器的值。
CALIB(Calibration Value Register):用于提供校准信息,通常用于操作系统的时钟节拍。
示例
#include "gd32f30x.h" void SysTick_Handler(void) { // SysTick 中断处理函数 // 在这里可以实现操作系统的任务调度或其他时间相关的操作 static uint32_t tick_count = 0; tick_count++; if (tick_count % 1000 == 0) { // 每 1000 个 SysTick 中断(即 1 秒)执行一次 // 在这里可以实现任务调度或其他时间相关的操作 } } void delay_ms(uint32_t ms) { // 使用 SysTick 实现简单的延时函数 SysTick->LOAD = SystemCoreClock / 1000 * ms; // 设置重装载值 SysTick->VAL = 0; // 清空当前值 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; // 使能 SysTick 和中断 // 等待 SysTick 计数器递减到零 while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); SysTick->CTRL = 0; // 禁用 SysTick } int main(void) { // 初始化系统时钟 SystemInit(); // 配置 SysTick 中断优先级 NVIC_SetPriority(SysTick_IRQn, 0); // 设置 SysTick 中断优先级为最高 // 使用 SysTick 实现延时 while (1) { // 做一些工作 delay_ms(1000); // 延时 1 秒 } }
轮询读取字符
while (usart_flag_get(USART2, USART_FLAG_RBNE) == RESET); ch = usart_data_receive(USART2);
串口
USART
应用场景
适用于需要同步和异步通信的场合,例如与外部设备进行时钟同步的数据传输。
同步模式
异步模式
类似于 UART
UART
应用场景
简单的点对点异步通信,例如与传感器、调试工具等进行通信
异步模式
仅支持异步通信模式
兼容M3
M4 without FP was compatible with M3
FreeRTOS
port 可以用 CM3 的文件
移植流程
1. 准备
下载FreeRTOS LTS源码
FreeRTOSv202406.01-LTS
Keil 工程
2. FreeRTOS Kernel 代码文件拷贝到 工程 的相应目录
1. 工程下的目录为 FreeRTOS
2. 裁剪,保留文件
croutine.c
event_groups.c
list.c
queue.c
stream_buffer.c
tasks.c
timers.c
include 目录
portable 目录
MemMang 目录
RVDS 目录
ARM_CM3 目录
3. FreeRTOSConfig.h
#ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__TASKING__) || defined(__GNUC__) #include <stdint.h> extern uint32_t SystemCoreClock; #endif #define configUSE_PREEMPTION 1 #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 8 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configQUEUE_REGISTRY_SIZE 8 #define configUSE_APPLICATION_TASK_TAG 0 /* hook function related definitions */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 /* run time and task stats gathering related definitions */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 1 /* co-routine definitions */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* software timer definitions */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( 2 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) /* set to 1 to include the API function, or 0 to exclude the API function */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* Cortex-M specific definitions */ #ifdef __NVIC_PRIO_BITS /* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif /* the lowest interrupt priority that can be used in a call to a "set priority" function */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. Do not call interrupt safe freertos api functions from any interrupt that has a higher priority than this! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 /* interrupt priorities used by the kernel port layer itself */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* normal assert() semantics without relying on the provision of an assert.h header file */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /* map the FreeRTOS port interrupt handlers to CMSIS standard names */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */
可以手动配置
也可以直接复制 其他参考例程
3. 修改代码
gd32f30x_it.c
注释函数 void PendSV_Handler(void)
注释函数 void SVC_Handler(void)
注释函数 void SysTick_Handler(void)
使用FreeRTOS 文件 port.c中的实现
4. 配置 Keil 工程
(1) Options for Target
Inlude Paths
..\FreeRTOS\include
..\FreeRTOS\portable\RVDS\ARM_CM3
(2) Manage Project Items
Project Items
Groups
添加组
FreeRTOS_Core croutine.c event_groups.c list.c queue.c stream_buffer.c tasks.c timers.c FreeRTOS_Port port.c heap_4.c 说明:1个组也可以。
FreeRTOS_Core
FreeRTOS_Port
5. 程序引用 FreeRTOS API
举例
xTimerCreate
if ((led1 = pvPortMalloc(sizeof(led_st_t))) == NULL) { // 需要使用 malloc 分配 return (NULL); } led1->interval =500; led1->pin = GPIO_PIN_0; led1->port = GPIOA; led_timer = xTimerCreate( "led_timer", 1000, pdTRUE, (void *)led1, led_flash_callback ); if (led_timer != NULL) { xTimerStart( led_timer, 0 ); } if ((led2 = pvPortMalloc(sizeof(led_st_t))) == NULL) { return (NULL); } led2->interval =3000; led2->pin = GPIO_PIN_1; led2->port = GPIOA; led_timer1 = xTimerCreate( "led_timer1", 3000, pdTRUE, (void *)led2, led_flash_callback ); if (led_timer1 != NULL) { xTimerStart( led_timer1, 0 ); } vTaskStartScheduler();
xTaskCreate
实战
引用头文件
#include "FreeRTOS.h"
其他
工程
keil5打开keil4工程
直接修改文件名 uproj -> uprojx
GD32处理器知识图谱
NVIC中断
NVIC 负责管理中断请求,支持中断优先级管理、中断嵌套和使能/禁用控制。 系统提供的 中断处理Handler 实现 stm32f10x_it.c
负责管理中断请求(IRQ)
中断优先级管理
NVIC 支持多达 256 个中断优先级,但 GD32F307C 通常只使用其中的 16 个优先级。每个中断都可以分配一个优先级,优先级值越低,优先级越高。
中断向量表
NVIC 使用中断向量表来存储中断服务例程(ISR)的地址。当一个中断发生时,NVIC 会根据中断号从向量表中获取相应的 ISR 地址,并跳转到该地址执行 ISR。
中断嵌套
NVIC 支持中断嵌套,即高优先级的中断可以打断低优先级的中断处理。
中断使能和禁用
NVIC 允许通过寄存器控制每个中断的使能和禁用状态。
NVIC 寄存器
ISER(Interrupt Set-Enable Register):用于使能中断。
ICER(Interrupt Clear-Enable Register):用于禁用中断。
ISPR(Interrupt Set-Pending Register):用于设置中断为挂起状态。
ICPR(Interrupt Clear-Pending Register):用于清除中断的挂起状态。
IPR(Interrupt Priority Register):用于设置中断的优先级。
SysTick
SysTick 是一个简单的 24 位递减计数器,通常用于操作系统的时钟节拍或简单的延时功能。 SysTick 中断是 NVIC 管理的一个特定中断,其中断号为 SysTick_IRQn。
24 位的递减计数器
通常用于实现操作系统的时钟节拍(tick)或简单的延时功能
特点
自动重装载:SysTick 可以配置为在计数器递减到零时自动重装载一个预设值,从而实现周期性的中断。
中断生成:当 SysTick 计数器递减到零时,可以触发一个 SysTick 中断,这个中断通常用于操作系统的任务调度或时间片轮转。
简单易用:SysTick 的配置和使用非常简单,通常只需要设置几个寄存器即可。
寄存器
CTRL(Control and Status Register):用于控制 SysTick 的工作模式和状态。
LOAD(Reload Value Register):用于设置 SysTick 计数器的重装载值。
VAL(Current Value Register):用于读取当前 SysTick 计数器的值。
CALIB(Calibration Value Register):用于提供校准信息,通常用于操作系统的时钟节拍。
示例
#include "gd32f30x.h" void SysTick_Handler(void) { // SysTick 中断处理函数 // 在这里可以实现操作系统的任务调度或其他时间相关的操作 static uint32_t tick_count = 0; tick_count++; if (tick_count % 1000 == 0) { // 每 1000 个 SysTick 中断(即 1 秒)执行一次 // 在这里可以实现任务调度或其他时间相关的操作 } } void delay_ms(uint32_t ms) { // 使用 SysTick 实现简单的延时函数 SysTick->LOAD = SystemCoreClock / 1000 * ms; // 设置重装载值 SysTick->VAL = 0; // 清空当前值 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; // 使能 SysTick 和中断 // 等待 SysTick 计数器递减到零 while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); SysTick->CTRL = 0; // 禁用 SysTick } int main(void) { // 初始化系统时钟 SystemInit(); // 配置 SysTick 中断优先级 NVIC_SetPriority(SysTick_IRQn, 0); // 设置 SysTick 中断优先级为最高 // 使用 SysTick 实现延时 while (1) { // 做一些工作 delay_ms(1000); // 延时 1 秒 } }
串口
USART
应用场景
适用于需要同步和异步通信的场合,例如与外部设备进行时钟同步的数据传输。
同步模式
异步模式
类似于 UART
UART
应用场景
简单的点对点异步通信,例如与传感器、调试工具等进行通信
异步模式
仅支持异步通信模式