本帖最后由 qjp1988113 于 2021-7-30 16:26 编辑
基于ST的对应型号缺货,大家都纷纷测试国内的替代芯片,我也想试一把。看到GD32E230C8T6理论上可以替代STM32F103C8T6,在这次去X商城买料的
时候,我顺便买了片样片,并要了个免费的最新系统样板PCB。
到货后,马不停蹄开工,焊好~
焊好后,去官网下载资料:
MDK PACK:
GD32E23x_AddOn_V1.1.0.rar
(1.77 MB, 下载次数: 100)
规格书:
GD32E230xx_Datasheet_Rev1.4.pdf
(2.44 MB, 下载次数: 99)
用户手册:
GD32E23x_yonghushouce_Rev1.4.pdf
(8.4 MB, 下载次数: 130)
固件手册:
GD32E23x_gujiankushiyongzhinan_Rev1.0.pdf
(5.69 MB, 下载次数: 108)
BSP:
GD32E23x_Firmware_Library_V1.1.1.rar
(861.82 KB, 下载次数: 74)
对应开发板资料:
GD32E23x_Demo_Suites_V1.0.1.rar
(4.06 MB, 下载次数: 129)
为了放心,我还是粗略的看了下它的规格书:
主要描述(除了内核M23,其他外设几乎没啥变动)
当前选用的C8T6(容量还是跟ST的保持一致,国产的就不能大些么~)
引导模式:
其中有一点不一样的就是,它的BOOT1由原来的映射引脚,变成了寄存器的一个配置位!
我们用跳帽把BOOT0连到GND,选择内部FLASH启动~
//////////////////////////////////////////////////////////////
我们看下我们最小系统的原理图:
不能再简陋了,就是最小系统加4个LED,2个KEY(其中只有WAKEUP能编程用)。
我们连接它的串口,好让调试信息输出:
查看数据手册得:
还是PA9/PA10与ST的一样。
我们打开GD32E23x_Demo_Suites_V1.0.1\GD32E230C_EVAL_Demo_Suites,这个板型号跟我的最新系统一致,就用
它的程序进行更改:
我们发现在它的gd32e230c_eval文件里,几乎包含了我们想要的外设,但是引脚有少许差异,修改下:
- /*!
- \file gd32e230c_eval.h
- \brief definitions for GD32E230C_EVAL's leds, keys and COM ports hardware resources
-
- \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 GD32E230C_EVAL_H
- #define GD32E230C_EVAL_H
- #ifdef cplusplus
- extern "C" {
- #endif
- #include "gd32e23x.h"
- /* exported types */
- typedef enum
- {
- LED1 = 0,
- LED2 = 1,
- LED3 = 2,
- LED4 = 3
- }led_typedef_enum;
- typedef enum
- {
- KEY_WAKEUP = 0,
- //KEY_TAMPER = 1,
- }key_typedef_enum;
- typedef enum
- {
- KEY_MODE_GPIO = 0,
- KEY_MODE_EXTI = 1
- }keymode_typedef_enum;
- /* eval board low layer led */
- #define LEDn 4U
- #define LED1_PIN GPIO_PIN_10
- #define LED1_GPIO_PORT GPIOB
- #define LED1_GPIO_CLK RCU_GPIOB
- #define LED2_PIN GPIO_PIN_11
- #define LED2_GPIO_PORT GPIOB
- #define LED2_GPIO_CLK RCU_GPIOB
- #define LED3_PIN GPIO_PIN_8
- #define LED3_GPIO_PORT GPIOA
- #define LED3_GPIO_CLK RCU_GPIOA
- #define LED4_PIN GPIO_PIN_9
- #define LED4_GPIO_PORT GPIOA
- #define LED4_GPIO_CLK RCU_GPIOA
- /* eval board low layer button */
- #define KEYn 1U //2U
- /* wakeup push-button */
- #define WAKEUP_KEY_PIN GPIO_PIN_0
- #define WAKEUP_KEY_GPIO_PORT GPIOA
- #define WAKEUP_KEY_GPIO_CLK RCU_GPIOA
- #define WAKEUP_KEY_EXTI_LINE EXTI_0
- #define WAKEUP_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOA
- #define WAKEUP_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN0
- #define WAKEUP_KEY_EXTI_IRQn EXTI0_1_IRQn
- /* tamper push-button */
- //#define TAMPER_KEY_PIN GPIO_PIN_13
- //#define TAMPER_KEY_GPIO_PORT GPIOC
- //#define TAMPER_KEY_GPIO_CLK RCU_GPIOC
- //#define TAMPER_KEY_EXTI_LINE EXTI_13
- //#define TAMPER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOC
- //#define TAMPER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN13
- //#define TAMPER_KEY_EXTI_IRQn EXTI4_15_IRQn
- /* eval board low layer COM */
- #define COMn 1U
- /* definition for COM, connected to USART0 */
- #define EVAL_COM USART0
- #define EVAL_COM_CLK RCU_USART0
- #define EVAL_COM_TX_PIN GPIO_PIN_9
- #define EVAL_COM_RX_PIN GPIO_PIN_10
- #define EVAL_COM_GPIO_PORT GPIOA
- #define EVAL_COM_GPIO_CLK RCU_GPIOA
- #define EVAL_COM_AF GPIO_AF_1
- /* function declarations */
- /* configure led GPIO */
- void gd_eval_led_init(led_typedef_enum lednum);
- /* turn on selected led */
- void gd_eval_led_on(led_typedef_enum lednum);
- /* turn off selected led */
- void gd_eval_led_off(led_typedef_enum lednum);
- /* toggle the selected led */
- void gd_eval_led_toggle(led_typedef_enum lednum);
- /* configure key */
- void gd_eval_key_init(key_typedef_enum keynum, keymode_typedef_enum keymode);
- /* return the selected key state */
- uint8_t gd_eval_key_state_get(key_typedef_enum keynum);
- /* configure COM port */
- void gd_eval_com_init(uint32_t com);
- #ifdef cplusplus
- }
- #endif
- #endif /* GD32E230C_EVAL_H */
main函数修改如下:
- /*!
- \file main.c
- \brief running LED
-
- \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 "gd32e230c_eval.h"
- #include "systick.h"
- #include <stdio.h>
- /*!
- \brief main function
- \param[in] none
- \param[out] none
- \retval none
- */
- int main(void)
- {
- //时钟初始化
- systick_config();
- //初始化LED
- gd_eval_led_init(LED1);
- gd_eval_led_init(LED2);
- gd_eval_led_init(LED3);
- gd_eval_led_init(LED4);
-
- gd_eval_led_off(LED1);
- gd_eval_led_off(LED2);
- gd_eval_led_off(LED3);
- gd_eval_led_off(LED4);
- //初始化按键
- gd_eval_key_init(KEY_WAKEUP,KEY_MODE_GPIO);
- //初始化串口0
- gd_eval_com_init(EVAL_COM);
-
- while(gd_eval_key_state_get(KEY_WAKEUP)==SET)
- {
- printf("please press wakeup_key to continue!\r\n");
- delay_1ms(200);
- }
- while(1){
- /* turn on LED1, turn off LED4 */
- gd_eval_led_on(LED1);
- gd_eval_led_off(LED4);
- delay_1ms(1000);
- /* turn on LED2, turn off LED1 */
- gd_eval_led_on(LED2);
- gd_eval_led_off(LED1);
- delay_1ms(1000);
- /* turn on LED3, turn off LED2 */
- gd_eval_led_on(LED3);
- gd_eval_led_off(LED2);
- delay_1ms(1000);
- /* turn on LED4, turn off LED3 */
- gd_eval_led_on(LED4);
- gd_eval_led_off(LED3);
- delay_1ms(1000);
- }
- }
- /* retarget the C library printf function to the USART */
- int fputc(int ch, FILE *f)
- {
- usart_data_transmit(USART0, (uint8_t) ch);
- while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
- return ch;
- }
编译下载,查看现象:
按下WAKEUP键后,继续执行到WHILE里面:
LED轮流亮灭~
上面仅仅实现了串口的打印,下面我们开启串口的接收中断,并将接收到的指令发回:在之前的串口初始化代码下面,我们定义2个宏,分别代表开启接收中断和发送中断:
#define EN_USART0_RX 1 //使能(1)/禁止(0)串口0接收中断
#define EN_USART0_TX 0 //使能(1)/禁止(0)串口0发送中断
发送中断一般很少用,我们开启接收中断。关闭发送中断:
#if EN_USART0_RX //如果使能了接收
//使能接收中断
usart_interrupt_enable(USART0, USART_INT_RBNE);
/* USART interrupt configuration */
nvic_irq_enable(USART0_IRQn, 0);
#endif
使能接收中断,并开启串口中断。
下面我们开始写接收中断的函数:
void USART0_IRQHandler(void) //串口1中断服务程序
{
#if EN_USART0_RX
uint8_t Res;
if(usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_RBNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =usart_data_receive(EVAL_COM); //读取接收到的数据
if((USART0_RX_STA&0x8000)==0)//接收未完成
{
if(USART0_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART0_RX_STA=0;//接收错误,重新开始
else USART0_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART0_RX_STA|=0x4000;
else
{
USART0_RX_BUF[USART0_RX_STA&0X3FFF]=Res ;
USART0_RX_STA++;
if(USART0_RX_STA>(USART0_REC_LEN-1))USART0_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#endif
#if EN_USART0_TX
if(usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_TBE)!= RESET)
{
/* transmit data */
// usart_data_transmit(EVAL_COM, transmitter_buffer[txcount++]);
// if(txcount == transfersize){
// usart_interrupt_disable(EVAL_COM, USART_INT_TBE);
// }
}
#endif
}
之前的printf重定义,仍然保留:
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t) ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
return ch;
}
具体串口代码:
usart0.h
- #ifndef __USART0_H
- #define __USART0_H
- #include "stdio.h"
- #include "gd32e23x.h"
- #include "gd32e230c_eval.h"
- #include "systick.h"
- #define USART0_REC_LEN 200 //定义最大接收字节数 200
- #define EN_USART0_RX 1 //使能(1)/禁止(0)串口0接收中断
- #define EN_USART0_TX 0 //使能(1)/禁止(0)串口0发送中断
-
- extern uint8_t USART0_RX_BUF[USART0_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
- extern uint16_t USART0_RX_STA; //接收状态标记
- void uart0_init(uint32_t bound);
- #endif
usart0.c
- #include "usart0.h"
- uint8_t USART0_RX_BUF[USART0_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
- //接收状态
- //bit15, 接收完成标志
- //bit14, 接收到0x0d
- //bit13~0, 接收到的有效字节数目
- uint16_t USART0_RX_STA=0; //接收状态标记
-
- void uart0_init(uint32_t bound)
- {
- //初始化
- gd_eval_com_init(EVAL_COM);
- //设置波特率
- usart_baudrate_set(EVAL_COM, bound);
- #if EN_USART0_TX
- //使能发送中断
- usart_interrupt_enable(USART0, USART_INT_TBE);
- #endif
- #if EN_USART0_RX //如果使能了接收
- //使能接收中断
- usart_interrupt_enable(USART0, USART_INT_RBNE);
- /* USART interrupt configuration */
- nvic_irq_enable(USART0_IRQn, 0);
- #endif
- }
- void USART0_IRQHandler(void) //串口1中断服务程序
- {
- #if EN_USART0_RX
- uint8_t Res;
- if(usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_RBNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
- {
- Res =usart_data_receive(EVAL_COM); //读取接收到的数据
-
- if((USART0_RX_STA&0x8000)==0)//接收未完成
- {
- if(USART0_RX_STA&0x4000)//接收到了0x0d
- {
- if(Res!=0x0a)USART0_RX_STA=0;//接收错误,重新开始
- else USART0_RX_STA|=0x8000; //接收完成了
- }
- else //还没收到0X0D
- {
- if(Res==0x0d)USART0_RX_STA|=0x4000;
- else
- {
- USART0_RX_BUF[USART0_RX_STA&0X3FFF]=Res ;
- USART0_RX_STA++;
- if(USART0_RX_STA>(USART0_REC_LEN-1))USART0_RX_STA=0;//接收数据错误,重新开始接收
- }
- }
- }
- }
- #endif
- #if EN_USART0_TX
- if(usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_TBE)!= RESET)
- {
- /* transmit data */
- // usart_data_transmit(EVAL_COM, transmitter_buffer[txcount++]);
- // if(txcount == transfersize){
- // usart_interrupt_disable(EVAL_COM, USART_INT_TBE);
- // }
- }
- #endif
- }
- /* retarget the C library printf function to the USART */
- int fputc(int ch, FILE *f)
- {
- usart_data_transmit(USART0, (uint8_t) ch);
- while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
- return ch;
- }
main函数中,做如下修改:
- /*!
- \file main.c
- \brief running LED
-
- \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 "gd32e230c_eval.h"
- #include "systick.h"
- #include <stdio.h>
- #include "usart0.h"
- /*!
- \brief main function
- \param[in] none
- \param[out] none
- \retval none
- */
- int main(void)
- {
- uint16_t t;
- uint16_t len;
- uint16_t times=0;
- //时钟初始化
- systick_config();
- //初始化LED
- gd_eval_led_init(LED1);
- gd_eval_led_init(LED2);
- gd_eval_led_init(LED3);
- gd_eval_led_init(LED4);
-
- gd_eval_led_off(LED1);
- gd_eval_led_off(LED2);
- gd_eval_led_off(LED3);
- gd_eval_led_off(LED4);
- //初始化按键
- gd_eval_key_init(KEY_WAKEUP,KEY_MODE_GPIO);
- //初始化串口0
- uart0_init(115200);
-
- // while(gd_eval_key_state_get(KEY_WAKEUP)==SET)
- // {
- // printf("please press wakeup_key to continue!\r\n");
- // delay_1ms(200);
- // }
- while(1){
- // /* turn on LED1, turn off LED4 */
- // gd_eval_led_on(LED1);
- // gd_eval_led_off(LED4);
- // delay_1ms(1000);
- // /* turn on LED2, turn off LED1 */
- // gd_eval_led_on(LED2);
- // gd_eval_led_off(LED1);
- // delay_1ms(1000);
- // /* turn on LED3, turn off LED2 */
- // gd_eval_led_on(LED3);
- // gd_eval_led_off(LED2);
- // delay_1ms(1000);
- // /* turn on LED4, turn off LED3 */
- // gd_eval_led_on(LED4);
- // gd_eval_led_off(LED3);
- // delay_1ms(1000);
-
-
- if(USART0_RX_STA&0x8000)
- {
- len=USART0_RX_STA&0x3fff;//得到此次接收到的数据长度
- printf("\r\n您发送的消息为:\r\n\r\n");
- for(t=0;t<len;t++)
- {
- usart_data_transmit(USART0,(uint8_t) USART0_RX_BUF[t]);//向串口1发送数据
- while(usart_flag_get(USART0, USART_FLAG_TBE)!=SET);//等待发送结束
- }
- printf("\r\n\r\n");//插入换行
- USART0_RX_STA=0;
- }else
- {
- times++;
- if(times%5000==0)
- {
- printf("\r\nGD32E230C8T6 串口实验\r\n");
- printf("----20210730----\r\n\r\n");
- }
- if(times%200==0)printf("请输入数据,以回车键结束\n");
- if(times%30==0)gd_eval_led_toggle(LED1);//闪烁LED,提示系统正在运行.
- delay_1ms(10);
- }
- }
- }
串口PRINTF重定义,别忘了勾选:
下载,编译,查看串口,并输入字符:
下面我们测试当前的ADC,我们选择PA2作为ADC的CH2,使用DMA,使用TIMER0作为外部触发(其内部与ADC触发引脚已相连)
我们写ADC初始化代码,我们设置ADC时钟为12M,采样点位220个,采样频率为TIMER0的PWM频率120K:
- void adc_init(void)
- {
- //////////////时钟初始化/////////////////
- /* enable the GPIO clock */
- //使能对应GPIO PIN时钟
- rcu_periph_clock_enable(RCU_GPIOA);
- /* ADCCLK = PCLK2/6 */
- //ADC时钟分频
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
- /* enable DMA clock */
- //使能DMA时钟
- rcu_periph_clock_enable(RCU_DMA);
- /* enable ADC clock */
- //使能ADC时钟
- rcu_periph_clock_enable(RCU_ADC);
- /* enable TIMER0 clock */
- //使能TIMER0时钟
- rcu_periph_clock_enable(RCU_TIMER0);
- /////////////配置输入引脚//////////////////////
- /* configure PA2(ADC channel2) as analog input */
- //配置PA2为模拟输入
- gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);
- //////////////配置DMA/////////////////////////
- dma_parameter_struct dma_init_struct;
- /* initialize DMA channel0 */
- dma_deinit(DMA_CH0);
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_addr = (uint32_t)ad_value;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
- dma_init_struct.number = sample_num;
- dma_init_struct.periph_addr = (uint32_t)&(ADC_RDATA);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_init(DMA_CH0, &dma_init_struct);
-
- /* configure DMA mode */
- dma_circulation_enable(DMA_CH0);
- dma_memory_to_memory_disable(DMA_CH0);
-
- /* enable DMA channel0 */
- dma_channel_enable(DMA_CH0);
-
- //////////////配置采样时钟TIMER0/////////////
- timer_oc_parameter_struct timer_ocintpara;
- timer_parameter_struct timer_initpara;
- timer_deinit(TIMER0);
- /* TIMER0 configuration */
- timer_initpara.prescaler = 5;
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 399;
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
- timer_initpara.repetitioncounter = 0;
- timer_init(TIMER0, &timer_initpara);
- /* CH0 configuration in PWM mode1 */
- timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW;
- timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
- timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);
- timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 100);
- timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1);
- timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
- /* auto-reload preload enable */
- timer_auto_reload_shadow_enable(TIMER0);
- timer_primary_output_config(TIMER0, ENABLE);
-
- /////////////////ADC配置///////////////////////////
- /* ADC channel length config */
- adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
- /* ADC regular channel config */
- adc_regular_channel_config(0, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
- /* ADC external trigger enable */
- adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
- /* ADC external trigger source config */
- adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T0_CH0);
- /* ADC data alignment config */
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
- /* enable ADC interface */
- adc_enable();
- /* ADC calibration and reset calibration */
- adc_calibration_enable();
- /* ADC DMA function enable */
- adc_dma_mode_enable();
- }
采样开启和关闭,通过开关TIMER0,累加220,然后求平均值,并串口输出:
- #include "usart0.h"
- void ADC_getvalue_Tast(void)
- {
- uint16_t i=0;
- uint32_t ADC_VALUE=0;
- float voltage_value=0.0;
- /* TIMER0 counter enable */
- //开启采样
- timer_enable(TIMER0);
- /* test on channel0 transfer complete flag */
- //等待设定的220个采样点结束
- while( !dma_flag_get(DMA_CH0, DMA_FLAG_FTF));
- /* clear channel0 transfer complete flag */
- dma_flag_clear(DMA_CH0, DMA_FLAG_FTF);
- /* TIMER0 counter disable */
- //关闭采样
- timer_disable(TIMER0);
- //串输出采样数值
-
- for(i=0;i<sample_num;i++)
- {
- ADC_VALUE=ad_value[i]*3300/4096+ADC_VALUE;//转换成mv
- }
-
- voltage_value=ADC_VALUE/sample_num*1.00;
- printf("the ADC_CH2 VOLTAGE IS : %.2f mv\r\n",voltage_value);
- }
具体代码:
ADC.H
- #ifndef __ADC_H_
- #define __ADC_H_
- #include "stdio.h"
- #include "gd32e23x.h"
- #include "gd32e230c_eval.h"
- #include "systick.h"
- #define sample_num 220 //定义采样点
- extern uint16_t ad_value[sample_num];
- void adc_init(void);
- void ADC_getvalue_Tast(void);
- #endif
ADC.C
- #include "adc.h"
- uint16_t ad_value[sample_num];
- //PA2 ADC_CH2
- void adc_init(void)
- {
- //////////////时钟初始化/////////////////
- /* enable the GPIO clock */
- //使能对应GPIO PIN时钟
- rcu_periph_clock_enable(RCU_GPIOA);
- /* ADCCLK = PCLK2/6 */
- //ADC时钟分频
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
- /* enable DMA clock */
- //使能DMA时钟
- rcu_periph_clock_enable(RCU_DMA);
- /* enable ADC clock */
- //使能ADC时钟
- rcu_periph_clock_enable(RCU_ADC);
- /* enable TIMER0 clock */
- //使能TIMER0时钟
- rcu_periph_clock_enable(RCU_TIMER0);
- /////////////配置输入引脚//////////////////////
- /* configure PA2(ADC channel2) as analog input */
- //配置PA2为模拟输入
- gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);
- //////////////配置DMA/////////////////////////
- dma_parameter_struct dma_init_struct;
- /* initialize DMA channel0 */
- dma_deinit(DMA_CH0);
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_addr = (uint32_t)ad_value;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
- dma_init_struct.number = sample_num;
- dma_init_struct.periph_addr = (uint32_t)&(ADC_RDATA);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_init(DMA_CH0, &dma_init_struct);
-
- /* configure DMA mode */
- dma_circulation_enable(DMA_CH0);
- dma_memory_to_memory_disable(DMA_CH0);
-
- /* enable DMA channel0 */
- dma_channel_enable(DMA_CH0);
-
- //////////////配置采样时钟TIMER0/////////////
- timer_oc_parameter_struct timer_ocintpara;
- timer_parameter_struct timer_initpara;
- timer_deinit(TIMER0);
- /* TIMER0 configuration */
- timer_initpara.prescaler = 5;
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 399;
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
- timer_initpara.repetitioncounter = 0;
- timer_init(TIMER0, &timer_initpara);
- /* CH0 configuration in PWM mode1 */
- timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW;
- timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
- timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);
- timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 100);
- timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1);
- timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
- /* auto-reload preload enable */
- timer_auto_reload_shadow_enable(TIMER0);
- timer_primary_output_config(TIMER0, ENABLE);
-
- /////////////////ADC配置///////////////////////////
- /* ADC channel length config */
- adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
- /* ADC regular channel config */
- adc_regular_channel_config(0, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
- /* ADC external trigger enable */
- adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
- /* ADC external trigger source config */
- adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T0_CH0);
- /* ADC data alignment config */
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
- /* enable ADC interface */
- adc_enable();
- /* ADC calibration and reset calibration */
- adc_calibration_enable();
- /* ADC DMA function enable */
- adc_dma_mode_enable();
- }
- #include "usart0.h"
- void ADC_getvalue_Tast(void)
- {
- uint16_t i=0;
- uint32_t ADC_VALUE=0;
- float voltage_value=0.0;
- /* TIMER0 counter enable */
- //开启采样
- timer_enable(TIMER0);
- /* test on channel0 transfer complete flag */
- //等待设定的220个采样点结束
- while( !dma_flag_get(DMA_CH0, DMA_FLAG_FTF));
- /* clear channel0 transfer complete flag */
- dma_flag_clear(DMA_CH0, DMA_FLAG_FTF);
- /* TIMER0 counter disable */
- //关闭采样
- timer_disable(TIMER0);
- //串输出采样数值
-
- for(i=0;i<sample_num;i++)
- {
- ADC_VALUE=ad_value[i]*3300/4096+ADC_VALUE;//转换成mv
- }
-
- voltage_value=ADC_VALUE/sample_num*1.00;
- printf("the ADC_CH2 VOLTAGE IS : %.2f mv\r\n",voltage_value);
- }
main函数里面调用:
- //初始化ADC
- adc_init();
- .......
- while(1)
- {
- ADC_getvalue_Tast();
- delay_1ms(1000);
- }
调试下载。并分别测试0V和3.3V
好了,基本的测试先到这~
总体而言没发现啥特别,上手也不难,库写的可读写也可以。
总而言之,国产MCU与国外的差距越来越小了~
|
打赏榜单
21小跑堂 打赏了 50.00 元 2021-07-30 理由:恭喜通过原创文章审核!请多多加油哦!
|