CH32库函数学习——CH32GPIO点亮LED(4)

CH32F2070----GPIO

  • 前言
  • 一、CH32F207?
  • 二、GPIO?
  • 三、初始化函数
    • 1.GPIO_INIT()
    • 2.最基本配置GPIO点亮LED
  • 四、重要函数
  • 五、主函数


前言

感谢沁恒的开发板用于学习,通过学习CH32来掌握标准库函数,虽然stm32现在都在主推HAL库,国产32还是在使用标注库,通过学习ch32来巩固标注库的相关内容。ch32与stm32高度相似,GPIO内部结构一样,对于内部原理不在一一概述,重点对标准库函数进行记录。


一、CH32F207?

CH32F205/7系列是基于Cortex-M3内核设计的工业级互联型微控制器,此系列主频高达144MHz,独立了GPIO电压(与系统供电分离)。资源同比增加了随机数单元,4组运放比较器;提高串口UART数量到8组,电机定时器到4组。搭配时钟安全、电源管理、双组DMA、DAC、SDIO、CAN、FSMC等资源。提供USB2.0高速接口(480Mbps)并内置了PHY收发器,以太网MAC升级到千兆并集成了10M-PHY模块。(其中ADC为16位,之前使用过的stm32f446只有12位,不知道stm32有没有16位ADC的单片机)

二、GPIO?

GPIO(general porpose intput output):通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能。
CH32库函数学习——CH32GPIO点亮LED(4)_第1张图片

三、初始化函数

1.GPIO_INIT()

GPIO_Init( GPIO_TypeDef GPIOx, GPIO_InitTypeDefGPIO_InitStruct )

void GPIO_Init( GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct )
{
    uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
    uint32_t tmpreg = 0x00, pinmask = 0x00;

    currentmode = ( ( uint32_t )GPIO_InitStruct->GPIO_Mode ) & ( ( uint32_t )0x0F );

    if( ( ( ( uint32_t )GPIO_InitStruct->GPIO_Mode ) & ( ( uint32_t )0x10 ) ) != 0x00 )
    {
        currentmode |= ( uint32_t )GPIO_InitStruct->GPIO_Speed;
    }

#if defined (CH32F20x_D6)	
		if(((*(uint32_t *) 0x40022030) & 0x0F000000) == 0)
		{
				MCU_Version = 1;
		}
		
		if((GPIOx == GPIOC) && MCU_Version){
				GPIO_InitStruct->GPIO_Pin = GPIO_InitStruct->GPIO_Pin >> 13;
		}
	
#endif
		
    if( ( ( uint32_t )GPIO_InitStruct->GPIO_Pin & ( ( uint32_t )0x00FF ) ) != 0x00 )
    {
        tmpreg = GPIOx->CFGLR;

        for( pinpos = 0x00; pinpos < 0x08; pinpos++ ){
            pos = ( ( uint32_t )0x01 ) << pinpos;
            currentpin = ( GPIO_InitStruct->GPIO_Pin ) & pos;

            if( currentpin == pos )
            {
                pos = pinpos << 2;
                pinmask = ( ( uint32_t )0x0F ) << pos;
                tmpreg &= ~pinmask;
                tmpreg |= ( currentmode << pos );

                if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD )
                {
                    GPIOx->BCR = ( ( ( uint32_t )0x01 ) << pinpos );
                }
                else
                {
                    if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU )
                    {
                        GPIOx->BSHR = ( ( ( uint32_t )0x01 ) << pinpos );
                    }
                }
            }
        }
        GPIOx->CFGLR = tmpreg;
    }

    if( GPIO_InitStruct->GPIO_Pin > 0x00FF )
    {
        tmpreg = GPIOx->CFGHR;

        for( pinpos = 0x00; pinpos < 0x08; pinpos++ ){
            pos = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
            currentpin = ( ( GPIO_InitStruct->GPIO_Pin ) & pos );

            if( currentpin == pos )
            {
                pos = pinpos << 2;
                pinmask = ( ( uint32_t )0x0F ) << pos;
                tmpreg &= ~pinmask;
                tmpreg |= ( currentmode << pos );

                if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD )
                {
                    GPIOx->BCR = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
                }

                if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU )
                {
                    GPIOx->BSHR = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
                }
            }
        }
        GPIOx->CFGHR = tmpreg;
    }
}

GPIO_Init()函数为GPIO的初始化函数,函数里有两个参数,GPIOx(显而易见x为任一项)用于指定那一组IO口,第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef,用结构体来定义GPIO的相关参数。
结构体相关成员:

typedef struct
{
 uint16_t GPIO_Pin;             /* 指明GPIO的引脚
                                   This parameter can be any value of @ref GPIO_pins_define */

 GPIOSpeed_TypeDef GPIO_Speed;  /* GPIO的引脚速度.
                                   This parameter can be a value of @ref GPIOSpeed_TypeDef */

 GPIOMode_TypeDef GPIO_Mode;    /* 指明GPIO的引脚模式.
                                   This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

GPIO_Speed:GPIO_Speed_10MHz, GPIO_Speed_2MHz, GPIO_Speed_50MHz
GPIO_Mode:

GPIO_Mode_AIN = 0x0, //模拟输入
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入
GPIO_Mode_IPD = 0x28, //下拉输入
GPIO_Mode_IPU = 0x48, //上拉输入
GPIO_Mode_Out_OD = 0x14, //开漏输出
GPIO_Mode_Out_PP = 0x10, //通用推挽输出
GPIO_Mode_AF_OD = 0x1C, //复用开漏输出
GPIO_Mode_AF_PP = 0x18 //复用推挽码片`
  • 其中在输入模式时,输出被禁止。可通过输入数据寄存器GPIOx_IDR 读取 I/O 状态。
  • 输入模式可以配置为模拟、上拉、下拉以及浮空模式。
  • 上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。
  • 浮空输入的电平是不确定的,完全由外部的输入决定。
  • 模拟输入则用于 ADC 采集。

2.最基本配置GPIO点亮LED

  1. 定义结构体名称 GPIO_InitTypeDef GPIO_InitStructure;
  2. 使能GPIO的时钟,使用每一种外设都要使能其时钟RCC_APB2PeriphClockCmd(对于是APB2还是APB1总线在系统时钟篇介绍)
  3. 调用GPIO_Init()函数初始化GPIO
  4. 设置GPIO初始电平

代码如下(示例):

void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE); //使能 PB,PE 端口时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 推挽输出
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高
}

四、重要函数

void GPIO_DeInit(GPIO_TypeDef* GPIOx);//释放初始化
void GPIO_AFIODeInit(void);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);//初始化函数
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读取输入模式管脚的电平
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);//读取输入模式GPIO一组的电平
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//读取输出模式管脚的电平
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);//读取输出模式GPIO一组的电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//设置管脚的电平为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//设置管脚的电平为低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//写管脚的高低电平
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//写GPIO一组的电平
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);//
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

五、主函数

//PE5间断点亮LED
int main( void )
{
    u8 i = 0;

    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 );
    Delay_Init();
    USART_Printf_Init( 115200 );
	LED_Init();
//    printf( "SystemClk:%d\r\n", SystemCoreClock );

//    printf( "GPIO Toggle TEST\r\n" );
//    GPIO_Toggle_INIT();

    while( 1 )
    {
        Delay_Ms(250);
		LED1=!LED1;
    }
}

PE5跳线短接LED
CH32库函数学习——CH32GPIO点亮LED(4)_第2张图片

工程源码

你可能感兴趣的:(单片机,stm32,嵌入式硬件)