#include "led.h" #include "bsp.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK战舰STM32开发板 //LED驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2012/9/2 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2009-2019 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //初始化PB5和PE5为输出口.并使能这两个口的时钟 //LED IO初始化 void LED_Init(void) { // GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟 #ifdef COLLECT_DEVICE //LED_RUN(PE14) GPIO_COMM_Init(RCC_APB2Periph_GPIOE, GPIOE, GPIO_Pin_14, GPIO_Mode_Out_PP, GPIO_Speed_50MHz); #else //LED_RUN(PC2) GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_2, GPIO_Mode_Out_PP, GPIO_Speed_50MHz); #endif } //通用定时器中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3! __IO uint32_t led0_cnt_dir = 0; __IO uint32_t led0_pwm_val = 0; uint32_t led1_delay = 3; uint32_t led2_delay = 3; uint32_t led3_delay = 3; uint8_t led1_duty = LED1_DUTY; uint8_t led2_duty = LED2_DUTY; uint8_t led3_duty = LED3_DUTY; uint32_t led1_cycle = LED1_CYCLE; uint32_t led2_cycle = LED2_CYCLE; uint32_t led3_cycle = LED3_CYCLE; uint16_t CCR1_Val = LED0_CYCLE; uint16_t CCR2_Val = LED1_CYCLE; uint16_t CCR3_Val = LED2_CYCLE; uint16_t CCR4_Val = LED3_CYCLE; //uint16_t PrescalerValue = 0; uint16_t capture = 0; void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 // PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500) - 1;//=168 /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = arr;//65535 TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Prescaler configuration */ //TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);//对72MHz进行710分频,即为50KHz /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10;//CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10;//CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10;//CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 /* TIM Interrupts enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); LED0 = 0; LED1 = 0; LED2 = 0; LED3 = 0; capture = TIM_GetCapture1(TIM3); TIM_SetCompare1(TIM3, capture + 100); capture = TIM_GetCapture1(TIM3); TIM_SetCompare2(TIM3, capture + 100); capture = TIM_GetCapture1(TIM3); TIM_SetCompare3(TIM3, capture + 100); capture = TIM_GetCapture1(TIM3); TIM_SetCompare4(TIM3, capture + 100); } void TIM3_Int_Deinit(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_DeInit(TIM3); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 /* TIM Interrupts enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, DISABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, DISABLE); } //uint8_t time[4]={0,0,0,0}; //void TIM3_IRQHandler(void) //TIM3中断 //{ // // // // if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) // { // TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); // if(led1_delay>0)led1_delay--; // // if(led1_delay>10*100)led1_delay=0; // // capture = TIM_GetCapture1(TIM3); // TIM_SetCompare1(TIM3, capture + CCR1_Val); // // } // /*7500为一个循环,周期为7500/500000=0.015,频率为66.67Hz*/ // if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET) // { // TIM_ClearITPendingBit(TIM3, TIM_IT_CC2); // if(led1_delay!=0){ // if(LED1) // { // LED1=0; //PB9=0。ARR增加5000后,到达这条语句。 // CCR2_Val=(led1_cycle * led1_duty / 100); //占空比 // } // else // { // LED1=1; //PB9=1 // CCR2_Val=led1_cycle-(led1_cycle * led1_duty / 100); // } //在原来的CCR1(即capture)基础上加5000,则再过5000,又会触发中断 // //另外,有个问题,进入中断时,当ARR计数器快加到65535,而又不足5000时,不是会有数据多余,而产生波形的移动吗? // //回答:不用担心。例如进入中断是,ARR=65000,65000+5000=70000>65535,那么高位会舍去,即为70000-65536=4464 // //等于是来了个循环,两次中断间ARR的增量还是5000。所以为了波形的稳定,初始化时,必须要有TIM_Period = 65535 // } // // if(led1_delay>0)led1_delay--; // if(led1_delay>10*100)led1_delay=10*100; // else{ // LED1=1; // } // // capture = TIM_GetCapture2(TIM3); // TIM_SetCompare2(TIM3, capture + CCR2_Val); // } // if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET) // { // TIM_ClearITPendingBit(TIM3, TIM_IT_CC3); // // if(led2_delay!=0){ // if(LED2) // { // LED2=0; //PB7=0。ARR增加5000后,到达这条语句。 // CCR3_Val=(led2_cycle * led2_duty / 100); //占空比 // } // else // { // LED2=1; //PB7=1 // CCR3_Val=led2_cycle-(led2_cycle * led2_duty / 100); // } // // if(led2_delay>0)led2_delay--; // if(led2_delay>10*100)led2_delay=10*100; // } // else{ // LED2=1; // } // capture = TIM_GetCapture3(TIM3); // TIM_SetCompare3(TIM3, capture + CCR3_Val); // } // if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET) { // TIM_ClearITPendingBit(TIM3, TIM_IT_CC4); // // if(led3_delay!=0){ // if(LED3) // { // LED3=0; //PB8=0。ARR增加5000后,到达这条语句。 // CCR4_Val=(led3_cycle * led3_duty / 100); //占空比 // } // else // { // LED3=1; //PB8=1 // CCR4_Val=led3_cycle-(led3_cycle * led3_duty / 100); // } // // if(led3_delay>0)led3_delay--; // if(led3_delay>10*100)led3_delay=10*100; // } // else{ // LED3=1; // } // capture = TIM_GetCapture4(TIM3); // TIM_SetCompare4(TIM3, capture + CCR4_Val); // } //} void start_led(uint8_t led,uint32_t delay, uint8_t duty,uint32_t period){ if(led == 1){ LED1=0; led1_delay = delay; led1_duty = duty; led1_cycle = period; capture = TIM_GetCapture2(TIM3); TIM_SetCompare2(TIM3, capture + led1_cycle); } else if(led == 2){ LED2=0; led2_delay = delay; led2_duty = duty; led2_cycle = period; capture = TIM_GetCapture3(TIM3); TIM_SetCompare3(TIM3, capture + led2_cycle); } else if(led == 3){ LED3=0; led3_delay = delay; led3_duty = duty; led3_cycle = period; capture = TIM_GetCapture4(TIM3); TIM_SetCompare4(TIM3, capture + led3_cycle); } }