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

[复制链接]
 楼主| yuyy1989 发表于 2023-9-24 12:23 | 显示全部楼层 |阅读模式
#申请原创# @21小跑堂  

时钟系统
CW32L031可用的时钟源有4个:
1.外部高速振荡器时钟(HSE),板子上接的是16MHz的晶振
2.外部低速振荡器时钟(LSE),板子上接的是32.768KHz的晶振
3.HSI 时钟,由内部高速 RC 振荡器时钟(HSIOSC)经过分频产生
4.内部低速 RC 振荡器时钟(LSI)
QQ截图20230924104844.png
当不做任何配置时,通电后默认使用HSIOSC经过6分频输出的8MHz的HSI时钟,接下来用不同的时钟源初始化
  1. void RCC_HSI_48M_init()
  2. {
  3.     //< 当使用的时钟源HCLK大于24M,小于等于48MHz:设置FLASH 读等待周期为2 cycle >
  4.     __RCC_FLASH_CLK_ENABLE();
  5.     FLASH_SetLatency(FLASH_Latency_2);
  6.     /* HSI使能 */
  7.     RCC_HSI_Enable(RCC_HSIOSC_DIV1); //1分频要在设置之前设置FLASH读等待周期
  8.     RCC_SystemCoreClockUpdate(48000000);
  9. }

  10. void RCC_HSE_16M_init()
  11. {
  12.     RCC_HSE_Enable( RCC_HSE_MODE_OSC, 16000000, RCC_HSE_DRIVER_NORMAL, RCC_HSE_FLT_CLOSE);
  13.     RCC_SysClk_Switch( RCC_SYSCLKSRC_HSE );
  14.     __RCC_FLASH_CLK_ENABLE();
  15.     FLASH_SetLatency(FLASH_Latency_1);
  16.     RCC_HSI_Disable();
  17.     RCC_SystemCoreClockUpdate(16000000);
  18. }

  19. void RCC_LSI_init()
  20. {
  21.     RCC_LSI_Enable();
  22.     RCC_SysClk_Switch(RCC_SYSCLKSRC_LSI);
  23.     __RCC_FLASH_CLK_ENABLE();
  24.     FLASH_SetLatency(FLASH_Latency_1);
  25.     RCC_HSI_Disable();
  26.     RCC_SystemCoreClockUpdate(32800);
  27. }

  28. void RCC_LSE_init()
  29. {
  30.     RCC_LSE_Enable(RCC_LSE_MODE_OSC,RCC_LSE_AMP_LARGER,RCC_LSE_DRIVER_LARGER);
  31.     RCC_SysClk_Switch(RCC_SYSCLKSRC_LSE);
  32.     __RCC_FLASH_CLK_ENABLE();
  33.     FLASH_SetLatency(FLASH_Latency_1);
  34.     RCC_HSI_Disable();
  35.     RCC_SystemCoreClockUpdate(32768);
  36. }

  37. int32_t main(void)
  38. {
  39.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  40.     RCC_HSI_48M_init();
  41.     //RCC_HSE_16M_init();
  42.     //RCC_LSI_init();
  43.     //RCC_LSE_init();
  44.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  45.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  46.     __RCC_GPIOB_CLK_ENABLE();
  47.     GPIO_InitStruct.IT = GPIO_IT_NONE;
  48.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  49.     GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
  50.     GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  51.     while (1)
  52.     {
  53.         GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
  54.         FirmwareDelay(0x40000);
  55.         GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
  56.         FirmwareDelay(0x40000);
  57.     }
  58. }
FirmwareDelay这个方法在system_cw32l031.c中,定义如下:
QQ截图20230924112535.png
在不同的时钟速度下延时的实际时间也不同,LED闪烁的频率也就不同
默认8MHz时
WeChat_20230924113418 00_00_00-00_00_30.gif
HSI 48MHz时
WeChat_20230924113428 00_00_00-00_00_30.gif
HSE 16MHz时
WeChat_20230924113434 00_00_00-00_00_30.gif
在使用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上的,这时候想要点亮它就要用到推挽模式
QQ截图20230924114206.png
使用CW32的库函数可以方便的设置GPIO的模式
  1. int32_t main(void)
  2. {
  3.     RCC_HSI_48M_init();
  4.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  5.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  6.     __RCC_GPIOB_CLK_ENABLE();
  7.     PB08_DIGTAL_ENABLE();
  8.     PB09_DIGTAL_ENABLE();
  9.     PB08_DIR_OUTPUT();
  10.     PB09_DIR_OUTPUT();
  11.     PB08_PUSHPULL_ENABLE();
  12.     PB09_PUSHPULL_ENABLE();
  13.     PB08_SETLOW();
  14.     PB09_SETLOW();

  15.     while (1)
  16.     {
  17.         PB08_TOG();
  18.         yuyy_delay_ms(250);
  19.         PB09_TOG();
  20.         yuyy_delay_ms(250);
  21.     }
  22. }
或者使用另外一种形式,效果都一样
  1. int32_t main(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.     RCC_HSI_48M_init();
  5.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  6.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  7.     __RCC_GPIOB_CLK_ENABLE();
  8.     GPIO_InitStruct.IT = GPIO_IT_NONE;
  9.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  10.     GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
  11.     GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  12.     GPIO_WritePin(CW_GPIOB,GPIO_PIN_8 | GPIO_PIN_9,GPIO_Pin_RESET);
  13.     while (1)
  14.     {
  15.         GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
  16.         yuyy_delay_ms(250);
  17.         GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
  18.         yuyy_delay_ms(250);
  19.     }
  20. }
运行效果
WeChat_20230924120245 00_00_00-00_00_30.gif
数字输入模式下MCU可以通过IO读取外部输入的高低电平,电流向MCU流入,可以配置上拉或下拉电阻来设定默认输入电平,高低电平的改变可以触发中断
评估板上的2个按键已经接了上拉电阻,默认输入为高电平,简单测试一下,根据按键输入电平设置LED输出电平
  1. int32_t main(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.     RCC_HSI_48M_init();
  5.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  6.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  7.     __RCC_GPIOA_CLK_ENABLE();
  8.     __RCC_GPIOB_CLK_ENABLE();
  9.     GPIO_InitStruct.IT = GPIO_IT_NONE;
  10.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  11.     GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
  12.     GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
  13.     GPIO_WritePin(CW_GPIOB,GPIO_PIN_8 | GPIO_PIN_9,GPIO_Pin_RESET);
  14.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  15.     GPIO_InitStruct.Pins = GPIO_PIN_1 | GPIO_PIN_2;
  16.     GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
  17.     while (1)
  18.     {
  19.         GPIO_WritePin(CW_GPIOB,GPIO_PIN_8,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1));
  20.         GPIO_WritePin(CW_GPIOB,GPIO_PIN_9,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2));
  21.     }
  22. }
运行效果
WeChat_20230924121528 00_00_00-00_00_30.gif

happypcb 发表于 2023-9-25 13:31 | 显示全部楼层
很不错的开发板评测贴,过来学习一下,给楼主点个赞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部