OpenEdv-开源电子网

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

原子例程跑马灯改为us级延时器bug

[复制链接]

1

主题

4

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-2-6
在线时间
7 小时
发表于 2020-3-20 09:28:49 | 显示全部楼层 |阅读模式
1金钱
开发板F429。例程,跑马灯。
修改的地方:将跑马灯的输出IO口改为PH9
                    每隔3msPH9输出高电平2us
                   LED_Init()函数中,将IO口配置为PH9
问题:1,2us高电平时间不准,是2.3us,偏差太大。
         2,2.3us的时间有时会变大,每隔7.4秒钟变为2.4us

main中代码如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
/************************************************
ALIENTEK 阿波罗STM32F429开发板 实验1
跑马灯实验-HAL库版本

/*下面主函数是使用HAL库函数实现控制IO口输出*/

int main(void)
{
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    LED_Init();                     //初始化LED  
    while(1)
    {
       // HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //LED0对应引脚PB1拉低,亮,等同于LED0(0)
        HAL_GPIO_WritePin(GPIOH,GPIO_PIN_9,GPIO_PIN_SET);   //LED1对应引脚PB0拉高,灭,等同于LED1(1)
                          delay_us(2);
       // delay_ms(500);                                                                                //延时500ms
      //  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);   //LED0对应引脚PB1拉高,灭,等同于LED0(1)
        HAL_GPIO_WritePin(GPIOH,GPIO_PIN_9,GPIO_PIN_RESET); //LED1对应引脚PB0拉低,亮,等同于LED1(0)
        delay_ms(3);                                      //延时500ms
    }
}



LED_Init()函数修改后代码如下:

void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOH_CLK_ENABLE();           //开启GPIOB时钟
       
    GPIO_Initure.Pin=GPIO_PIN_9; //PH9
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FAST;     //高速
    HAL_GPIO_Init(GPIOH,&GPIO_Initure);
       
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_9,GPIO_PIN_RESET);        //PH9置1,默认初始化后灯灭
    //HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);        //PB1置1,默认初始化后灯灭
}



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

使用道具 举报

2

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2020-3-13
在线时间
24 小时
发表于 2020-3-20 10:46:39 | 显示全部楼层
很正常吧,2us定时实际2.3us,就差了300ns,对于us级定时来说很准了,晶振也不可能绝对是8.00M,肯定会有误差,加上软件处理上的延迟响应,高优先级中断打断滴答定时器中断…在使用系统时钟定时的时候高精度的定时只适合来一次,因为误差是会累积的
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-2-6
在线时间
7 小时
 楼主| 发表于 2020-3-20 13:03:36 | 显示全部楼层
for人生 发表于 2020-3-20 10:46
很正常吧,2us定时实际2.3us,就差了300ns,对于us级定时来说很准了,晶振也不可能绝对是8.00M,肯定会有误 ...

感谢回复。你说的我大概知道,但是应该如何解决这种每3ms输出2us的的高电平呢?对于180M的主频来说,2us实现应该一点没问题。用定时器中断来做吗?
回复

使用道具 举报

2

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2020-3-13
在线时间
24 小时
发表于 2020-3-20 16:50:56 | 显示全部楼层
zhang119320 发表于 2020-3-20 13:03
感谢回复。你说的我大概知道,但是应该如何解决这种每3ms输出2us的的高电平呢?对于180M的主频来说,2us ...

这种规律性的脉冲用PWM可能是最好的方案,但你这个2/3002的占空比太小了,用32位的定时器不知道能不能搞定,实在不行就只能用中断了
回复

使用道具 举报

127

主题

207

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1077
金钱
1077
注册时间
2017-9-11
在线时间
105 小时
发表于 2020-3-20 22:42:47 | 显示全部楼层
用3ms的定时中断,然后用软延时输出高电平,你这种精确2μs还是自己做子函数用nop来写吧
回复

使用道具 举报

127

主题

207

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1077
金钱
1077
注册时间
2017-9-11
在线时间
105 小时
发表于 2020-3-21 10:13:09 | 显示全部楼层
huyuezhan 发表于 2020-3-20 22:42
用3ms的定时中断,然后用软延时输出高电平,你这种精确2μs还是自己做子函数用nop来写吧

如果是IAR编译器,有__delay_cycles(x)这样的精确跑多少时钟周期的软延时函数
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-3 17:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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