#申请原创# @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));
}
}
运行效果
|