OpenEdv-开源电子网

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

STM32 F407产生1us正负交替的脉冲信号

[复制链接]

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
发表于 2022-8-24 09:09:56 | 显示全部楼层 |阅读模式
5金钱
利用STM32F407产生两路脉冲信号,两路脉冲信号正脉冲时间和负脉冲时间在1us-2000us之间可以调节,现在用定时器做出来,但是随着时间累加误差越来越大,各位大佬有什么办法让它精准输出吗。

微信图片_20220824091046.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

465

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1732
金钱
1732
注册时间
2021-4-11
在线时间
320 小时
发表于 2022-8-24 11:02:51 | 显示全部楼层
帮顶              
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8463
金钱
8463
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-8-24 16:13:02 | 显示全部楼层
误差越来越大是什么现象?频率有变化还是两路信号相位有变化?
专治疑难杂症
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 16:49:24 | 显示全部楼层
LcwSwust 发表于 2022-8-24 16:13
误差越来越大是什么现象?频率有变化还是两路信号相位有变化?

1us出来是1.3us。10us出来是12us,100us出来是120us
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8463
金钱
8463
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-8-24 16:56:35 | 显示全部楼层
本帖最后由 LcwSwust 于 2022-8-24 17:00 编辑
leleluo123 发表于 2022-8-24 16:49
1us出来是1.3us。10us出来是12us,100us出来是120us

哦,只是误差啊,且基本成比例,那么设置时除以1.2不就行了。
估计是某个地方的系数没整对,
比如你以为是5分频,实际是6分频。
举个例子,给PSC的值为5,你以为是5分频,结果却是6分频。


傲游截图20220824165846.jpg
专治疑难杂症
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 17:29:07 | 显示全部楼层
本帖最后由 leleluo123 于 2022-8-24 17:43 编辑
LcwSwust 发表于 2022-8-24 16:56
哦,只是误差啊,且基本成比例,那么设置时除以1.2不就行了。
估计是某个地方的系数没整对,
比如你以 ...

这个最小是1us,预分屏都设置的1,1才可以出来1us,用的定时器2,是要可调的,不是固定的1us
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-24 18:12:08 | 显示全部楼层
leleluo123 发表于 2022-8-24 17:29
这个最小是1us,预分屏都设置的1,1才可以出来1us,用的定时器2,是要可调的,不是固定的1us

你把调节us部分的代码放出来看一下
又菜又爱指点
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 19:21:32 | 显示全部楼层
驭剑的秘密 发表于 2022-8-24 18:12
你把调节us部分的代码放出来看一下

void TIM2_Int_Init(uint16_t arr,uint8_t psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM2,ENABLE); //使能定时器2
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; //定时器2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
}

void TIM2_IRQHandler(void)
{  
        static uint8_t sec=0;
        static uint16_t sec1=0;
        static uint8_t run_times=0;
       
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET) //溢出中断
        {

                    sec1++;
                    
                  
//                 
//                  if(sec>0&&sec<=1)
//                        {
//                                 //
//                                sec=0;
//                               
//                      sec1++;
//                       
//                        }
               
                  if(sec1>0&&sec1<=20)
                        {
                        GPIO_SetBits(GPIOC,GPIO_Pin_7);
                       
                        GPIO_ResetBits(GPIOD,GPIO_Pin_14);
                        }               
     



  if(sec1>20&&sec1<=100)
                        {
                        GPIO_ResetBits(GPIOC,GPIO_Pin_7);
                                GPIO_ResetBits(GPIOD,GPIO_Pin_14);       
                               
                       
                        }               
                       
          if(sec1>100&&sec1<200)
                {
      {
               
                         GPIO_SetBits(GPIOD,GPIO_Pin_14);
                               
                                        GPIO_ResetBits(GPIOC,GPIO_Pin_7);
                        }                       
                }       
                       
      if(sec1>=200&&sec1<300)
      {
                               
                         GPIO_ResetBits(GPIOD,GPIO_Pin_14);
                                       
                                        GPIO_ResetBits(GPIOC,GPIO_Pin_7);
                        }       
    if(sec1>300)
                {
               
                    sec1=0;
               
                }



                       
//                        else if(sec1>5&&sec1<=8)
//                        {
//                               
//                                  
//                                  GPIO_ResetBits(GPIOC,GPIO_Pin_7);
//                         
//                        }
//                       
//                       
//                       
//                else if(sec1>=8&&sec1<15)
//                        {
//                         GPIO_ResetBits(GPIOC,GPIO_Pin_7);
//        
//                       
//                       
//                        }
               
//                 if(sec1>1)
//                {
//                                //run_times++;
//       sec1=0;
//         GPIO_ResetBits(GPIOC,GPIO_Pin_7);
//                 //GPIO_ResetBits(GPIOD,GPIO_Pin_14);
//                }
//                               
//                          
//                                 //USART_Cmd(USART2, ENABLE);
//                //        }
////                        if(run_times>=count)
////                        {
////                          run_times=0;
////                                //sec=0;
////                                TIM_Cmd(TIM2,DISABLE);
////                          //使能串口1
////             TIM_Cmd(TIM5, ENABLE);
////                               
//                }
        }
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //清除中断标志位
}


回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-24 19:26:37 | 显示全部楼层
leleluo123 发表于 2022-8-24 19:21
void TIM2_Int_Init(uint16_t arr,uint8_t psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructur ...

多出来的时间是不是花在if条件的判断上了,你试试switch
又菜又爱指点
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 19:33:17 | 显示全部楼层
驭剑的秘密 发表于 2022-8-24 19:26
多出来的时间是不是花在if条件的判断上了,你试试switch

这个需要让某一段时间电平变成高或者低,switch貌似不可以
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-24 19:36:30 | 显示全部楼层
leleluo123 发表于 2022-8-24 19:33
这个需要让某一段时间电平变成高或者低,switch貌似不可以

case 1:高;
case 10:低;
case 100:高;
在1~10这段时间内是高,10~100这段时间是低,这样不行吗
又菜又爱指点
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-24 19:38:06 | 显示全部楼层
leleluo123 发表于 2022-8-24 19:33
这个需要让某一段时间电平变成高或者低,switch貌似不可以

你这里的if,每一次中断进来,他每一个if都使用了点时间,然后在进入下一个阶段之前,某一个if还会一直被执行,我觉得这里使用了非常多的时间
又菜又爱指点
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 20:01:29 | 显示全部楼层
驭剑的秘密 发表于 2022-8-24 19:26
多出来的时间是不是花在if条件的判断上了,你试试switch

好的,thanks
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-24 20:02:02 | 显示全部楼层
驭剑的秘密 发表于 2022-8-24 19:36
case 1:高;
case 10:低;
case 100:高;

好的,谢谢
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-25 10:12:58 | 显示全部楼层
驭剑的秘密 发表于 2022-8-24 19:38
你这里的if,每一次中断进来,他每一个if都使用了点时间,然后在进入下一个阶段之前,某一个if还会一直被 ...

看来一下,时间是个变量,可以设置,swich,不可以的
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8463
金钱
8463
注册时间
2020-5-11
在线时间
3904 小时
发表于 2022-8-25 10:43:09 | 显示全部楼层
leleluo123 发表于 2022-8-24 17:29
这个最小是1us,预分屏都设置的1,1才可以出来1us,用的定时器2,是要可调的,不是固定的1us

哦,你的代码是每1us都要进中断去做各种判断、控制IO口,估计中断服务函数耗时大于1us,所以定时不准确,估计主循环基本没机会运行。建议使用PWM功能,或者定时触发DMA将值传递到IO口。
专治疑难杂症
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-25 10:54:07 | 显示全部楼层
LcwSwust 发表于 2022-8-25 10:43
哦,你的代码是每1us都要进中断去做各种判断、控制IO口,估计中断服务函数耗时大于1us,所以定时不准确, ...

没有,点击运行的时候才触发定时器,PWM不可以的,这个需要实时更改正负脉冲时间的哦
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2022-8-25 16:47:01 | 显示全部楼层
1.用定时器配和DMA做,
2.在你这代码上面加优化修改
1-1
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-25 18:25:24 | 显示全部楼层
你这个脉冲具体什么要求,能说一下不,我做着玩玩看
又菜又爱指点
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-25 18:57:46 来自手机 | 显示全部楼层
我现在弄了一个周期2000us,占空比可调的,不知道跟你那个要求差多少
IMG_20220825_185452.jpg
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-27 11:32:05 | 显示全部楼层
驭剑的秘密 发表于 2022-8-25 18:57
我现在弄了一个周期2000us,占空比可调的,不知道跟你那个要求差多少

辛苦了,这个需要正高脉冲时间可以调节,正负脉冲可以调节的
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-29 09:39:44 | 显示全部楼层
leleluo123 发表于 2022-8-27 11:32
辛苦了,这个需要正高脉冲时间可以调节,正负脉冲可以调节的

我就做着玩的,这两天确实不忙,只是想看一下我做不做得出来,你这个是有两路哦?
又菜又爱指点
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-29 14:59:57 | 显示全部楼层
驭剑的秘密 发表于 2022-8-29 09:39
我就做着玩的,这两天确实不忙,只是想看一下我做不做得出来,你这个是有两路哦?

两路IO口输出两路脉冲信号,其中一路高电平脉冲时间为t1,低脉冲时间为t2,另一路脉冲高电平时间为t3,低电平时间为t4,,其中两路脉冲的不能出现高低电平相交,t1,t3为1-10us可以调,t2,t4为1-2000us可调
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-29 15:02:13 | 显示全部楼层
mygod 发表于 2022-8-25 16:47
1.用定时器配和DMA做,
2.在你这代码上面加优化修改

定时器DMA怎么用,貌似没有用过
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-29 17:21:38 来自手机 | 显示全部楼层
leleluo123 发表于 2022-8-29 15:02
定时器DMA怎么用,貌似没有用过

我先做了一路出来,只用了定时器PWM
IMG_20220829_171826.jpg
IMG_20220829_171817.jpg
IMG_20220829_171810.jpg
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-29 17:25:16 | 显示全部楼层
驭剑的秘密 发表于 2022-8-29 17:21
我先做了一路出来,只用了定时器PWM

1us还是很精准的,所以建议用定时器做
又菜又爱指点
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-31 08:50:31 | 显示全部楼层
驭剑的秘密 发表于 2022-8-29 17:25
1us还是很精准的,所以建议用定时器做

你这个用的定时器几哦,是正负脉冲都可以设置的吗
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-8-31 09:22:19 | 显示全部楼层
驭剑的秘密 发表于 2022-8-29 17:25
1us还是很精准的,所以建议用定时器做

我这边也用的是定时器,那个高低脉宽可以设置不同时间吗。把你的代码发过来借鉴一下
回复

使用道具 举报

54

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1042
金钱
1042
注册时间
2022-4-20
在线时间
373 小时
发表于 2022-8-31 14:08:49 | 显示全部楼层
leleluo123 发表于 2022-8-31 09:22
我这边也用的是定时器,那个高低脉宽可以设置不同时间吗。把你的代码发过来借鉴一下

可以设置不同时间,你看我那三张图。
刚准备出门,才发现小区被封控了,一时半会应该是出不去了,程序没在家,我给你个思路。
原子例程里面有个PWM的例程,你直接根据t1,t2的时间算出周期,然后设定自动重装值和预分频数,每改动一次t1或者t2就重新调用这段函数就行了
又菜又爱指点
回复

使用道具 举报

0

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2021-12-12
在线时间
10 小时
发表于 2022-9-3 14:36:31 | 显示全部楼层
没有 我用定时器延时1us 实际延时有2.4us 我用示波器看的 他的误差有1.4us
回复

使用道具 举报

1

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2016-9-12
在线时间
51 小时
 楼主| 发表于 2022-9-3 14:37:02 | 显示全部楼层
驭剑的秘密 发表于 2022-8-31 14:08
可以设置不同时间,你看我那三张图。
刚准备出门,才发现小区被封控了,一时半会应该是出不去了,程序没 ...

我测试了,低电平时间不可设置
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 04:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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