- void led_init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __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);
- }
- void key_init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __RCC_GPIOA_CLK_ENABLE();
- GPIO_InitStruct.IT = GPIO_IT_NONE;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pins = GPIO_PIN_1 | GPIO_PIN_2;
- GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
- }
- int32_t main(void)
- {
- RCC_HSI_48M_init();
- RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
- RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
- led_init();
- key_init();
- while (1)
- {
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1) == GPIO_Pin_RESET)
- {
- yuyy_delay_ms(10);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1) == GPIO_Pin_RESET)
- {
- while(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1) == GPIO_Pin_RESET);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
- }
- }
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET)
- {
- yuyy_delay_ms(10);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET)
- {
- while(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
- }
- }
- }
- }
运行效果
中断方式,CW32L031的GPIO中断可以配置为上升沿或下降沿触发(虽然cw32l031_gpio.h有高低电平的中断参数定义但并无效果,手册中也没写支持电平中断),按键按下时从高电平变为低电平时会触发下降沿中断,CW32L031的中断可以配置滤波功能,通过滤波实现去抖
- void key_init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __RCC_GPIOA_CLK_ENABLE();
- GPIO_InitStruct.IT = GPIO_IT_FALLING;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pins = GPIO_PIN_1 | GPIO_PIN_2;
- GPIO_Init(CW_GPIOA, &GPIO_InitStruct);
- GPIO_ConfigFilter(CW_GPIOA,GPIO_PIN_1 | GPIO_PIN_2,GPIO_FLTCLK_RC150K);
- GPIOA_INTFLAG_CLR(bv1| bv2);
- NVIC_EnableIRQ(GPIOA_IRQn);
- }
- void GPIOA_IRQHandler(void)
- {
- if (CW_GPIOA->ISR_f.PIN1)
- {
- GPIOA_INTFLAG_CLR(bv1);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1) == GPIO_Pin_RESET)
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
- }
- if (CW_GPIOA->ISR_f.PIN2)
- {
- GPIOA_INTFLAG_CLR(bv2);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET)
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
- }
- }
- int32_t main(void)
- {
- RCC_HSI_48M_init();
- RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
- RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
- led_init();
- key_init();
- while (1)
- {
- }
- }
运行效果
定时器的使用
CW32L031拥有三个基本定时器(BTIM)两个通用定时器(GTIM)和一个高级定时器(ATIM),先用BTIM做一个控制LED以1Hz闪烁的定时器
- void btim1_init()
- {
- BTIM_TimeBaseInitTypeDef BTIM_InitStruct = {0};
- __RCC_BTIM_CLK_ENABLE();
- BTIM_InitStruct.BTIM_Mode = BTIM_Mode_TIMER;
- BTIM_InitStruct.BTIM_Period = 50000 - 1;
- BTIM_InitStruct.BTIM_Prescaler = 480 - 1;
- BTIM_TimeBaseInit(CW_BTIM1, &BTIM_InitStruct);
- BTIM_ITConfig(CW_BTIM1, BTIM_IT_OV, ENABLE);
- BTIM_Cmd(CW_BTIM1, ENABLE);
- NVIC_EnableIRQ(BTIM1_IRQn);
- }
- void BTIM1_IRQHandler(void)
- {
- if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
- {
- BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
- }
- }
- int32_t main(void)
- {
-
- RCC_HSI_48M_init();
- RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
- RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
- led_init();
- btim1_init();
- while (1)
- {
- }
- }
运行效果
通用定时器和高级定时器都有PWM输出功能,可以通过调节PWM占空比来调节LED亮度,评估板上的2个LED分别对应GTIM1的CH3和CH4,接下来写个程序使用按键调节LED亮度
- void led_init()
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __RCC_GPIOB_CLK_ENABLE();
- PB08_AFx_GTIM1CH3();
- PB09_AFx_GTIM1CH4();
- 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);
- }
- void gtim1_pwm_init()
- {
- GTIM_InitTypeDef GTIM_InitStruct = {0};
- __RCC_GTIM1_CLK_ENABLE();
- GTIM_InitStruct.Mode = GTIM_MODE_TIME;
- GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;
- GTIM_InitStruct.Prescaler = 48 - 1;
- GTIM_InitStruct.ReloadValue = 1000 - 1;
- GTIM_InitStruct.ToggleOutState = DISABLE;
- GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);
- GTIM_OCInit(CW_GTIM1, GTIM_CHANNEL3, GTIM_OC_OUTPUT_PWM_LOW);
- GTIM_OCInit(CW_GTIM1, GTIM_CHANNEL4, GTIM_OC_OUTPUT_PWM_LOW);
- GTIM_SetCompare3(CW_GTIM1, 0);
- GTIM_SetCompare4(CW_GTIM1, 0);
- GTIM_Cmd(CW_GTIM1, ENABLE);
- }
- uint16_t pwm = 0;
- void GPIOA_IRQHandler(void)
- {
- if (CW_GPIOA->ISR_f.PIN1)
- {
- GPIOA_INTFLAG_CLR(bv1);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_1) == GPIO_Pin_RESET)
- {
- if(pwm<1000-100)
- pwm += 100;
- else
- pwm = 1000;
- GTIM_SetCompare3(CW_GTIM1, pwm);
- GTIM_SetCompare4(CW_GTIM1, pwm);
- }
- }
- if (CW_GPIOA->ISR_f.PIN2)
- {
- GPIOA_INTFLAG_CLR(bv2);
- if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET)
- {
- if(pwm > 100)
- pwm -= 100;
- else
- pwm = 0;
- GTIM_SetCompare3(CW_GTIM1, pwm);
- GTIM_SetCompare4(CW_GTIM1, pwm);
- }
- }
- }
编译又有2处优先级警告,找到相关代码处加上括号就好了
运行效果
定时器还可以级联使用来实现更长时间幅度的定时,下面尝试用BTIM和GTIM级联实现1秒的定时器,用BTIM的溢出信号作为GTIM的时钟源
- void btim1_init()
- {
- BTIM_TimeBaseInitTypeDef BTIM_InitStruct = {0};
- __RCC_BTIM_CLK_ENABLE();
- BTIM_InitStruct.BTIM_Mode = BTIM_Mode_TIMER;
- BTIM_InitStruct.BTIM_Period = 1000 - 1;
- BTIM_InitStruct.BTIM_Prescaler = 48 - 1;
- BTIM_TimeBaseInit(CW_BTIM1, &BTIM_InitStruct);
- BTIM_Cmd(CW_BTIM1, ENABLE);
- }
- void gtim1_counter_init()
- {
- GTIM_InitTypeDef GTIM_InitStruct = {0};
- __RCC_GTIM1_CLK_ENABLE();
- GTIM_InitStruct.Mode = GTIM_MODE_COUNTER;
- GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;
- GTIM_InitStruct.Prescaler = 1;
- GTIM_InitStruct.ReloadValue = 1000 - 1;
- GTIM_InitStruct.ToggleOutState = DISABLE;
- GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct);
- GTIM1_ITRConfig(ITR_SOURCE_BTIM1);
- GTIM_ITConfig(CW_GTIM1, GTIM_IT_OV, ENABLE);
- GTIM_Cmd(CW_GTIM1, ENABLE);
- NVIC_EnableIRQ(GTIM1_IRQn);
- }
- void GTIM1_IRQHandler(void)
- {
- if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_OV))
- {
- GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_OV);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8);
- GPIO_TogglePin(CW_GPIOB, GPIO_PIN_9);
- }
- }
运行效果