×
嵌入式开发 > 详情

工程师STM32单片机学习手记(3):修修改改玩串口

发布时间:2020-06-29 发布时间:
|

STM学习笔记——用定时器实现荧火虫灯

在第6篇笔记中,我用软件延时的方法实现了荧火虫,学了定时器,当然就要用一用定时器了,这里仍是用荧火虫灯为例。

用ST库所带的例子Tim中的TimBase为例来修改,这个例子的位置以及如何建立工程请参考第7篇笔记,这里就不再重复了,下面简述一下修改的过程。

(1) 由于我的板子上的灯是由PD8~PD11来控制的,因此,要将

void RCC_Configuration(void)

中的:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开GPIOC的时钟

改为

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //打开GPIOD的时钟

(2) 将四个通道全部设置为TIM_OCMode_Toggle模式,即将

/* Output Compare Timing Mode configuration: Channel1 *

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;

改为:

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;

(3)例子中原来中断产生的频率很低,是不适合于做这种荧火虫灯的,但为了比较,我只改了最后一个值:

__IO uint16_t CCR4_Val = 8192;改为

__IO uint16_t CCR4_Val = 2048;

这样,这个通道的中断频率变为

CC4 update rate = TIM2 counter clock / CCR4_Val = 3515.6 Hz

(4) 到stm32f10x_it.c中作修改中断处理函数如下:

uint8_t allCount=16;

uint8_t upDown1,upDown2,upDown3,upDown4;

void TIM2_IRQHandler(void)

{ static uint8_t Count1,Count2,Count3,Count4;

static uint8_t hCnt1,hCnt2,hCnt3,hCnt4;

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

if(Count1《hCnt1)

{ GPIO_SetBits(GPIOD, GPIO_Pin_8); //点亮灯

}

else

{ GPIO_ResetBits(GPIOD, GPIO_Pin_8); //熄灭灯

}

Count1++;

if(Count1》=allCount)

{ Count1=0;

if(upDown1)

{ hCnt1++;

if(hCnt1》=(allCount-1))

upDown1=!upDown1;

}

else

{ hCnt1--;

if(hCnt1《2)

upDown1=!upDown1;

}

}

capture = TIM_GetCapture1(TIM2);

TIM_SetCompare1(TIM2, capture + CCR1_Val);

}

else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

if(Count2《hCnt2)

{ GPIO_SetBits(GPIOD, GPIO_Pin_9); //点亮灯

}

else

{ GPIO_ResetBits(GPIOD, GPIO_Pin_9); //熄灭灯

}

Count2++;

if(Count2》=allCount)

{ Count2=0;

if(upDown2)

{ hCnt2++;

if(hCnt2》=(allCount-1))

upDown2=!upDown2;

}

else

{ hCnt2--;

if(hCnt2《2)

upDown1=!upDown1;

}

}

capture = TIM_GetCapture2(TIM2);

TIM_SetCompare2(TIM2, capture + CCR2_Val);

}

else if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);

if(Count3《hCnt3)

{ GPIO_SetBits(GPIOD, GPIO_Pin_10); //点亮灯

}

else

{ GPIO_ResetBits(GPIOD, GPIO_Pin_10); //熄灭灯

}

Count3++;

if(Count3》=allCount)

{ Count3=0;

if(upDown3)

{ hCnt3++;

if(hCnt3》=(allCount-1))

upDown3=!upDown3;

}

else

{ hCnt3--;

if(hCnt3《2)

upDown3=!upDown3;

}

}

capture = TIM_GetCapture3(TIM2);

TIM_SetCompare3(TIM2, capture + CCR3_Val);

}

else

{

TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);

if(Count4《hCnt4)

{ GPIO_SetBits(GPIOD, GPIO_Pin_11); //点亮灯

}

else

{ GPIO_ResetBits(GPIOD, GPIO_Pin_11); //熄灭灯

}

Count4++;

if(Count4》=allCount)

{ Count4=0;

if(upDown4)

{ hCnt4++;

if(hCnt4》=(allCount-1))

upDown4=!upDown4;

}

else

{ hCnt4--;

if(hCnt4《2)

upDown4=!upDown4;

}

}

capture = TIM_GetCapture4(TIM2);

TIM_SetCompare4(TIM2, capture + CCR4_Val);

}

}

即将LED点亮的过程分成16(allCount)份,第一次是点亮1/16时间,而15/16的时间都是灭着的,这个1是变量hCnt来控制的,随着中断16次完毕,hCnt会加1,于是第二个周期来了,在这个周期中,LED会被点亮2/16,而14/16的时间是灭着的,依次类推,到最后会有 15/16的时间被点亮,而1/16的时间是灭着的,于是就产生了渐亮效果。请原谅我在学习时的代码写得很粗糙了。

由于TIM2_CH1通道的中断频率是:

CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz

再除以16那就是:9.1Hz,闪烁现像应该很明显了。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
NXP推出Wi-Fi 6E三频段SOC 充分释放6GHz频谱潜力