OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5260|回复: 1

大家来讨论下PWM输出固定脉冲数量的问题吧~

[复制链接]

2

主题

2

帖子

0

精华

新手入门

积分
30
金钱
30
注册时间
2013-9-4
在线时间
0 小时
发表于 2013-9-25 23:36:48 | 显示全部楼层 |阅读模式
最近开始学习定时器了,STM32的定时器真是好强大...光看那一大堆寄存器和参考手册上的相关页数就晕了

学到PWM这里的时候,想试着实现输出固定数量的脉冲的功能,虽然没玩过,但感觉步进电机有时候会需要这种动作吧

想了一下决定就用输出PWM的定时器本身的中断完成

程序中启用了TIM3通用定时器,4个通道都开了,占空比75%,50%,25%,12.5%。之前学习时候的遗留产物~

现在用通道2的捕获比较中断    TIM_IT_CC2    来完成脉冲计数并比较,达到规定数量(程序里为5+1个)脉冲时候就关闭通道2的输出。

现在有几个相关or无关的小问题:
1.语句A:    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
  语句B:     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  语句C:    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
A的执行时间是远小于B+C还是差不多?


2.程序输出的第一个脉冲的周期T 比后续脉冲的都要短。例如本程序中的第一个脉冲周期约12.2us,后续均为13.8~13.9左右
而在启用TIM3语句之后马上就进入了while循环
是什么导致此现象的?

3.中断不会打断TIM3这种外设的工作,即便是配置其相关的寄存器(如在CCMR1中关闭CH2)的语句,
只要片上外设的工作不涉及到占用CPU的代码就不会有影响,我这样的理解对吗?

4.感觉这种方式如果没有上一个问题,似乎是实现此功能的最好办法?而且也可以稍微改下就能在中断里实现纯计数功能
不知道大家有没有更高效的方法呢



附上代码
u8 steps = 0; //PWM脉冲计数全局变量
int main(void)
{
SystemInit();
pwm_MyInit();

while(1)
continue;
}

void pwm_MyInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef Base_InitStructure;
TIM_OCInitTypeDef PWM_InitSturcture;
NVIC_InitTypeDef PWM_NVICStructure;
/*******************RCC********************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
/************************************************/
/*******************GPIO********************/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOB,&GPIO_InitStructure);
/************************************************/


/*******************NVIC********************/
PWM_NVICStructure.NVIC_IRQChannel = TIM3_IRQn;
PWM_NVICStructure.NVIC_IRQChannelCmd = ENABLE;
PWM_NVICStructure.NVIC_IRQChannelSubPriority = 1;
PWM_NVICStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_Init(&WM_NVICStructure);
/************************************************/
/*******************TIM3 BASE********************/
Base_InitStructure.TIM_ClockDivision = 0;
Base_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
Base_InitStructure.TIM_Period = 999;
Base_InitStructure.TIM_Prescaler = 0;
Base_InitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3,&Base_InitStructure);
/************************************************/
TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);


/*******************TIM3 PWM********************/
PWM_InitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
PWM_InitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;
PWM_InitSturcture.TIM_OutputState= TIM_OutputState_Enable;
PWM_InitSturcture.TIM_Pulse = 750;
TIM_OC1Init(TIM3,&WM_InitSturcture);
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
PWM_InitSturcture.TIM_OutputState = TIM_OutputState_Enable;
PWM_InitSturcture.TIM_Pulse = 500;
TIM_OC2Init(TIM3,&WM_InitSturcture);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

PWM_InitSturcture.TIM_OutputState = TIM_OutputState_Enable;
PWM_InitSturcture.TIM_Pulse = 250;
TIM_OC3Init(TIM3,&WM_InitSturcture);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
PWM_InitSturcture.TIM_OutputState = TIM_OutputState_Enable;
PWM_InitSturcture.TIM_Pulse = 125;
  TIM_OC4Init(TIM3,&WM_InitSturcture);
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
/************************************************/
TIM_ARRPreloadConfig(TIM3,ENABLE);
TIM_Cmd(TIM3,ENABLE);
}


void TIM3_IRQHandler(void)
{
extern vu8 steps;
if (TIM_GetITStatus(TIM3,TIM_IT_CC2) != RESET)
{
if (steps >= 5)
{
TIM3->CCMR1 = 0x0868;
steps = 0;
}
else steps++;
TIM_ClearITPendingBit(TIM3,TIM_IT_CC2);
}
}


























正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-9-26 01:20:16 | 显示全部楼层
1,都是配置寄存器,应该差不多吧,具体看函数里面的代码了。或者直接写代码测试下。
2,是每次复位后的第一个周期,还是每次指定脉冲个数的第一个周期?可以仿真看看。
3,是的
4,我用过门控模式,不过需要2个定时器,优点是不需要频繁中断,缺点是需要2个定时器。你的这个方法优点是只需要一个定时器,缺点就是得频繁的中断...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-13 05:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表