关于SYSTICK的问题

2019-07-20 12:32发布

本帖最后由 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工作。

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

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
22条回答
Mojo
1楼-- · 2019-07-21 09:19
李小龙 发表于 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时你最后提到的代码才会被执行,但是这个跑马灯实验并未这样做啊。
Mojo
2楼-- · 2019-07-21 11:47
 精彩回答 2  元偷偷看……
李小龙
3楼-- · 2019-07-21 13:48
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寄存器哦。
李小龙
4楼-- · 2019-07-21 19:18
李小龙 发表于 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库搭的工程,移植原子哥的延时函数没有一点问题呀
再仔细把代码过一遍吧,估计你没看懂代码含义
李小龙
5楼-- · 2019-07-22 00:19
 精彩回答 2  元偷偷看……
Mojo
6楼-- · 2019-07-22 05:16
李小龙 发表于 2017-8-17 10:35
而且你配置的模板中是开乐1ms的中断哦

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

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

一周热门 更多>