关于兆易创新GD32的产品,目前在单片机MCU的业务上,GD全部是32bit的单片机,目前GD32的单片机从内核上区分有Cortex-M3、Cortex-M4、Cortex-M23三个系列,其中红色框框为主推系列:
开发调试环境: 支持主流的Keil MDK4/5、IAR、Eclipse等IDE环境
开发编程/烧写工具: 因为采用标准的Cortex-M内核,所有支持标准的JlinkV8/V9、Ulink2和自己的GD-link工具
开发特色: 同样是基于标准库的形式进行开发,每一个外设都有相对应的API封装库,不必要去熟悉每个外设的底层寄存器,可以快速上手
第一步:
GD官网下载GD32F10x_Firmware_Library_V2.2.2
新建工程文件夹iar_progect_uart其中包括:
Application:GD32F10x_Firmware_Library_V2.2.2\Template所包含文件
Firmware: GD32F10x_Firmware_Library_V2.2.2\Firmware
Utilities: GD32F10x_Firmware_Library_V2.2.2\Utilities
第二步:
新建工程,选择工程文件夹iar_project_uart,输出工程名字iar_uart:
右键add,添加5个group分别为:
第三步:
向group中添加源文件(.C文件)
Application分组中添加Application文件夹中的.c文件
CMSIS中添加Firmware\CMSIS\GD\GD32F10x\Sourcesystem_gd32f10x.c
Peripherals中添加Firmware\GD32F10x_standard_peripheral\Source所有.c
Startup中添加Firmware\CMSIS\GD\GD32F10x\Source\IAR\startup_gd32f10x_cl.s
Utilities中添加用户编写的文件
第四步:
Options设置:
选择芯片型号,需要提前安装GD32F10x_AddOn_V2.0.2支持包
然后添加头文件路径:
第五步:
编译完成后烧录
第一步:
创建工程文件夹,准备好相应文件
建立工程,选择工程文件夹,然后选择对应芯片
第二步:
同样创建五个group,然后添加.c文件:
需要注意的是Startup中添加Firmware\CMSIS\GD\GD32F10x\Source\ ARM \startup_gd32f10x_cl.s
第三步:
添加头文件路径与宏定义
补充:Use MicroLIB 需要勾选,否则程序下载后不运行
第一步:
打开时钟配置文件,修改为外部高速晶振
第二步:
选择外部晶振频率
第三步:
修改gd32f10x.h中外部晶振的频率值
第四步:
上述操作只是选择了108MHz作为时钟频率,但距离真正产生108MHz时钟还需要先对时钟源(高速外部时钟)进行倍频等处理。
在system_gd32f10x.c文件中找到如下代码段:
static void system_clock_108m_hxtal(void)
1.使能时钟
2.配置GPIO端口
3.电平置零
void user_gpio_init_PA9()
{
/* enable clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* configure GPIO port */
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
GPIO_BC(GPIOA) = GPIO_PIN_9;
}
使用:
gpio_bit_set(GPIOA,GPIO_PIN_9);
gpio_bit_reset(GPIOA,GPIO_PIN_9);
gpio_input_bit_get(GPIOA,GPIO_PIN_9);
gpio_output_bit_get(GPIOA,GPIO_PIN_9);
1.优先级数值越小,优先级越高。
2. Cortex-M支持中断嵌套,高优先级异常会抢占低优先级异常。
3. 有三个系统异常:复位/NMI/Hardfault 它们的优先级是负数
4. GD32Fxxx使用了4bit来表达优先级,4bit分为抢占优先级和子优先级。
5. 抢占优先级高的会打断抢占优先级低的中断;
如果抢占优先级相同,谁先发生的先执行完谁,若同时发生,则执行子优先级高的中断;
如果抢占优先级相同,子优先级也相同,若同时发生,则比较中断编号,中断编号越小优先级越高。
6.EXTI是中断/事件控制器包括边沿检测电路,能够向处理器内核产生中断请求或者唤醒事件,三种触发类型:上升沿、下降沿、任意沿。
7.Arm Cortex-M3处理器和嵌套式矢量型中断控制器(NVIC)在处理(Handler)模式下对所有异常进行优先级区分以及处理。当异常发生时,系统自动将当前处理器工作状态压栈,在执行完中断服务子程序 (ISR)后自动将其出栈。
取向量是和当前工作态压栈并行进行的,从而提高了中断入口效率。处理器支持咬尾中断,可实现背靠背中断,大大削减了反复切换工作态所带来的开销。
8.EXTI触发源包括来自I/O管脚的16根线以及来自内部模块的4根线。(包括LVD、RTC闹钟、USB唤醒、以太网唤醒)。
通过配置GPIO模块的AFIO_EXTISSx寄存器,所有的GPIO管脚都可以被选作EXTI的触发源。
int main(void)
{
systick_config();//系统配置
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_bit_reset(GPIOA, GPIO_PIN_9);//配置一个输出控制LED的GPIO
rcu_periph_clock_enable(RCU_GPIOB);//配置一个输入按键用于中断的产生
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
rcu_periph_clock_enable(RCU_AF);//中断时钟
nvic_irq_enable(EXTI0_IRQn, 2U, 0U);//中断使能
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_0);//设置中断源为PB0
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);//中断/事件控制器初始化
exti_interrupt_flag_clear(EXTI_0);//清除中断标志位
uint16_t temp = 0;
while(1)
{
temp++;
delay_1ms(1000);
}
}
void EXTI0_IRQHandler(void)//中断处理函数
{
if(RESET != exti_interrupt_flag_get(EXTI_0))
{
gpio_bit_write(GPIOA, GPIO_PIN_9, (bit_status)(1 - gpio_input_bit_get(GPIOA,GPIO_PIN_9)));
exti_interrupt_flag_clear(EXTI_0);
}
}
中断处理函数的名字在启动文件startup_gd32f10x_cl.s中:
中断号IRQn在gd32f10x.h中:
EXTI线的编号为0-19共20根,位置在gd32f10x_exti.h中:
USART:通用同步和异步收发器
UART:通用异步收发器
当进行异步通信时,这两者是没有区别的。区别在于USART比UART多了同步通信功能。 这个同步通信功能可以把USART当做SPI来用,比如用USART来驱动SPI设备。
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
同步是阻塞模式,异步是非阻塞模式。
其中SPI IIC为同步通信 UART为异步通信, usart为同步&异步通信。
单工、半双工、全双工
单工数据传输只支持数据在一个方向上传输;
半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;
全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。
I2C是半双工,SPI是全双工,uart是全双工。
设置uart3接收中断:
uart3_init();
/* USART interrupt configuration */
nvic_irq_enable(UART3_IRQn, 0, 0);
/* enable receive interrupt */
usart_interrupt_enable(UART3, USART_INT_RBNE);// receive buffer not empty
void UART3_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(UART3, USART_INT_FLAG_RBNE))
{
/* read one byte from the receive data register */
rx_buffer[rx_counter++] = (uint8_t)usart_data_receive(UART3);
}
user_gpio_toggle(GPIO_PA9);
}