OpenEdv-开源电子网

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

关于SYSTICK的问题

[复制链接]

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
发表于 2017-8-16 21:11:40 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 Mojo 于 2017-8-17 09:49 编辑

       我用原子哥的HAL库版本的教程自己新建了一个工程模板,然后复制了原子哥的“跑马灯试验的原代码到main函数里,同时复制了LED.c里面的代码,运行之后发现SYSTICK并未运行,卡在了delay_us的while循环里,因为tnow和told都为零(SYSTICK未运行)。 经过一番研究之后发现,我在delay.c的函数systick时钟那里加上HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U)函数之后,SYSTICK就可以正常运行了,但是我在原子哥的”跑马灯试验“原代码里并未发现使用这段函数,并且HAL_Init();里面也已经包含了这段函数,我自己建的模板里的HAL_Init()同样包含了此段函数。
       想不明白为什么原子哥的原代码里没有这段函数也可以让SYSTICK工作,而我的模板和代码与原子哥的都是一样的我的就不能让SYSTICK工作。

在旺旺上找了技术支持,未果,望有知道为什么的朋友告知一下。十分感谢!

最佳答案

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

又对比了下,没什么区别,我在连着板子仿真的时候看了下,原子哥的原版工程在仿真的时候SysTick里面的VAL和CURRENT寄存器不是实时在变化的,只有停止再运行才会发现变化,但是不知道为什么SYSTICK控制下的delay函数依然准确的在计时,当然,单步运行也可以看见变化,但是全速运行的时候就看不到变化了,而我自己的工程在把CTRL|=0x01和LOAD=0x00FFFF(当然,别的值也可以)运行之后,SysTick里面的VAL和CURRENT寄存器在全速 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-16 21:11:41 | 显示全部楼层
       又对比了下,没什么区别,我在连着板子仿真的时候看了下,原子哥的原版工程在仿真的时候SysTick里面的VAL和CURRENT寄存器不是实时在变化的,只有停止再运行才会发现变化,但是不知道为什么SYSTICK控制下的delay函数依然准确的在计时,当然,单步运行也可以看见变化,但是全速运行的时候就看不到变化了,而我自己的工程在把CTRL|=0x01和LOAD=0x00FFFF(当然,别的值也可以)运行之后,SysTick里面的VAL和CURRENT寄存器在全速运行的时候也是一直在变化。
       很奇怪啊,但是不知道是哪里出了问题,希望原子哥能帮忙看下,我估计出现这种问题的人不止我一人。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-8-16 22:05:53 | 显示全部楼层
C语言找不到的代码,可能 是在汇编里面有.不然, 就是有库文件里面有.
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 08:40:32 | 显示全部楼层
操作系统 发表于 2017-8-16 22:05
C语言找不到的代码,可能 是在汇编里面有.不然, 就是有库文件里面有.

      模板都是和原子的相同,都是用的HAL库,而CUBE包文件是在原子提供的资源里考的,就是有汇编那新建的模板里应该也有相同的代码。     实际应用部分(跑马灯)的代码也是完全复制的。   
      我仔细的对比过,除了数字上有区别外(原子的模板用的库里写的1000,我的里面写的1000U)别的都是一样的。而这个1000还是1000U应该不会是导致不写HAL_SYSTICK_Config()函数SYSTICK就不运行的原因的。我也只是对比了相关的代码,可能有些我没发现。对这个函数我也只是做了全局搜索。
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-8-17 08:58:11 | 显示全部楼层
main函数里面有没有调用函数delay_init()来初始化systick?
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 09:47:54 | 显示全部楼层
zuozhongkai 发表于 2017-8-17 08:58
main函数里面有没有调用函数delay_init()来初始化systick?

有啊,delay_init(180);
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 09:50:06 | 显示全部楼层
本帖最后由 李小龙 于 2017-8-17 09:53 编辑

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U)这个函数你可以跳进去看看调用了SysTick_Config( )函数,这个函数内部初始化的是systick的相关寄存器。而原子哥的代码直接把SysTick_Config( )函数内部代码写出来了,没有调用SysTick_Config( )函数。所以你看见原子哥没用HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U)为什么也可以了。知道了吧。[mw_shl_code=applescript,true]uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
{
   return SysTick_Config(TicksNumb);
}[/mw_shl_code]

[mw_shl_code=applescript,true]__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
    return (1UL);                                                   /* Reload value impossible */
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}[/mw_shl_code]

下面是原子哥的systick初始化代码
[mw_shl_code=applescript,true]        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //开启SYSTICK中断
        SysTick->LOAD=reload;                                                 //每1/delay_ostickspersec秒中断一次       
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //开启SYSTICK   
[/mw_shl_code]
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 10:03:34 | 显示全部楼层
李小龙 发表于 2017-8-17 09:50
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U)这个函数你可以跳进去看看调用了SysTick_Config( )函数 ...

我并未使用OS,只是简单的跑马灯试验。你在最下面的部分代码我在原子哥的例程里看了下,完全体是这样的:
[mw_shl_code=applescript,true]#if SYSTEM_SUPPORT_OS
        reload=SYSCLK;
        reload*=1000000/delay_ostickspersec;
        fac_ms=1000/delay_ostickspersec;
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
        SysTick->LOAD=reload;
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; [/mw_shl_code]
原子哥的代码里只有在SYSTEM_SUPPORT_OS为1时你最后提到的代码才会被执行,但是这个跑马灯实验并未这样做啊。
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 10:09:16 | 显示全部楼层
李小龙 发表于 2017-8-17 09:50
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000U)这个函数你可以跳进去看看调用了SysTick_Config( )函数 ...

另外,代码我是完完全全复制的原子哥的啊。只不过工程模板是我自己建的,编译过后也无任何问题。
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 10:31:22 | 显示全部楼层
Mojo 发表于 2017-8-17 10:09
另外,代码我是完完全全复制的原子哥的啊。只不过工程模板是我自己建的,编译过后也无任何问题。

那个原子哥的代码是在ucos下用的,太久了,没看清。
是这样的:原子哥代码中普通延时并没有开systick中断,[mw_shl_code=applescript,true]#else //不用OS时
//延时nus
//nus为要延时的us数.                                                                                       
void delay_us(uint32_t nus)
{               
        uint32_t temp;                     
        SysTick->LOAD=nus*fac_us;                                         //时间加载                           
        SysTick->VAL=0x00;                                                //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数         
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                                               //清空计数器         
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(uint16_t nms)
{                                    
        uint32_t temp;                  
        SysTick->LOAD=(uint32_t)nms*fac_ms;                                //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                                                        //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数  
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                                               //清空计数器                     
} [/mw_shl_code]

每次调用延时函数时都重新配置systick寄存器哦。
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 10:35:47 | 显示全部楼层
李小龙 发表于 2017-8-17 10:31
那个原子哥的代码是在ucos下用的,太久了,没看清。
是这样的:原子哥代码中普通延时并没有开systick中 ...

而且你配置的模板中是开乐1ms的中断哦

  /*Configure the SysTick to have interrupt in 1ms time basis*/
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

你要用原子哥的代码,至少也要屏蔽这段代码吧

我自己HAL库搭的工程,移植原子哥的延时函数没有一点问题呀
再仔细把代码过一遍吧,估计你没看懂代码含义
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 10:37:42 | 显示全部楼层
Mojo 发表于 2017-8-17 10:09
另外,代码我是完完全全复制的原子哥的啊。只不过工程模板是我自己建的,编译过后也无任何问题。

编译没问题,只能说明,没有语法问题,但并不能代表有逻辑问题呀,况且这是和硬件有关系的
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 11:51:59 | 显示全部楼层
李小龙 发表于 2017-8-17 10:35
而且你配置的模板中是开乐1ms的中断哦

  /*Configure the SysTick to have interrupt in 1ms time bas ...

我知道这个是开中断的,/1000   /100000 /1000000是1ms,10us,1us。但是不开这个中断我复制的原子哥的代码这个SYSTICK根本就不运行啊。   代码不是我自己写的,我只是新建了个模板而已,代码是复制原子哥的,所以代码肯定都是一样的。而模板是按照原子哥的教程来建的,所以模板应该也是一样的,这样的话运行的效果应该也是一样的才对。
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 12:10:08 | 显示全部楼层
Mojo 发表于 2017-8-17 11:51
我知道这个是开中断的,/1000   /100000 /1000000是1ms,10us,1us。但是不开这个中断我复制的原子哥的代码 ...

把你代码上传上来看看,这样说是讲不明白的
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 12:11:37 | 显示全部楼层
李小龙 发表于 2017-8-17 12:10
把你代码上传上来看看,这样说是讲不明白的

我看看你的代码,这样比较容易找到问题
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 12:28:13 | 显示全部楼层
和原子哥的跑马灯试验是一模一样的代码。   只不过我是用原子哥提供的STM32Cube_FW_F4_V1.11.0版本的Cube包建的模板。我在想是不是包的版本的问题。

templete.zip

2.17 MB, 下载次数: 151

分卷1

回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 12:33:20 | 显示全部楼层
Mojo 发表于 2017-8-17 12:28
和原子哥的跑马灯试验是一模一样的代码。   只不过我是用原子哥提供的STM32Cube_FW_F4_V1.11.0版本的Cube包 ...

上传格式限制,请去掉.zip     扩展名应该是.z01。       分卷2

templete.z01.zip

15 MB, 下载次数: 194

去掉.zip

回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 12:37:53 | 显示全部楼层
Mojo 发表于 2017-8-17 12:33
上传格式限制,请去掉.zip     扩展名应该是.z01。       分卷2


一共三个分卷,这是分卷三。         其中我后面自己添加的HAL_SYSTICK_Config()部分我已经注释掉,代码是复制原子哥的,只是模板是我自己建的。    麻烦帮忙看下是哪出了问题,只有添加上我前面说的函数SYSTICK才会运行。     而原子哥的代码里并没有加这段代码,另外,HAL_Init()里应该已经有HAL_SYSTICK_Config()函数了。

templete.z02.zip

15 MB, 下载次数: 228

回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 12:39:54 | 显示全部楼层
李小龙 发表于 2017-8-17 12:11
我看看你的代码,这样比较容易找到问题

麻烦帮忙看一下,由于格式和大小限制,我弄了三个分卷,有两个分卷需要把扩展名改一下。十分感谢,这就是SYSTICK不运行的工程,模板是我自己建的,库文件用的版本是STM32Cube_FW_F4_V1.11.0,代码复制原子哥的。
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 12:46:41 | 显示全部楼层
Mojo 发表于 2017-8-17 12:39
麻烦帮忙看一下,由于格式和大小限制,我弄了三个分卷,有两个分卷需要把扩展名改一下。十分感谢,这就是 ...

文件损坏,解压不出来。有百度网盘吗?上传网盘,然后分享链接给我
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 14:21:41 | 显示全部楼层
李小龙 发表于 2017-8-17 12:46
文件损坏,解压不出来。有百度网盘吗?上传网盘,然后分享链接给我

http://pan.baidu.com/s/1qYhr6Ja
回复

使用道具 举报

13

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2016-7-15
在线时间
175 小时
发表于 2017-8-17 15:51:26 | 显示全部楼层
Mojo 发表于 2017-8-17 14:21
http://pan.baidu.com/s/1qYhr6Ja

建议你硬件仿真下,查看systick寄存器,因为我没有F4的板子,没办法帮你仿真。
回复

使用道具 举报

3

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2017-7-4
在线时间
11 小时
 楼主| 发表于 2017-8-17 16:04:30 | 显示全部楼层
本帖最后由 Mojo 于 2017-8-17 16:25 编辑
李小龙 发表于 2017-8-17 15:51
建议你硬件仿真下,查看systick寄存器,因为我没有F4的板子,没办法帮你仿真。

我试着不用HAL_SYSTICK_Config()而直接给SysTick的LOAD寄存器赋了个值,把CTRL寄存器便能,也是可以让SYSTICK成功跑起来,我再找找看问题到底出在哪里再说。我一直都是连着板子仿真的。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-18 20:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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