haldelay是多少时间,汇编DELAY 的时间计算
来源:整理 编辑:亚灵电子网 2023-04-01 17:58:46
本文目录一览
1,汇编DELAY 的时间计算
RET 返回主程序 你调用的那句时间0.2X20X20X248us寄存器R0-r7 默认是内部数据存储器00H-07Hdelay应该是个函数,你函数里按bl是分钟来编的因为延时的具体实现应该计算时钟频率,循环,或者定时中断来实现
2,halwait 函数
void halWait(BYTE wait)我复制的,我就想问问你是不是搞ZIGBEE.......??

3,可不可以具体讲一下delay括号里面的值代表的时间大概值怎么
这个函数是平台依赖的,不同的操作平台不一样通常参数为毫秒当然也有可能是tick, 1/主频 就是tick的单位好像在菩提脚本里的(等待,xxx)均以秒计,另外还有一种如延时,1000)则是以毫秒计,1000毫秒=1秒,不知你提到的(等待300,等待480,)是那里来的?
4,cube切换了时钟haldelay还不行
一.现象(未使用freertos等操作系统)不管是在main中的task还是中断服务函数,调用HAL_Delay系统就处于卡死状态;(起初怀疑优先级过低导致,但NVIC配置Base SysTick优先级高于中断优先级也不触发Base SysTick中断)二.断点调试发现HAL_GetTick()->uwTick始终不变,问题确定uwTick未进行设置,对应到改变uwTick的库函数HAL_IncTick,发现没有地方调用;而系统时钟中断函数SysTick_Handler也未实现任何功能,在Core\Src\stm32f1xx_it.c添加如下代码:
5,DELAY子程序的时间怎么计算
该程序的延时是靠 内部循环(DJNZ R6,D2),该句执行“R6”次即250次循环,在内循环的外面还要进行“R7”即250次外循环(DJNZ R7,D1),所以一共执行250*250次循环,根据你晶振的频率算出机器周期后,再结合循环次数就可以得出时间了。。。。自己需要设定其他值的话,修改R6,R7的值就可以了!
6,stm32超轻量操作系统之抢占式内核
这一章比上一章内容多了不少。第一章完成了任务切换功能,这一章在任务切换功能上增加了以下几个功能。 1.改变特权级,加入SVC异常 2.增加优先级,使得内核可以抢占。 3.增加了滴答定时器中断功能,使得同优先级的任务以时间片方式调度。 4.增加延时函数。 接下来一项一项介绍。 1. 改变特权级 第一章中,所有的程序都是运行在特权级下。在中断中时切换到内核模式,在任务中切换到线程模式(Thread),但是权限都是特权级,意味着程序对内存中所有的数据都有修改的权限。此处加入两张图,通过修改寄存器,可以在退出中断后,在任务中运行即线程模式时权限是非特权级,这样在线程模式时就不能够更改内核模式下的数据了,程序的更具有健壮性。更改特权级只能在特权级下更改,所以通过在PendSV最后加入红色字体部分来更改了特权级。 __ASM void PendSVPopData() extern PendSVFirst; extern currTCB; extern nextTCB; PRESERVE8 LDR R0,=currTCB //R0=currTCB LDR R1,=nextTCB //R1=nextTCB LDR R1,[R1] //R1=*R1 STR R1,[R0] //*R0=R1 currTCB=nextTCB完成了指向新的任务TCB的工作 LDR R0,[R1] //R0=*R1 R0保存了TCB堆栈栈顶的指针 LDMIA R0!, MSR PSP,R0 //PSP=R0 ORR LR,LR,#0x04 //LR=LR|0x04,表示函数返回后使用PSP指针 //使程序运行在非特权级,设置CONTROL[0]位为1,这样内核级和用户级就分开了,即是某个线程出现了问题也不会影响内核 LDR R1,=0x3 MSR CONTROL,R1 ISB CPSIE I BX LR nop } 同时要注意在非特权级(用户级)下只有触发异常才可以进入重新进入特权级,因此额外加入了SVC异常来主动触发中断。 还记得我们上一章讲过的发起任务调度的两种方式吗? 1.产生异常。 2.systick定时器中断。 其中第一条就是SVC异常中断。SVC异常用于产生系统调用,它的优先级最高,一经调用立刻进入此异常,因此,通过调用SVC异常,OS就进入了内核态(handler模式),在此就可以进行任务切换了。这种方式发起任务调度就不必等到systick定时器中断产生再发生任务调度了。 在任务中调用SvcTaskSwitch()就可以进行一次任务切换,这是自己定义的函数。SVC具体细节可以在网上查看相关资料。2. 增加优先级功能 优先级功能参考了FreeRTOS的设计,通过列表和列表项的方式实现。 简单来讲,为了实现这个功能,我们设置了不同的列表,如果我们设置优先级共有8个,则新建8个优先级列表priorityReadyList[8]存储处于就绪态的任务,新建一个delayedList,存储处于延时的任务,新建一个pendList,存储处于挂起态的任务。所有的任务必然存在于这三种列表中。 列表又由列表项组成,列表中的列表项以双向链表的形式组合在一起,每一个列表项又存储了一个任务的TCB,这样就可以找到相应的任务。在任务切换时,首先找到一个目前优先级最高的任务,OSFindMaxPriorityTask()。如果找到的这个任务跟当前任务的优先级相同,那么就指向当前任务在列表中的下一个任务,来做切换,如果找到的任务优先级更高,那么直接切换高优先级的任务3. 滴答定时器 滴答定时器的中断时间时1ms,也是时间片的时间。同优先级的任务每个运行1ms再切换。 systemTicks是任务运行的时间,系统初始化时赋值为0。在此我们不考虑溢出的问题,因为systemTicks是一个uint32_t的值,在此最大值代表约50天,因此在这个简易系统中不考虑溢出的情况。 其中需要注意的一点是判断任务的延时是否到达。其实很简单,如果有一个任务的延时时间到了,在延时列表中删除这个任务,在就绪列表中增加这个任务。我们怎么在延时列表中找到这个任务呢?因为列表中的列表项是按照readyTime升序排列的,因此通过我们前面在列表中特意设的最后列表的最后一项可以轻易的根据previous找到列表中的第一项。更新完任务后不要忘了更新下一项延时任务将要到达的时间。 在初始话列表的过程中我们给列表最后一项赋予了一个很大的值0x3ffffffff,因此可以任务永远不会到达这个时间。在列表中添加的项都会在它的前面。4. 增加延时函数。 在第一章,我们时通过无意义的while(i--)来达到延时的目的,但这是阻塞运算,程序会卡在这个地方,满足不了实际的需要。OS中的延时函数会发生任务的调度,这样才不会浪费资源。 OSDelay的主要功能就是把当前任务挂起,在就绪列表中删除当前的任务,把任务加入到延时的列表中,更新其将要延时的时间,然后寻找下一个优先级最高的任务,进行切换。最后设计了几个小实验,来验证程序是否正确运行。 设计了几个实验 1.两个小灯优先级相同,验证同优先级下的时间片调度。ok void Task1() int j = 0; while(1) j=20000000; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); while(j!=0) j--; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); j=20000000; while(j!=0) j--; } } void Task2() int i = 0; while(1) i=10000000; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); while(i!=0) i--; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); i=10000000; while(i!=0) i--; } } 2.两个任务优先级相同,验证延时功能是否有效 ok void Task1() while(1) OSDelay(2000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); OSDelay(2000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); } } void Task2() while(1) OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } } 3.验证优先级不同,任务一优先级高,任务二优先级低,任务一一直运行,小灯暗灭切换,可以看到任务二不运行,小灯一直亮 void Task1() int i = 0; while(1) i = 20000000; while(i!=0) i--; //OSDelay(2000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); i = 20000000; while(i!=0) i--; //OSDelay(2000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); } } void Task2() while(1) OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } } 4.任务一优先级高,任务二优先级低,任务一程序中有挂起3秒。可以看到在挂起的这段时间内任务二会切换,一但不挂起,任务二灯不会切换 void Task1() int i = 0; while(1) i = 100000000; while(i!=0) i--; //OSDelay(2000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); i = 100000000; while(i!=0) i--; OSDelay(5000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); } } void Task2() while(1) OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); OSDelay(1000); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } } 程序链接如下,实验用的是STM32F407的开发板 链接:https://pan.baidu.com/s/1my2HPG6shXB7QiwbR47Dnw 提取码:j5hw stm32超轻量操作系统之任务调度 stm32超轻量操作系统之信号量与互斥量
7,arm中delay延时函数具体时间怎么计算
ARM结构理具体计算指令执行时间一般情况下没有意义,除非你关闭预取指缓冲这样指令执行时间可以预测,应该根据flash频率计算,具体怎么计算我不知道,但是如果要得到精确延时在arm结构里是不能用单纯赋变量延时的,利用定时器比较靠谱要看他的晶振和ppl设定是多少,一句话,就是运行频率是多少此外要看其汇编指令的循环的指令数是几条看他的汇编才能算出 假如运行频率为60mhz,时间为0.005秒
8,请问单片机中的delay的单位时间是什么
这个具体要看使用的晶振的频率以及delay内部的代码,可以大致算下来。这个delay()不是KEIL提供的,而是用户自己编制的,一般都是编成delay(1)延时1ms,你说的us是在晶振12M时一个指令周期(机器周期)的时间。你好!单位时间取决于用户对delay()函数的设计。通常在写程序的时候便于阅读,我们会写delay_ms()表示单位时间是ms的延时,delay_10ms()表示单位时间是10ms的延时...打字不易,采纳哦!你可以认为最小的单位是us,根据你的延时函数的写法可组合成ms,s
文章TAG:
haldelay是多少时间多少 时间 汇编