L-MCU 发表于 2024-7-3 15:22

CH32L103 GPIO和DMA应用

1、GPIO介绍关于CH32L103的GPIO引脚,其中,PA11/PA12作为USB的IO引脚时,有两套互斥的上拉和下拉电阻,在进行电路设计时,无需外接上下拉电阻;同理,PB6/7作为USB PD的IO引脚时,有两套相互独立的上拉和下拉电阻,电路设计上可以进行一定的简化。关于GPIO的具体介绍,可看CH32L103应用手册。GPIO作为最常用的外设,此处主要介绍一种功能—锁定机制。锁定机制可以锁定 IO 口的配置。经过特定的一个写序列后,选定的 IO 引脚配置将被锁定,在下一个复位前无法更改。锁定机制使用代码如下:/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2023/12/26
* Description      : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/

/*
*@Note
*GPIO routine:
*PA0 push-pull output.
*
*/

#include "debug.h"

/* Global define */

/* Global Variable */

/*********************************************************************
* @fn      GPIO_Toggle_INIT
*
* @brief   Initializes GPIOA.0
*
* @returnnone
*/
void GPIO_Toggle_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void GPIO_IN_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************
* @fn      main
*
* @brief   Main program.
*
* @returnnone
*/
int main(void)
{
    vu8 i = 0;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("GPIO Toggle TEST\r\n");
    GPIO_Toggle_INIT();

    GPIO_PinLockConfig(GPIOA,GPIO_Pin_0);

    GPIO_IN_INIT();

    while(1)
    {
      Delay_Ms(250);
      GPIO_WriteBit(GPIOA, GPIO_Pin_0, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
    }
}程序中,当调用GPIO_PinLockConfig函数对PA0引脚进行锁定之后,PA0的配置不会被改变,即便后面将其进行浮空输入初始化配置,由于锁定,也不会生效,按照之前的输出配置进行运行,PA0引脚会250ms翻转一次,如下图: GPIO_PinLockConfig函数主要对配置锁定寄存器(GPIOx_LCKR)进行配置,该寄存器具体介绍如下: GPIO可配置8种工作模式,关于这8种工作模式的具体介绍,可参考下链接帖子讲解:https://www.cnblogs.com/liaigu/p/17787234.html
2、DMA介绍DMA全称为直接存储器访问控制器,可以提供在外设和存储器之间或存储器与存储器之间的高速数据传输方式,无需CPU的干预,可以节省CPU资源用于其他操作。关于DMA的具体介绍,可看CH32L103应用手册。DMA的数据传输方式有两种模式:正常模式和循环模式
[*]DMA_Mode_Normal,当DMA通道配置为正常(不循环)模式时,传输结束(DMA通道传输数量寄存器变为0)后将不再产生DMA操作。要开启新的DMA传输,需要进行以下操作配置:在关闭DMA通道后,为DMA通道传输数量寄存器重新赋值,然后重新开启DMA。
[*]DMA_Mode_Circular,当DMA通道配置为循环模式时,最后一次传输结束后,DMA通道传输数量寄存器将会自动重新加载为之前配置时的数值。内部的当前外设/存储器地址寄存器也被重新加载为外设/存储器地址寄存器设定的初始基地址。
关于DMA的应用,CH32L103 EVT提供了外设和存储器之间以及存储器和存储器之间数据传输的例程,具体可参考对应例程。
附件为GPIO锁定机制测试例程,可以参考一下。

tpgf 发表于 2024-9-3 15:37

在使用GPIO时,需要注意引脚图示,避免将输入输出模式配置错误

caigang13 发表于 2024-9-3 16:10

DMA主要用于需要大量数据交互的外设中,能够提高处理效率。

guanjiaer 发表于 2024-9-17 22:31

CH32L103的GPIO具有锁定机制,可以通过特定的写序列锁定IO口的配置,防止在复位前被更改

heimaojingzhang 发表于 2024-9-19 11:30

每个DMA通道都可以在传输过半、完成和出错时产生中断,这为应用程序提供了极大的灵活性

keaibukelian 发表于 2024-9-23 08:46

每个DMA通道都可以在传输过半、完成和出错时产生中断,这为应用程序提供了极大的灵活性

paotangsan 发表于 2024-9-24 07:11

DMA支持多通道操作,可以同时进行多个独立的数据传输任务

renzheshengui 发表于 2024-9-24 15:32

利用DMA和GPIO配合,可以实现高效的ADC多通道数据采集。具体来说,通过GPIO配置ADC通道为模拟输入,然后利用DMA将ADC转换结果直接传输到内存中指定的数组

kzlzqi 发表于 2025-2-9 13:31

在 CH32L103 中,锁定机制可以通过特定的写序列将 GPIO 引脚的配置锁定。
页: [1]
查看完整版本: CH32L103 GPIO和DMA应用