/*想通过定时器8控制4个通道输出4个不同占空比的方波从而控制4个步进电机,下面的程序可以让通道PC789产生不同的方波,通道一不能产生方波*/
//通过示波器观察 通道2、3、4都可以根据CCR的值改变占空比,而通道一即PC6引脚在示波器上的周期是个变值,不会产生方波
//如果将将通道一那里的配置写在通道二前面会导致只有通道四产生%50占空比的方波,且另外几个通道不会产生方波
.c代码如下:
#include "driver.h"
#include "delay.h"
#include "usart.h"
/*************************************定时器8通道脉冲**********************************/
u16 CCR1_Val=999;
u16 CCR2_Val=300;
u16 CCR3_Val=500;
u16 CCR4_Val=700;
/***********************************************
//TIM8_CH1(PC6)
TIM8_CH1(PC7)
TIM8_CH1(PC8)
TIM8_CH1(PC9) 输出比较模式 翻转
//TIM8 时钟频率 84*2=168MHz
//arr:自动重装值
//psc:时钟预分频数
************************************************/
u16 capture1=0;
u16 capture2=0;
u16 capture3=0;
u16 capture4=0;
void TIM8_Compare_output(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
printf("进入初始化");
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTC时钟
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8); //GPIOC6复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //GPIOC7复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8); //GPIOC8复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8); //GPIOC9复用为定时器8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6; //GPIOC7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PC6 PC7 PC8 PC9
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; //TIM向上计数模式
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn ; //TIM8中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //选择定时器模式:翻转模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
/***********************通道2*************************/
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM8,TIM_OCPreload_Enable);
/***********************通道3*************************/
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC3PreloadConfig(TIM8,TIM_OCPreload_Enable);
/***********************通道4*************************/
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4PreloadConfig(TIM8,TIM_OCPreload_Enable);
/***********************通道1*************************/
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1PreloadConfig(TIM8,TIM_OCPreload_Enable);
TIM_ClearITPendingBit(TIM8,TIM_IT_CC4|TIM_IT_CC3|TIM_IT_CC2|TIM_IT_CC1);
TIM_CtrlPWMOutputs(TIM8,ENABLE);
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_ITConfig(TIM8,TIM_IT_CC3|TIM_IT_CC4|TIM_IT_CC2|TIM_IT_CC1,ENABLE );
TIM_Cmd(TIM8, ENABLE); //使能TIMx外设
}
/**************************************定时器8中断**********************************/
void TIM8_CC_IRQHandler(void) //TIM8中断
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); //清除TIMx的中断待处理位:TIM 中断源
capture1=TIM_GetCapture1(TIM8);
TIM_SetCompare1(TIM8,capture1);
}
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC2); //清除TIMx的中断待处理位:TIM 中断源
capture2=TIM_GetCapture2(TIM8);
TIM_SetCompare2(TIM8,capture2);
}
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3); //清除TIMx的中断待处理位:TIM 中断源
capture3=TIM_GetCapture3(TIM8);
TIM_SetCompare3(TIM8,capture3);
}
if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC4); //清除TIMx的中断待处理位:TIM 中断源
capture4=TIM_GetCapture4(TIM8);
TIM_SetCompare4(TIM8,capture4);
}
} |