概述
#define TIM2_CLK_ENABLE() ( RCC->APB1ENR |= RCC_APB1ENR_TIM2EN )
#define TIM3_CLK_ENABLE() ( RCC->APB1ENR |= RCC_APB1ENR_TIM3EN )
#define TIMx_CHANNEL_GPIOA_PORT() ( RCC->IOPENR |= (RCC_IOPENR_GPIOAEN))
#define TIMx_CHANNEL_GPIOB_PORT() ( RCC->IOPENR |= (RCC_IOPENR_GPIOBEN))
arm_drv_tim_pwm_channel_config (TIM2_BASE, GPIO_A, GPIO_A_15, GPIO_AF5_TIM2, TIM_CHANNEL_1);
short drv_io_config_pin( unsigned long pin, unsigned char config )
{
unsigned short port, index, bits;
GPIO_TypeDef* GPIO_Init_PORT;
GPIO_InitTypeDef GPIO_InitStruct;
port = (unsigned short)(pin >> 16); // port index for PORT A-H (0-4)
if(port > (MAXIMUM_GPIO_PORT-1)) // only has 5 ports: PORT_[A~H]
return 1;
GPIO_Init_PORT = GPIO_PORT[port];
GPIO_InitStruct.Pin = 0;
bits = 0x8000; // start from bit 15.
// prepare configure register
for( index = 0; index < 16; index++ )
{
if( pin & bits )
{
// the bit is selected.
GPIO_InitStruct.Pin = bits;
// config format: 0011,0001.pupd[7:6]=00=no pull-up, pull-down; ospeed[5:4]=11=high speed; otype[2]=0=push-pull; mode[1:0]=01=output.
GPIO_InitStruct.Mode = (GPIOMode_TypeDef) (config & 0x03); // GPIO_Mode;
GPIO_InitStruct.OType = (GPIOOType_TypeDef)((config>>2)&0x01); // GPIO_OType;
GPIO_InitStruct.Speed = (GPIOSpeed_TypeDef)((config>>4)&0x03); // GPIO_OSpeed;
GPIO_InitStruct.PuPd = (GPIOPuPd_TypeDef)((config>>6)&0x03); //GPIO_PuPd
GPIO_Init(GPIO_Init_PORT, &GPIO_InitStruct);
}
bits >>= 1;
}
return 0;
}
void drv_io_af_config(unsigned long pin, unsigned char gpio_af)
{
unsigned short port, GPIO_PinSource;
unsigned long pos;
GPIO_TypeDef* GPIOx;
unsigned long temp = 0x00;
unsigned long temp_2 = 0x00;
unsigned long temp_3 = 0x00;
port = (unsigned short)(pin >> 16); // port index for PORT A-H (0-4)
if(port > (MAXIMUM_GPIO_PORT-1)) // only has 5 ports: PORT_[A~H]
return;
GPIOx = GPIO_PORT[port];
for(GPIO_PinSource = 0x00; GPIO_PinSource < 0x10; GPIO_PinSource++)
{
pos = ((unsigned long)0x01) << GPIO_PinSource;
if(pin & pos) //Get the port pin position
{
temp = (unsigned long)(gpio_af) << ((unsigned long)((unsigned long)GPIO_PinSource & (unsigned long)0x07) * 4);
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] & (~((unsigned long)0xF << ((unsigned long)((unsigned long)GPIO_PinSource & (unsigned long)0x07) * 4)));
temp_3 = temp_2 | temp;
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_3;
}
}
}
void arm_drv_tim_pwm_channel_config (uint32_t u32TimerBase,
uint32_t u16GpioPortNo,
uint32_t u16GpioPinNo,
uint32_t u16GpioAltNo,
uint16_t u16TimerChannel)
{
TIM_TypeDef *TIMx;
GPIO_TypeDef *GPIOx;
TIMx = (TIM_TypeDef *)u32TimerBase;
TIM_Base_InitTypeDef TIM_InitStructure;
TIM_OC_InitTypeDef sConfig;
// uint32_t u32PinAddr;
uint32_t tmpcr1 = 0;
switch (u16GpioPortNo)
{
case GPIO_A: GPIOx = GPIOA; break;
case GPIO_B: GPIOx = GPIOB; break;
case GPIO_C: GPIOx = GPIOC; break;
case GPIO_D: GPIOx = GPIOD; break;
}
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* TIMx Peripheral clock enable */
if ( TIMx == TIM2)
{
TIM2_CLK_ENABLE();
}
else if ( TIMx == TIM3)
{
TIM3_CLK_ENABLE();
}
/* Enable all GPIO Channels Clock requested */
if ( GPIOx == GPIOA)
{
TIMx_CHANNEL_GPIOA_PORT();
}
else if ( GPIOx == GPIOB)
{
TIMx_CHANNEL_GPIOB_PORT();
}
/*##-1.1- setup GPIO port accordingly #################################*/
/* Common configuration for all channels */
drv_io_config_pin(u16GpioPinNo, GPIO_AFO_PP_HIGH_UP);
// // setup AFR with pin number
drv_io_af_config(u16GpioPinNo, u16GpioAltNo);
/*##-2.1- initialize the timer to be the PWM with known period ##############*/
// fill up the common initialization settings
TIM_InitStructure.Prescaler= (uint32_t)(SystemCoreClock / 2000000) - 1;
TIM_InitStructure.CounterMode= TIM_COUNTERMODE_UP;
//TIM_InitStructure.Period= PERIOD_VALUE;
TIM_InitStructure.Period= *DEVICE_CONFIG_1_BIAS_PWM_PERIOD_COUNT;
TIM_InitStructure.ClockDivision= 0;
//arm_drv_tim_Base_SetConfig(TIMx, &TIM_InitStructure);
// can create a new standalone function for this functionality
/* save CR1 content first */
tmpcr1 = TIMx->CR1;
/* set the counter Mode */
tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
tmpcr1 |= TIM_InitStructure.CounterMode;
/* set the clock division*/
tmpcr1 &= ~TIM_CR1_CKD;
tmpcr1 |= (uint32_t)TIM_InitStructure.ClockDivision;
TIMx->CR1 = tmpcr1;
/* Set the Autoreload value */
TIMx->ARR = (uint32_t)TIM_InitStructure.Period ;
/* Set the Prescaler value */
TIMx->PSC = (uint32_t)TIM_InitStructure.Prescaler;
/* Generate an update event to reload the Prescaler value immediatly */
TIMx->EGR = TIM_EGR_UG;
//arm_drv_tim_Base_SetConfig(TIMx, &TIM_InitStructure);
/*##-2- Configure the PWM channels #########################################*/
/* Common configuration for all channels */
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE;
/* configure the timer with the given channel # */
arm_drv_tim_pwm_channel_setting (TIMx, &sConfig, u16TimerChannel);
/* start the timer for the desired channel */
arm_drv_tim_pwm_start (TIMx, (uint32_t)u16TimerChannel);
}
1、配置GPIO口
2、初始化定时器
3、设置TIM2_CH1的PWM模式,使能TIM2的CH1输出
4、使能定时器2
5、使用PWM
最后
以上就是光亮茉莉为你收集整理的定时器TIM2输出pwm波的全部内容,希望文章能够帮你解决定时器TIM2输出pwm波所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复