OpenEdv-开源电子网

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

FreeRTOS中delay_ms和delay_us的使用疑问

[复制链接]

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
发表于 2019-11-14 10:52:13 | 显示全部楼层 |阅读模式
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
 楼主| 发表于 2019-11-14 14:04:48 | 显示全部楼层
本帖最后由 Apphia 于 2019-11-14 14:11 编辑

如图所示
1.png
2.png
3.png
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
 楼主| 发表于 2019-11-14 14:10:24 | 显示全部楼层
本帖最后由 Apphia 于 2019-11-14 14:13 编辑

我现在用KEAZ128芯片移植的FreeRTOS,但是在除main函数以外的.c文件中无法使用delay_ms和delay_us这两个延时函数,而正点原子的战舰板子就可以,如上图所示,这是为啥,求大神指点。是我哪个地方没有配置好,delay.c文件没动,和裸跑相比。
回复

使用道具 举报

12

主题

146

帖子

0

精华

高级会员

Rank: 4

积分
914
金钱
914
注册时间
2018-7-18
在线时间
384 小时
发表于 2019-11-14 15:02:05 | 显示全部楼层
delay_ms和delay_us  应该只有main.c包含了 声明这两个函数的头文件,所以只能在main.c使用      这不是FreeRTOS的库函数   第三幅图上的才是FreeRTOS自带的函数   线程中延时 一般用库的延时函数
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
 楼主| 发表于 2019-11-14 15:29:57 | 显示全部楼层
本帖最后由 Apphia 于 2019-11-14 15:34 编辑
wwhh 发表于 2019-11-14 15:02
delay_ms和delay_us  应该只有main.c包含了 声明这两个函数的头文件,所以只能在main.c使用      这不是Fre ...

了解您的意思,不过,我在其他.c文件中使用delay_ms和delay_us就用不了,用FreeRTOS库的延时函数就可以,这是为什么呢
1.png
2.png
3.png
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
 楼主| 发表于 2019-11-14 16:10:35 | 显示全部楼层
wwhh 发表于 2019-11-14 15:02
delay_ms和delay_us  应该只有main.c包含了 声明这两个函数的头文件,所以只能在main.c使用      这不是Fre ...

我想要delay_ms和delay_us在其他.c文件中可以正常使用, vTaskDelay()在主函数中可以正常使用,应该是中断服务函数没有移植好,还在找原因
回复

使用道具 举报

12

主题

146

帖子

0

精华

高级会员

Rank: 4

积分
914
金钱
914
注册时间
2018-7-18
在线时间
384 小时
发表于 2019-11-14 16:20:58 | 显示全部楼层
Apphia 发表于 2019-11-14 16:10
我想要delay_ms和delay_us在其他.c文件中可以正常使用, vTaskDelay()在主函数中可以正常使用,应该是中 ...

你的这个delay 文件是移植正点原子例程里面的吧   他的这个好像是用了 STM32的内核定时器实现的  你换了款单片机 应该不是同一个内核 所以用不了  

如果是72M时钟 可以按下面实现(可能内有定时器准 没什么影响)
void soft_delayus(uint32_t tus)
{
        uint16_t i=0;

        while(tus--)
        {
                i=8;
                while(i--);
        }
}

void soft_delayms(uint16_t tms)
{
        while(tms--)
        {
                soft_delayus(1000);
        }
}
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-6-15
在线时间
9 小时
 楼主| 发表于 2019-11-14 16:38:18 | 显示全部楼层
wwhh 发表于 2019-11-14 16:20
你的这个delay 文件是移植正点原子例程里面的吧   他的这个好像是用了 STM32的内核定时器实现的  你换了 ...

不是用的正点原子的,用的KEAZ128的单片机CM0+的内核,中断的问题,已经改好了,但是不知道有没有后遗症,先用着吧,现在vTaskDelay()和delay_ms都可以用了,多谢哈
回复

使用道具 举报

21

主题

131

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
423
金钱
423
注册时间
2019-5-12
在线时间
168 小时
发表于 2020-2-11 12:39:24 | 显示全部楼层
Apphia 发表于 2019-11-14 16:38
不是用的正点原子的,用的KEAZ128的单片机CM0+的内核,中断的问题,已经改好了,但是不知道有没有后遗症 ...
  1. <font size="3">static u8  fac_us=0;                                                        //us延时倍乘数                          
  2. static u16 fac_ms=0;                                                        //ms延时倍乘数,在ucos下,代表每个节拍的ms数

  3. extern void xPortSysTickHandler(void);

  4. //systick中断服务函数,使用FreeRTOS时用到
  5. void SysTick_Handler(void)
  6. {       
  7.     if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
  8.     {
  9.         xPortSysTickHandler();       
  10.     }
  11. }

  12.                           
  13. //初始化延迟函数
  14. //SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
  15. //这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
  16. //SYSCLK:系统时钟频率
  17. void delay_init()
  18. {
  19.         u32 reload;
  20.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK
  21.         fac_us=SystemCoreClock/1000000;                                //不论是否使用OS,fac_us都需要使用
  22.         reload=SystemCoreClock/1000000;                                //每秒钟的计数次数 单位为M  
  23.         reload*=1000000/configTICK_RATE_HZ;                        //根据configTICK_RATE_HZ设定溢出时间
  24.                                                                                                 //reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右       
  25.         fac_ms=1000/configTICK_RATE_HZ;                                //代表OS可以延时的最少单位          

  26.         SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
  27.         SysTick->LOAD=reload;                                                 //每1/configTICK_RATE_HZ秒中断一次       
  28.         SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   
  29. }                                                                    


  30. //延时nus
  31. //nus:要延时的us数.       
  32. //nus:0~204522252(最大值即2^32/fac_us@fac_us=168)                                                                              
  33. void delay_us(u32 nus)
  34. {               
  35.         u32 ticks;
  36.         u32 told,tnow,tcnt=0;
  37.         u32 reload=SysTick->LOAD;                                //LOAD的值                     
  38.         ticks=nus*fac_us;                                                 //需要的节拍数
  39.         told=SysTick->VAL;                                        //刚进入时的计数器值
  40.         while(1)
  41.         {
  42.                 tnow=SysTick->VAL;       
  43.                 if(tnow!=told)
  44.                 {            
  45.                         if(tnow<told)tcnt+=told-tnow;        //这里注意一下SYSTICK是一个递减的计数器就可以了.
  46.                         else tcnt+=reload-tnow+told;            
  47.                         told=tnow;
  48.                         if(tcnt>=ticks)break;                        //时间超过/等于要延迟的时间,则退出.
  49.                 }  
  50.         };                                                                                    
  51. }  
  52. //延时nms,区别于delay_xms(u32 nms) 引发任务调度
  53. //nms:要延时的ms数
  54. //nms:0~65535
  55. void delay_ms(u32 nms)
  56. {       
  57.         if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
  58.         {               
  59.                 if(nms>=fac_ms)                                                //延时的时间大于OS的最少时间周期
  60.                 {
  61.                            vTaskDelay(nms/fac_ms);                         //FreeRTOS延时
  62.                 }
  63.                 nms%=fac_ms;                                                //OS已经无法提供这么小的延时了,采用普通方式延时   
  64.         }
  65.         delay_us((u32)(nms*1000));                                //普通方式延时
  66. }

  67. //延时nms,不会引起任务调度
  68. //nms:要延时的ms数
  69. void delay_xms(u32 nms)
  70. {
  71.         u32 i;
  72.         for(i=0;i<nms;i++) delay_us(1000);
  73. }
  74. </font>
复制代码
原子哥的代码在裸奔上修改了void delay_ms()和void delay_us(),用FreeRTOS的任务调度和vTaskDelay延时,这些是裸奔代码的void delay_ms()和void delay_us()上没有的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-25 21:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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