因為前段時間需要用STM32F103控制步進電機,所以寫了了可用于控住GPIO口輸出固定數量脈沖的函式,可直接輸入脈沖數,并且可以調節PWM的頻率(每個脈沖的周期),
參考了網上大神的指導,我的思路是:用兩個定時器(一個用于PWM輸出,一個用于中斷PWM輸出),通過對PWM的周期和輸出時間的控制,來達到輸出固定脈沖數的目的,
下面為主要代碼:
#include <sys.h>
#include <pwn.h>
#include <interrupt.h>
#include <step.h>
//輸出固定脈沖數量
//speed為輸出脈沖的頻率
//pulse為輸出脈沖數量
//在調脈沖頻率時,需同時調x
void pulse_putput(u16 speed, u16 pulse)
{
TIM2_init(pulse*10); //設定脈沖數量(10為speed/100)
TIM_Cmd(TIM2, ENABLE); //使能TIM4
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中斷標志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能更新中斷
TIM3_PWM_Init(speed); //設定PWM輸出的頻率
TIM_Cmd(TIM3, ENABLE); //使能定時器3
}
然后就是PWM的初始化代碼(這一段是基礎的PWM初始化)
//TIM3 PWN2?·?3?ê??ˉ
//PWNê?3?3?ê??ˉ
//arr: ×??ˉ??×°??
//psc: ê±?ó?¤·??μ
void TIM3_PWM_Init(u16 arr)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //ê1?ü?¨ê±?÷3ê±?ó
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //??ó3é?TIM3_CH2->PB5
//éè????òy???a?′ó?ê?3?1|?ü£?ê?3?TIM3 CH2μ?PWN??3?2¨D? GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //?′ó?í?íìê?3?
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //3?ê??ˉGPIO
//3?ê??ˉTIM3
TIM_TimeBaseStructure.TIM_Period = arr-1; //éè???ú×??ˉ??×°???ü?ú?μ
TIM_TimeBaseStructure.TIM_Prescaler = 71; //éè???¤·??μ?μ
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //éè??ê±?ó·???£oTDTS = Tck_tiim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM?òé???êy?£ê?
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //3?ê??ˉTIMx
//3?ê??ˉTIM3 Channel2 PWN?£ê?
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //????PWN?£ê?2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±è??ê?3?
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //ê?3???D???
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //3?ê??ˉíaéèTIM3 OC2
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Update);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //ê1?ü?¤×°????′??÷
TIM_SetCompare2(TIM3, arr/4);
TIM_Cmd(TIM3, ENABLE); //ê1?üTIM3
}
定時器中斷初始化
#include <interrupt.h>
#include "sys.h"
//通用定時器2中斷初始化
void TIM2_init(u16 arr)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//定時器TIM2初始化
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_Prescaler = 7200-1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
//中斷優先級設定
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);
}
//定時器2中斷服務程式
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_CtrlPWMOutputs(TIM3, DISABLE);
TIM_Cmd(TIM3, DISABLE);
TIM_Cmd(TIM2, DISABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
}
}
程式的思維圖如下
僅為個人拙見!
獻上工程檔案(KEIL,STM32F103VET6芯片)
百度網盤鏈接:https://pan.baidu.com/s/1jcsudApm-fGemTKgDYPnhA
提取碼:ky18
復制這段內容后打開百度網盤手機App,操作更方便哦
本人為新手,有不對的地方歡迎指正!
侵刪,謝謝
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/163923.html
標籤:其他
上一篇:基于51單片機的矩陣按鍵
