OpenEdv-开源电子网

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

f103 TIM DMA输出可控频率、占空比、脉冲数

[复制链接]

28

主题

294

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1790
金钱
1790
注册时间
2018-3-26
在线时间
294 小时
发表于 2021-6-23 16:41:08 | 显示全部楼层 |阅读模式
33金钱
本帖最后由 htao 于 2021-6-23 16:43 编辑

如图,输出可控的脉冲数之后,电平的状态很随机,怎么修改配置来保证输出之后,稳定在低电平图中写错了,是1MHZ 脉冲

2.png

在初始化中,也修改过几个部分,也没有变化
3.png

不太理解DMA DMA_InitStructure.DMA_PeripheralBaseAddr 外设基地址 和 DMA_InitStructure.DMA_MemoryBaseAddr 内存基地址具体的作用。

这个过程复盘一下,

首先初始化完,调用   TIM2_Dma_Pwm_Pulse_Output_Set(8-1,9 - 1,50,1000);
  1. void TIM2_Dma_Pwm_Pulse_Output_Set(u16 arr,u16 psc,u8 zhankongbi_temp,u16 geshu)
  2. {
  3.         TIM_SetAutoreload(TIM2,arr);                               //设置重装载寄存器
  4.         TIM_PrescalerConfig(TIM2,psc,TIM_PSCReloadMode_Immediate); //设置定时器时钟分频,立即生效

  5.         DutyCycle1=(arr+1)*(100-zhankongbi_temp)/100;              //计算占空比
  6.         TIM_SetCompare1(TIM2,DutyCycle1);                          //占空比填入比较寄存器

  7.         DMA_Cmd(DMA1_Channel2, DISABLE);                           //DMA失能才能设置
  8.         DMA_SetCurrDataCounter(DMA1_Channel2,geshu+1);             //设置DMA长度,即脉冲数量
  9.         DMA_Cmd(DMA1_Channel2, ENABLE);                            //开启

  10.         TIM_SetCounter(TIM2, 0);                                   //确保定时器计数归零
  11.         TIM_Cmd(TIM2, ENABLE);                                     //开启
  12. }
复制代码
  1. TIM_SetAutoreload(TIM2,arr); //设置重装载寄存器
复制代码
8-1 代表 计数到8 溢出一次。

  1. TIM_PrescalerConfig(TIM2,psc,TIM_PSCReloadMode_Immediate); //设置定时器时钟分频,立即生效
复制代码

9-1 预分配就是 72 / 9 = 8MHZ ,就是0.125us 计数一次。
  1. DutyCycle1=(arr+1)*(100-zhankongbi_temp)/100; //计算占空比
复制代码
DutyCycle1 = (7+1)*0.5 = 4
  1. TIM_SetCompare1(TIM2,DutyCycle1); //占空比填入比较寄存器
复制代码
改变CCR1比较寄存器,也就是在PWM 模式下,计数时小于 CCR1 时,输出初始化 时设定的有效电平TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;     //输出极性:TIM输出比较极性高
大于CCR1时输出无效电平, (这里可能正好相反,不过没什么差异)
  1. DMA_Cmd(DMA1_Channel2, DISABLE);                           //DMA失能才能设置
  2. DMA_SetCurrDataCounter(DMA1_Channel2,geshu+1);             //设置DMA长度,即脉冲数量
  3. DMA_Cmd(DMA1_Channel2, ENABLE);                            //开启
复制代码
这里设置DMA 传输长度,另传输长度到了就产生中断。
  1. TIM_SetCounter(TIM2, 0);                                   //确保定时器计数归零
  2. TIM_Cmd(TIM2, ENABLE);                                     //开启
复制代码
开始。


上面个人的理解应该是没什么问题,问题是,这个跟,以下两个基地址设置是有什么关系。
  1. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&TIM2->CCR1;               //DMA外设基地址
  2. DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)&DutyCycle1;               //DMA内存基地址
复制代码



希望路过的大佬,指点一下,不胜感激。
附上工程 F103.zip (4.28 MB, 下载次数: 29)

最佳答案

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

问题解决:之前想的是把占空比设置成0,应该就会保持低电平,实际上没有,还是有些结束的时候是高电平。 TIM_SetCompare1(TIM2, 0); 然后修改成,在DMA中断的时候,把占空比修改成 100,就保持了低电平了。 TIM_SetCompare1(TIM2, 100);
茵茵猪头
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

28

主题

294

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1790
金钱
1790
注册时间
2018-3-26
在线时间
294 小时
 楼主| 发表于 2021-6-23 16:41:09 | 显示全部楼层
问题解决:之前想的是把占空比设置成0,应该就会保持低电平,实际上没有,还是有些结束的时候是高电平。
TIM_SetCompare1(TIM2, 0);

然后修改成,在DMA中断的时候,把占空比修改成 100,就保持了低电平了。
TIM_SetCompare1(TIM2, 100);
茵茵猪头
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-6-23 17:04:03 | 显示全部楼层
外设地址就是你的TIM_CCR,内存地址是你的待写入数据地址,你要停在低电平的话就脉冲计数+查询TIM计数值,到脉冲数了再查询TIM值,在低电平的时候disable
回复

使用道具 举报

28

主题

294

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1790
金钱
1790
注册时间
2018-3-26
在线时间
294 小时
 楼主| 发表于 2021-6-23 17:24:56 | 显示全部楼层
阿侑kevin 发表于 2021-6-23 17:04
外设地址就是你的TIM_CCR,内存地址是你的待写入数据地址,你要停在低电平的话就脉冲计数+查询TIM计数值, ...

再用中断或者加个定时器来脉冲计数的话,就背离了使用这个工程目的(节约mcu),我在DMA 中断,加 TIM_SetCompare1(TIM2, 0);  占空比设置成0 ,还是会有这个问题。
茵茵猪头
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-6-24 09:05:05 | 显示全部楼层
htao 发表于 2021-6-23 17:24
再用中断或者加个定时器来脉冲计数的话,就背离了使用这个工程目的(节约mcu),我在DMA 中断,加 TIM_SetC ...

完整的脉冲周期本来就是低开始高结束或是高开始低结束,你要低开始低结束的话脉冲就不完整了,只有正脉宽没有负脉宽,会被多计一个脉冲或是少计一个脉冲的
回复

使用道具 举报

28

主题

294

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1790
金钱
1790
注册时间
2018-3-26
在线时间
294 小时
 楼主| 发表于 2021-6-25 09:16:37 | 显示全部楼层
再给自己顶一下
茵茵猪头
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4638
金钱
4638
注册时间
2017-7-6
在线时间
705 小时
发表于 2021-7-7 14:18:42 | 显示全部楼层
htao 发表于 2021-6-23 17:24
再用中断或者加个定时器来脉冲计数的话,就背离了使用这个工程目的(节约mcu),我在DMA 中断,加 TIM_SetC ...

有些PWM你输出占空比0,是不能完全输出你想要的电平
我是小白,很白很白的小白!!!
回复

使用道具 举报

3

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2021-1-11
在线时间
30 小时
发表于 2021-7-29 16:23:55 | 显示全部楼层
顶一下
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 19:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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