当前位置: 首页 > news >正文

#基于一个小车项目的FREERTOS分析(一)系统时钟

系统时钟

//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
//SYSCLK:系统时钟频率
/*  系统定时器是一个 24bit
的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK
等于168M*/
void delay_init(u8 SYSCLK) 
{u32 reload;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); /* 系统滴答定时器时钟源初始化 使用时钟源为 SysTick_CLKSource_HCLK  HCLK代表CPU时钟*/fac_us=SYSCLK;							//不论是否使用OS,fac_us都需要使用reload=SYSCLK;							//每秒钟的计数次数 单位为M	   reload*=1000000/configTICK_RATE_HZ;		//根据configTICK_RATE_HZ设定溢出时间  reload=168000//reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右	fac_ms=1000/configTICK_RATE_HZ;			//代表OS可以延时的最少单位	    fac_ms = 1SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断SysTick->LOAD=reload; 					//每1/configTICK_RATE_HZ断一次	/* 0.0001s 中断一次LOAD重装载值 SYSCLK=168 计算 reload=16800   按HCLK为168M算 1/168M * 16800=0.0001s*/SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK     
}	
//延时nus
//nus:要延时的us数.	
//nus:0~204522252(最大值即2^32/fac_us@fac_us=168)	    								   
void delay_us(u32 nus)
{		u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD;				//LOAD的值	    	 ticks=nus*fac_us; 						//需要的节拍数  reload值并不会影响时基(1/HCLK)也就是不会影响一个节拍的时长进而不会影响us reload会影响systick中断频率told=SysTick->VAL;        				//刚进入时的计数器值while(1){tnow=SysTick->VAL;	if(tnow!=told){	    if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.else tcnt+=reload-tnow+told;	    told=tnow;if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.}  };										    
}  
//延时nms
//nms:要延时的ms数
//nms:0~65535
void delay_ms(u32 nms)
{	if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行{		if(nms>=fac_ms)						//延时的时间大于OS的最少时间周期 { vTaskDelay(nms/fac_ms);	 		//FreeRTOS延时   fac_ms=1 也就是说>1ms的ms延时都是使用的vTaskDelay}nms%=fac_ms;						//OS已经无法提供这么小的延时了,采用普通方式延时    }delay_us((u32)(nms*1000));				//普通方式延时
}//延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{u32 i;for(i=0;i<nms;i++) delay_us(1000);
}

vTaskDelay完成
1调用vTaskSuspendAll()挂起任务调度器,
2调用 prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );将要延时的任务添加到延时列表中
3xAlreadyYielded = xTaskResumeAll(); 调用 xTaskResumeAll();恢复任务调度
4.如果发生任务调度调用portYIELD_WITHIN_API();产生任务调度。

#if ( INCLUDE_vTaskDelay == 1 )void vTaskDelay( const TickType_t xTicksToDelay ){BaseType_t xAlreadyYielded = pdFALSE;/* A delay time of zero just forces a reschedule. */if( xTicksToDelay > ( TickType_t ) 0U ){configASSERT( uxSchedulerSuspended == 0 );vTaskSuspendAll();{traceTASK_DELAY();/* A task that is removed from the event list while thescheduler is suspended will not get placed in the readylist or removed from the blocked list until the scheduleris resumed.This task cannot be in an event list as it is the currentlyexecuting task. */prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );}xAlreadyYielded = xTaskResumeAll();}else{mtCOVERAGE_TEST_MARKER();}/* Force a reschedule if xTaskResumeAll has not already done so, we mayhave put ourselves to sleep. */if( xAlreadyYielded == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}#endif /* INCLUDE_vTaskDelay */
http://www.lryc.cn/news/190086.html

相关文章:

  • ubuntu mmdetection配置
  • 嵌入式面试常见问题(一)
  • docker批量删除本地镜像
  • 数据结构(一)—— 数据结构简介
  • Ubuntu输入正确密码重新跳到登录界面
  • TCP/IP(十四)流量控制
  • CSS网页标题图案和LOGO SEO优化
  • 机器人制作开源方案 | 双轮提升搬运小车
  • 5G安卓核心板-MT6833/MT6853核心板规格参数
  • 信创之国产浪潮电脑+统信UOS操作系统体验4:visual studio code中怎么显示中文
  • Magica Cloth 使用方法笔记
  • c++ 学习之 强制类型转换运算符 const_cast
  • Ceph相关部署应用(博客)
  • 基于 ceph-deploy 部署 Ceph 集群 超详细
  • 做一个物联网的后台程序与数据库设计
  • Pytorch深度学习—FashionMNIST数据集训练
  • uniapp 返回上一步携带参数
  • 软件工程与计算总结(七)需求文档化与验证
  • MySQL锁概述
  • 【Ceph Block Device】块设备挂载使用
  • Arbitrum Stylus 的工作原理
  • nextjs构建服务端渲染,同时使用Material UI进行项目配置
  • Java 使用 Easyexcel 导出大量数据
  • 高效防汛决策:山海鲸可视化系统助力城市防洪
  • 易点云CFO向征:CFO不能只讲故事,价值创造才是核心
  • 【计算机网络】poll | epoll
  • C++设计模式_07_Bridge 桥模式
  • [JAVA版本] Websocket获取B站直播弹幕——基于直播开放平台
  • 第一个 Python 程序
  • 广告牌安全监测,保障户外广告牌的安全与稳定