②使能GPIOB時鐘:RCC_APB2PeriphClockCmd();
(2)初始化IO口爲複用功能輸出。函數:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//這裏我們是要把引腳用作定時器的PWM輸出引腳,因此要重映射配置。所以需要開啓AFIO時鐘。同時設置重映射。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
(4)初始化輸出比較參數:TIM_OC2Init();
(5)使能預裝載寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
(6)使能定時器。TIM_Cmd();
(7)不斷改變比較值CCRx,達到不同的佔空比效果:TIM_SetCompare2();
//TIM3 PWM部分初始化
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預分頻數
void TIM3_PWM_Init(u16 arr,u16 psc)//STM32F103ZET6
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定時器3時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設和AFIO複用功能模塊時鐘
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//設置該引腳爲複用輸出功能,輸出TIM3 CH2的PWM脈衝波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器週期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作爲TIMx時鐘頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
//初始化TIM3 CH2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據T指定的參數初始化外設TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預裝載寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預分頻數
void TIM1_PWM_Init(u16 arr,u16 psc)//STM32F103RCT6
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能GPIOA外設時鐘使能
//設置該引腳爲複用輸出功能,輸出TIM1 CH1和CH4的PWM脈衝波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11;//TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器週期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作爲TIMx時鐘頻率除數的預分頻值 不分頻
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈衝值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根據TIM_OC1InitStruct中指定的參數初始化外設TIM1的通道1
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根據TIM_OC2InitStruct中指定的參數初始化外設TIM1的通道4
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主輸出使能
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable); //CH1預裝載使能 通道1
TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable); //CH4預裝載使能 通道4
TIM_ARRPreloadConfig(TIM1,ENABLE); //使能TIMx在ARR上的預裝載寄存器(x==1)
TIM_Cmd(TIM1,ENABLE); //使能TIM1
}
初始化函數在主函數的開頭處調用,調用函數的兩個參數根據自己需要去設定。
/**
* @brief Sets the TIMx Capture Compare1 Register value
* @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
* @param Compare1: specifies the Capture Compare1 register new value.
* @retval None
*/
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
{
/* Check the parameters */
assert_param(IS_TIM_LIST8_PERIPH(TIMx));//有效性判斷
/* Set the Capture Compare1 Register value */
TIMx->CCR1 = Compare1;
}
說明:和這個函數類似的一共有四個:TIM_SetCompare1(); TIM_SetCompare2(); TIM_SetCompare3(); TIM_SetCompare4();其實現框架都是一樣的,四個函數分別對應四個通道,使用哪個通道調用哪個函數,要對應起來。u8 Case_F_SIGN(void)//直行
{
while(1){
delay_ms(10);
pwmvalR=413;
pwmvalL=413;
TIM_SetCompare1(TIM1,pwmvalR);
TIM_SetCompare4(TIM1,pwmvalL);
t=SensorScan();
if(t!=F_SIGN)
return t;
}
}
pwmvalR和pwmvalL是兩個全局變量,它們的值是根據項目需要和小車硬件情況實際測出來的,然後調用兩個函數,寫入相關寄存器,,下面是調用SensorScan();看小車是不是還沿着軌跡在行駛,如果不是,那麼跳出while(1)循環,否則,返回主調函數當前小車的狀態。這段代碼現在看寫得不是特別好了,但是說明這個函數的用法還是沒問題的。