OpenEdv-开源电子网

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

PWM输出固定个数脉冲可以这样设置吗?只输出一次,求解答

[复制链接]

1

主题

6

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-8
在线时间
8 小时
发表于 2017-12-1 14:29:17 | 显示全部楼层 |阅读模式
10金钱
void PWMS8_Init(unsigned short cycle,unsigned short duty,unsigned short pulse_n)
{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
       
TIM_TimeBaseStructure.TIM_Period = cycle-1;
TIM_TimeBaseStructure.TIM_Prescaler = 7199;//100us
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = pulse_n;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_GenerateEvent(TIM8,TIM_EventSource_Update);
TIM_InternalClockConfig(TIM8);

TIM_SelectOCxM(TIM8,TIM_Channel_1,TIM_OCMode_PWM2);       

/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = duty-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM8, ENABLE);

  /* TIM8 enable counter */
  TIM_CtrlPWMOutputs(TIM8,ENABLE);
  TIM_SelectOnePulseMode(TIM8,TIM_OPMode_Single);
  TIM_Cmd(TIM8, ENABLE);
}

最佳答案

查看完整内容[请看2#楼]

1)外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但非常不科学,并且浪费资源。 2)使用定时器,使用一个和PWM频率一致的定时器,使用定时器中断来计数。此方法比第一种办法好了很多,但是仍然感觉比较笨,并且单片机会频繁的进中断...... 3)利用定时器内部互联,一个定时器的给另一个定时器提供时钟,主从模式,一个PWM输出脉冲给另一个定时提供时钟,每来一个脉冲,计数器值+1,当+ ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-8
在线时间
8 小时
 楼主| 发表于 2017-12-1 14:29:18 | 显示全部楼层
2246606206 发表于 2017-12-5 20:07
这个没研究过,研究透告诉我一下

1)外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但非常不科学,并且浪费资源。   
     2)使用定时器,使用一个和PWM频率一致的定时器,使用定时器中断来计数。此方法比第一种办法好了很多,但是仍然感觉比较笨,并且单片机会频繁的进中断......
     3)利用定时器内部互联,一个定时器的给另一个定时器提供时钟,主从模式,一个PWM输出脉冲给另一个定时提供时钟,每来一个脉冲,计数器值+1,当+到指定个数后,产生一次中断,然后关闭PWM输出。此方法还是浪费资源,且多路电机控制需                     要产生多路频率不同、个数不同的脉冲时就不能满足要求了。
     4)使用DMA来控制发送的脉冲数,最大可以65535个,如果想使用不同频率和脉宽,可以设置不同的装载值,如果你发送的脉冲数超过65535个,则可以使用DMA传输完成中断中切换DMA传输的数据起始地址及发送数量,继续发送。这个方法即方便,又减轻CPU的负担,可以同时驱动多个电机工作,还可以根据电机的启动-运行-停止使用不同的频率。
5)既然高级定时器有重复计数功能,那为什么没人用呢?我看了两天例程,原来重复计算只有8位宽度,且没有资料说中断里可以更新计数值,每次重装计数值很浪费时间,这个看起来最方便的放法不能用了,只能放弃
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-12-3 01:19:53 | 显示全部楼层
自行测试
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-8
在线时间
8 小时
 楼主| 发表于 2017-12-4 10:20:02 | 显示全部楼层

用示波器看过输出一次,多次调用只执行一次
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-12-5 01:43:08 | 显示全部楼层
weizuokai 发表于 2017-12-4 10:20
用示波器看过输出一次,多次调用只执行一次

具体问题,慢慢解决
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

241

帖子

0

精华

高级会员

Rank: 4

积分
806
金钱
806
注册时间
2017-8-17
在线时间
159 小时
发表于 2017-12-5 08:33:26 | 显示全部楼层
本帖最后由 2246606206 于 2017-12-5 08:35 编辑

你没有使能自动输出,看看我的


//初始化TIM1
//arr:自动重装值
//pse:时钟预分频系数

void Tim1_Init(u16 arr,u16 pse)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCStructure;
        TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
        
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_TIM1 ,ENABLE );
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO ,ENABLE );
        
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP ;
        GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        
        //GPIO_PinRemapConfig(GPIO_FullRemap_TIM1, ENABLE);
        
        TIM_TimeBaseStructure .TIM_Period =arr;
        TIM_TimeBaseStructure .TIM_Prescaler =pse ;
        TIM_TimeBaseStructure .TIM_ClockDivision =TIM_CKD_DIV1 ;
        TIM_TimeBaseStructure .TIM_CounterMode =TIM_CounterMode_Up ;
        TIM_TimeBaseStructure .TIM_RepetitionCounter =0;  //不使用重复计数
        TIM_TimeBaseInit (TIM1 ,&TIM_TimeBaseStructure );
        
        //启用ARR的影子寄存器(直到产生更新事件才更改设置)
        TIM_ARRPreloadConfig (TIM1 ,ENABLE );
        
        TIM_OCStructure .TIM_OCMode =TIM_OCMode_PWM1 ; //比较输出模式
        TIM_OCStructure .TIM_OutputState =TIM_OutputState_Enable ; //比较输出使能
        //TIM_OCStructure .TIM_OutputState =TIM_OutputState_Disable ; //比较输出使能
        //TIM_OCStructure .TIM_OutputNState =TIM_OutputNState_Enable ;//比较互补输出使能
        TIM_OCStructure .TIM_OutputNState =TIM_OutputNState_Disable ;//比较互补输出使能
        TIM_OCStructure .TIM_Pulse =PWM_Pulse  ; //比较值
        //TIM_OCStructure .TIM_OCPolarity =TIM_OCPolarity_High;//输出极性
        TIM_OCStructure .TIM_OCPolarity =TIM_OCPolarity_Low ;//输出极性
        //TIM_OCStructure .TIM_OCNPolarity =TIM_OCNPolarity_High ;//互补输出极性
        //TIM_OCStructure .TIM_OCNPolarity =TIM_OCNPolarity_Low ;//互补输出极性
        //TIM_OCStructure .TIM_OCIdleState =TIM_OCIdleState_Reset ; //空闲状态下输出状态
        TIM_OCStructure .TIM_OCIdleState =TIM_OCIdleState_Set ; //空闲状态下输出状态
        //TIM_OCStructure .TIM_OCNIdleState =TIM_OCNIdleState_Set ;
        //TIM_OCStructure .TIM_OCNIdleState =TIM_OCNIdleState_Reset ;
        TIM_OC1Init (TIM1 ,&TIM_OCStructure );
        
        //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置)
        TIM_OC1PreloadConfig (TIM1,TIM_OCPreload_Enable );
        
        //死区设置
        TIM_BDTRInitStructure .TIM_OSSIState =TIM_OSSRState_Enable ; //运行模式下的关闭状态选择
        //TIM_BDTRInitStructure .TIM_OSSIState =TIM_OSSRState_Disable ; //运行模式下的关闭状态选择
        TIM_BDTRInitStructure .TIM_OSSIState =TIM_OSSIState_Enable ;//空闲模式下的关闭状态选择
        TIM_BDTRInitStructure .TIM_LOCKLevel =TIM_LOCKLevel_OFF ; //锁定配置
        TIM_BDTRInitStructure .TIM_DeadTime =0x0F;//这里调整死区大小0-0xff
        TIM_BDTRInitStructure .TIM_Break =TIM_Break_Disable ;//断路输入使能控制
        TIM_BDTRInitStructure .TIM_BreakPolarity =TIM_BreakPolarity_High ; //断路输出极性
        //TIM_BDTRInitStructure .TIM_AutomaticOutput =TIM_AutomaticOutput_Disable ;//自动输出使能
        TIM_BDTRInitStructure .TIM_AutomaticOutput =TIM_AutomaticOutput_Enable ;//自动输出使能
        TIM_BDTRConfig (TIM1,&TIM_BDTRInitStructure );
               /*这里可以改为使能*/
        TIM_Cmd(TIM1,DISABLE  );
        TIM_CtrlPWMOutputs (TIM1,DISABLE  );
        
}
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-8
在线时间
8 小时
 楼主| 发表于 2017-12-5 16:10:17 | 显示全部楼层
2246606206 发表于 2017-12-5 08:33
你没有使能自动输出,看看我的

你这个能输出固定脉冲个数么?
回复

使用道具 举报

12

主题

241

帖子

0

精华

高级会员

Rank: 4

积分
806
金钱
806
注册时间
2017-8-17
在线时间
159 小时
发表于 2017-12-5 16:36:20 | 显示全部楼层
脉冲是要自己设置的好吧
这个函数
TIM_SetCompare1();

多看看例程吧
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-8
在线时间
8 小时
 楼主| 发表于 2017-12-5 16:53:13 | 显示全部楼层
本帖最后由 weizuokai 于 2017-12-5 16:59 编辑
2246606206 发表于 2017-12-5 16:36
脉冲是要自己设置的好吧
这个函数
TIM_SetCompare1();

TIM_SetCompare1这个是调占空比的,TIM_SetAutoreload这个调频率没问题,我想的是用一个定时器在PWM方式下,输出想要的脉冲数,而不是频率占空比呢
回复

使用道具 举报

12

主题

241

帖子

0

精华

高级会员

Rank: 4

积分
806
金钱
806
注册时间
2017-8-17
在线时间
159 小时
发表于 2017-12-5 20:07:27 | 显示全部楼层
weizuokai 发表于 2017-12-5 16:53
TIM_SetCompare1这个是调占空比的,TIM_SetAutoreload这个调频率没问题,我想的是用一个定时器在PWM方式 ...

这个没研究过,研究透告诉我一下
回复

使用道具 举报

12

主题

241

帖子

0

精华

高级会员

Rank: 4

积分
806
金钱
806
注册时间
2017-8-17
在线时间
159 小时
发表于 2017-12-6 11:28:22 | 显示全部楼层
weizuokai 发表于 2017-12-6 10:52
1)外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但非常不科学,并且浪费资源 ...

受教了,看这选4方式应该是最合适的了
回复

使用道具 举报

4

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2017-9-22
在线时间
14 小时
发表于 2018-1-31 22:05:42 | 显示全部楼层
你可进中断啊,每次脉冲数减一不就好了,,
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 16:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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