GD32
閑話說在前頭
這里又開一個系列啦。
原因就是之前買了立創開發板的9.9的GD32E230C8T6的板子,買都買了就跟著立創開發板學習一下(屬于是一次性支持了兩個國產品牌了,立創和兆易創新)。并且我還買了GD32F407VET6的板子,后續也會使用GD32F407VET6這塊板子來做一些別的。
GD32可以說是STM32的國產平替版,聽說部分型號可以直接替換掉STM32(我沒試過)。
反正以后有啥項目我的首選MCU肯定不會是STM32了(雖然我是用的STM32入門的32位單片機),因為上有更好用ESP32,下有供貨穩定(21年的時候STM32斷貨,STM32F103C8T6的價格曾被炒到六十多一片)的GD32。
剛剛去某寶逛了逛,目前為止(2024.4.23),我在同一家店鋪里發現GD32F103C8T6的芯片會比STM32F103C8T6的芯片稍貴三毛錢(不過GD32的主頻更高,其他外設和性能什么的沒去翻手冊對比不太清楚)。并且在某寶上賣STM32開發板的商家明顯比GD32開發板的多。現在一個STM32F103C8T6的最小系統板我找到的便宜的可能也就十塊錢出頭,但是GD32F103C8T6的核心板要二十多塊,而且選擇還很少。我想這大概是市場上的差異,因為有了需求才會有供給,大家都去買STM32那么STM32自然就能投入更多到研發和生產上,導致了強者愈強的局面。隨著國內技術的不斷發展和市場的逐步成熟,GD32等國產MCU正在逐漸縮小與國際品牌的差距。
本人懷著強烈的愛國之心,呼吁各位小伙伴支持國產。你不支持,我不支持,那國產品牌哪來的研發資金給咱整什么國貨崛起。
總之一句話,支持國產就完事了。
命名規則
GD32和STM32可以說是非常相似的,連命名規則都差不多。
外設資源
上面紅框框出來的是GD32E230的外設資源。相比較STM32F103C8T6來說,相對少一些。不過E230在GD32系列芯片里屬于入門級,拿來學習是綽綽有余的。
GPIO
接下來我們直接看如何驅動GPIO,點個燈先。
國產的還有一個好處就是手冊對中文的支持比較好,省的跑去找翻譯了。
可以看得出GD32的固件庫功能還是挺多的,比如最后一個翻轉GPIO的引腳狀態,這個在STM32的固件庫里是沒有的(HAL庫有)。雖然不用人家提供,我們另外也有辦法可以實現翻轉的操作,但是直接就有的話還是很舒服的。
在STM32中,我們配置GPIO口是需要一個結構體變量的,通過給這個結構體的成員賦值來配置GPIO口。
在GD32中,我們可以看到配置GPIO口是通過兩個函數來配置的,分別是設置GPIO模式和GPIO輸出模式和速度。
gpio_mode_set
可以選什么參數,在上面的表格寫的非常清楚。
這邊就簡單說一下一些參數的具體含義。
首先是mode,輸入輸出這個沒什么好說的,模擬模式就是我們使用ADC的時候用的。備用功能模式也就是復用引腳,比如我現在要用串口,那么就需要給串口的TX和RX這倆引腳配上這個備用功能模式。
pull_up_down是配置電阻的,和STM32不同的是GD32把這個配置拆開了,STM32中是直接配置為上拉輸入,下拉輸入等,而在GD32中是配置輸入模式,再加上上拉電阻或者是下拉電阻。
gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_0);
上面示例代碼的意思就是我們配置GPIOA的0號引腳為輸出模式,沒有加電阻。
gpio_output_options_set
配置輸出的模式和速率。
一般來說咱就陪推挽輸出是夠用的,不過具體還得看咱要驅動的模塊的手冊來判斷。
輸出速度,如果是通過高低電平來傳輸數據,那么速度是建議在通信速率的5~10倍的。
gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_0);
上面配置了GPIOA的0號引腳為2MHz的推挽輸出模式。?
如果是輸入模式則不需要使用這個函數。
gpio_bit_write
設置輸出電平的函數有很多個,除了這個還有gpio_bit_set ,gpio_bit_reset,gpio_port_write。不過我這邊就講gpio_bit_write,因為這個是最常用的,并且剩下三個能實現的功能,用這個函數都可以實現。
參數就是指定端口和引腳,以及高電平(SET)或是低電平(RESET)。
gpio_input_bit_get
gpio_output_bit_get
上面的兩個函數都可以讀取指定端口和引腳的電平。
跟STM32不一樣的是GD32細分了讀取電平,分為了讀取輸出模式下的引腳和讀取輸入模式下的引腳。
gpio_af_set
設置復用哪一個外設。
這個具體看我們要使用哪一個外設,對照著表格去配置就好了。后續我們會用到。
點亮LED
剩下還有一點就是GD32和STM32一樣,默認都是關閉外設時鐘的,因此我們還需要打開外設時鐘。
rcu_periph_clock_enable ?
參照著表格填寫我們需要打開的外設時鐘即可。?
#include "gd32e23x.h"void Z_Init_GPIO(void){rcu_periph_clock_enable(RCU_GPIOA);gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_0);gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_0);
}int main(void){Z_Init_GPIO();gpio_bit_write(GPIOA,GPIO_PIN_0,0);while(1){}
}
閃爍LED
點亮LED之后我們再讓LED閃爍。
我們需要延時函數,這個時候就直接把立創開發板寫的拿過來用就好了。
systick.c
/******************************************************************************* 測試硬件:立創開發板·GD32E230C8T6 使用主頻72Mhz 晶振8Mhz* 版 本 號: V1.0* 修改作者: www.lckfb.com* 修改日期: 2023年11月02日* 功能介紹: ****************************************************************************** 梁山派軟硬件資料與相關擴展板軟硬件資料官網全部開源 * 開發板官網:www.lckfb.com * 技術支持常駐論壇,任何技術問題歡迎隨時交流學習 * 立創論壇:club.szlcsc.com * 其余模塊移植手冊:【立創·GD32E230C8T6開發板】模塊移植手冊* 關注bilibili賬號:【立創開發板】,掌握我們的最新動態!* 不靠賣板賺錢,以培養中國工程師為己任******************************************************************************/
/*!\file systick.c\brief the systick configuration file\version 2019-02-19, V1.0.0, firmware for GD32E23x
*//*Copyright (c) 2019, GigaDevice Semiconductor Inc.All rights reserved.Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/#include "gd32e23x.h"
#include "systick.h"volatile static float count_1us = 0;
volatile static float count_1ms = 0;/*!\brief configure systick\param[in] none\param[out] none\retval none
*/
void systick_config(void)
{/* systick clock source is from HCLK/8 */systick_clksource_set(SYSTICK_CLKSOURCE_HCLK_DIV8);count_1us = (float)SystemCoreClock/8000000;count_1ms = (float)count_1us * 1000;
}/*!\brief delay a time in microseconds in polling mode\param[in] count: count in microseconds\param[out] none\retval none
*/
void delay_1us(uint32_t count)
{uint32_t ctl;/* reload the count value */SysTick->LOAD = (uint32_t)(count * count_1us);/* clear the current count value */SysTick->VAL = 0x0000U;/* enable the systick timer */SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;/* wait for the COUNTFLAG flag set */do{ctl = SysTick->CTRL;}while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));/* disable the systick timer */SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;/* clear the current count value */SysTick->VAL = 0x0000U;
}void delay_us(uint32_t count)
{uint32_t ctl;/* reload the count value */SysTick->LOAD = (uint32_t)(count * count_1us);/* clear the current count value */SysTick->VAL = 0x0000U;/* enable the systick timer */SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;/* wait for the COUNTFLAG flag set */do{ctl = SysTick->CTRL;}while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));/* disable the systick timer */SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;/* clear the current count value */SysTick->VAL = 0x0000U;
}/*!\brief delay a time in milliseconds in polling mode\param[in] count: count in milliseconds\param[out] none\retval none
*/
void delay_1ms(uint32_t count)
{uint32_t ctl;/* reload the count value */SysTick->LOAD = (uint32_t)(count * count_1ms);/* clear the current count value */SysTick->VAL = 0x0000U;/* enable the systick timer */SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;/* wait for the COUNTFLAG flag set */do{ctl = SysTick->CTRL;}while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));/* disable the systick timer */SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;/* clear the current count value */SysTick->VAL = 0x0000U;
}void delay_ms(uint32_t count)
{uint32_t ctl;/* reload the count value */SysTick->LOAD = (uint32_t)(count * count_1ms);/* clear the current count value */SysTick->VAL = 0x0000U;/* enable the systick timer */SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;/* wait for the COUNTFLAG flag set */do{ctl = SysTick->CTRL;}while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));/* disable the systick timer */SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;/* clear the current count value */SysTick->VAL = 0x0000U;
}
systick.h
/*!\file systick.h\brief the header file of systick\version 2019-02-19, V1.0.0, firmware for GD32E23x
*//*Copyright (c) 2019, GigaDevice Semiconductor Inc.All rights reserved.Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/#ifndef SYS_TICK_H
#define SYS_TICK_H#include <stdint.h>/* function declarations */
/* configure systick */
void systick_config(void);
/* delay a time in milliseconds */
void delay_1ms(uint32_t count);/* delay a time in milliseconds */
void delay_ms(uint32_t count);/* delay a time in microseconds */
void delay_1us(uint32_t count);/* delay a time in microseconds */
void delay_us(uint32_t count);#endif /* SYS_TICK_H */
閃爍LED代碼?
#include "gd32e23x.h"
#include "systick.h"void Z_Init_GPIO(void){rcu_periph_clock_enable(RCU_GPIOA);gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_0);gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_0);
}int main(void){systick_config();Z_Init_GPIO();gpio_bit_write(GPIOA,GPIO_PIN_0,0);while(1){//gpio_bit_write(GPIOA,GPIO_PIN_0,!gpio_output_bit_get(GPIOA,GPIO_PIN_0));gpio_bit_toggle(GPIOA,GPIO_PIN_0);delay_ms(500);}
}