打印
[开发板]

【CW32L031CxTx StartKit评估板测评】3.熟悉时钟系统与GPIO

[复制链接]
720|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  

时钟系统
CW32L031可用的时钟源有4个:
1.外部高速振荡器时钟(HSE),板子上接的是16MHz的晶振
2.外部低速振荡器时钟(LSE),板子上接的是32.768KHz的晶振
3.HSI 时钟,由内部高速 RC 振荡器时钟(HSIOSC)经过分频产生
4.内部低速 RC 振荡器时钟(LSI)

当不做任何配置时,通电后默认使用HSIOSC经过6分频输出的8MHz的HSI时钟,接下来用不同的时钟源初始化
void RCC_HSI_48M_init()
{
    //< 当使用的时钟源HCLK大于24M,小于等于48MHz:设置FLASH 读等待周期为2 cycle >
    __RCC_FLASH_CLK_ENABLE();
    FLASH_SetLatency(FLASH_Latency_2);
    /* HSI使能 */
    RCC_HSI_Enable(RCC_HSIOSC_DIV1); //1分频要在设置之前设置FLASH读等待周期
    RCC_SystemCoreClockUpdate(48000000);
}

void RCC_HSE_16M_init()
{
    RCC_HSE_Enable( RCC_HSE_MODE_OSC, 16000000, RCC_HSE_DRIVER_NORMAL, RCC_HSE_FLT_CLOSE);
    RCC_SysClk_Switch( RCC_SYSCLKSRC_HSE );
    __RCC_FLASH_CLK_ENABLE();
    FLASH_SetLatency(FLASH_Latency_1);
    RCC_HSI_Disable();
    RCC_SystemCoreClockUpdate(16000000);
}

void RCC_LSI_init()
{
    RCC_LSI_Enable();
    RCC_SysClk_Switch(RCC_SYSCLKSRC_LSI);
    __RCC_FLASH_CLK_ENABLE();
    FLASH_SetLatency(FLASH_Latency_1);
    RCC_HSI_Disable();
    RCC_SystemCoreClockUpdate(32800);
}

void RCC_LSE_init()
{
    RCC_LSE_Enable(RCC_LSE_MODE_OSC,RCC_LSE_AMP_LARGER,RCC_LSE_DRIVER_LARGER);
    RCC_SysClk_Switch(RCC_SYSCLKSRC_LSE);
    __RCC_FLASH_CLK_ENABLE();
    FLASH_SetLatency(FLASH_Latency_1);
    RCC_HSI_Disable();
    RCC_SystemCoreClockUpdate(32768);
}

int32_t main(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_HSI_48M_init();
    //RCC_HSE_16M_init();
    //RCC_LSI_init();
    //RCC_LSE_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOB_CLK_ENABLE();
    GPIO_InitStruct.IT = GPIO_IT_NONE;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
    while (1)
    {
        GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
        FirmwareDelay(0x40000);
        GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
        FirmwareDelay(0x40000);
    }
}
FirmwareDelay这个方法在system_cw32l031.c中,定义如下:

在不同的时钟速度下延时的实际时间也不同,LED闪烁的频率也就不同
默认8MHz时

HSI 48MHz时

HSE 16MHz时

在使用LSE或LSI时可以将延时的参数减小,不然很长时间都不会看到LED变化,另外如果有示波器可以配置MCO_OUT输出HCLK,通过MCO_OUT引脚(PA04 PA08 PC15)查看时钟波形
GPIO
GPIO 控制器实现芯片内部各类数字和模拟电路与物理引脚之间的联系。CW32L031的GPIO 可配置为数字输入输出和模拟功能,支持外设功能复用,支持上升沿和下降沿 2 种中断源,可在深度休眠模式下通过外部中断唤醒 MCU 回到运行模式。
数字输出模式下可以配置为择推挽输出或开漏输出
推挽输出:这种模式下IO可以直接输出高低电平,高电平时可以向外输出电流,输出高电平电压与VCC保持一致,需要注意连接的受控设备的IO电压承受范围
开漏输出:这种模式下IO不能真正的输出高电平,需要借助上拉电阻来实现高电平输出,输出高电平电压取决于上拉电阻所接的电源,这种模式下可以实现电平的转换,通过读取输入寄存器的值可以获得真实的高低电平,在I2C和一些单线通讯(DHT11、DS18B20等)的场景下就可以用这个模式,这个模式下还可以实现线与的效果
评估板上的LED是直接接在IO上的,这时候想要点亮它就要用到推挽模式

使用CW32的库函数可以方便的设置GPIO的模式
int32_t main(void)
{
    RCC_HSI_48M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOB_CLK_ENABLE();
    PB08_DIGTAL_ENABLE();
    PB09_DIGTAL_ENABLE();
    PB08_DIR_OUTPUT();
    PB09_DIR_OUTPUT();
    PB08_PUSHPULL_ENABLE();
    PB09_PUSHPULL_ENABLE();
    PB08_SETLOW();
    PB09_SETLOW();

    while (1)
    {
        PB08_TOG();
        yuyy_delay_ms(250);
        PB09_TOG();
        yuyy_delay_ms(250);
    }
}
或者使用另外一种形式,效果都一样
int32_t main(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_HSI_48M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOB_CLK_ENABLE();
    GPIO_InitStruct.IT = GPIO_IT_NONE;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
    GPIO_WritePin(CW_GPIOB,GPIO_PIN_8 | GPIO_PIN_9,GPIO_Pin_RESET);
    while (1)
    {
        GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
        yuyy_delay_ms(250);
        GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
        yuyy_delay_ms(250);
    }
}
运行效果

数字输入模式下MCU可以通过IO读取外部输入的高低电平,电流向MCU流入,可以配置上拉或下拉电阻来设定默认输入电平,高低电平的改变可以触发中断
评估板上的2个按键已经接了上拉电阻,默认输入为高电平,简单测试一下,根据按键输入电平设置LED输出电平
int32_t main(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_HSI_48M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOA_CLK_ENABLE();
    __RCC_GPIOB_CLK_ENABLE();
    GPIO_InitStruct.IT = GPIO_IT_NONE;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
    GPIO_WritePin(CW_GPIOB,GPIO_PIN_8 | GPIO_PIN_9,GPIO_Pin_RESET);
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pins = GPIO_PIN_1 | GPIO_PIN_2;
    GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
    while (1)
    {
        GPIO_WritePin(CW_GPIOB,GPIO_PIN_8,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1));
        GPIO_WritePin(CW_GPIOB,GPIO_PIN_9,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2));
    }
}
运行效果


使用特权

评论回复
沙发
happypcb| | 2023-9-25 13:31 | 只看该作者
很不错的开发板评测贴,过来学习一下,给楼主点个赞

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

149

主题

708

帖子

7

粉丝