AVR 中 delay 函数的调用注意事项!delay_ns delay_ms

AVR 中 delay 函数的调用注意事项!delay_ns delay_ms
AVR 中 delay 函数的调用注意事项!delay_ns delay_ms

早就知道AVR的编译器有自带的延时子函数(或者说是头文件),但一直没时间一探究竟,今天终于揭开了其内幕。

AVR编译器众多,可谓是百家齐鸣,本人独尊WinAVR.

说明:编译器版本WinAVR-20080610

先说winAVR的_Delay.h_肯定是在Include文件夹下了,进去一看果然有,可打开一看,其曰:“This file has been moved to

."

在util文件夹中找到delay头文件如下:

--------------------------------------------------------------------------------------------------------------------------------------------

void

_delay_us(double __us)

{

uint8_t __ticks;

double __tmp = ((F_CPU) / 3e6) * __us; //3e6=3000000

if (__tmp< 1.0)

__ticks = 1;

else if (__tmp> 255)

{

_delay_ms(__us / 1000.0);

return;

}

else

__ticks = (uint8_t)__tmp;

_delay_loop_1(__ticks);

}

-----------------------------------------------------------------------------------------------------------------------------------------------

_delay_ms(double __ms)

{

uint16_t __ticks;

double __tmp = ((F_CPU) / 4e3) * __ms;

if (__tmp< 1.0)

__ticks = 1;

else if (__tmp> 65535)

{

// __ticks = requested delay in 1/10 ms

__ticks = (uint16_t) (__ms * 10.0);

while(__ticks)

{

// wait 1/10 ms

_delay_loop_2(((F_CPU) / 4e3) / 10);

__ticks --;

}

return;

}

else

__ticks = (uint16_t)__tmp;

_delay_loop_2(__ticks);

}

1、分析程序发现上面两个子函数,分别using _delay_loop_1() and using_delay_loop2()

2、还有一点,用此头文件时,必须设置主频和优化项,否则会出现如下提示:

#ifndef F_CPU

/* prevent compiler error by supplying a default */

# warning "F_CPU not defined for "

# define F_CPU 1000000UL

#endif

#ifndef__OPTIMIZE__

# warning "Compiler optimizations disabled; functions from won't work as designed"

#endif

3、通过查找发现_Delay_loop1()和_Delay_loop2()在文件delay_basic.h中,如下:

/** \ingrouputil_delay_basic

Delay loop using an 8-bit counter \c __count, so up to 256 iterations are possible. (The value 256 would have to be passedas 0.) The loop executes three CPU cycles per iteration, not including the overhead the compiler needs to setup the counter register.

Thus, at a CPU speed of 1 MHz, delays of up to 768 microseconds can be achieved.

*/

上面翻译如下:

循环变量为8位,所以可达256(其值256和0等同),每次循环好执行3个CPU时钟,不包括程序调用和退出该函数所花费的时间。

如此,当CPU为1MHZ时,最大延时为768us。(3us*256)void _delay_loop_1(uint8_t __count)

{

__asm__ volatile (

"1: dec %0" "\n\t"

"brne 1b" a a

: "=r" (__count)

: "0" (__count)

);

}

/** \ingrouputil_delay_basic

Delay loop using a 16-bit counter \c __count, so up to 65536 iterations are possible. (The value 65536 would have to be passed as 0.) The loop executes four CPU cycles per iteration, not including the overhead the compiler requires to setup the counter register pair.

Thus, at a CPU speed of 1 MHz, delays of up to about 262.1 milliseconds can be achieved.

*/

上面翻译如下:

循环变量为16位,所以可达65536(其值65536和0等同),每次循环好执行4个CPU时钟,不包括程序调用和退出该函数所花费的时间。

如此,当CPU为1MHZ时,最大延时大约为262.1us。

(4us*65536)

void_delay_loop_2(uint16_t __count)

{

__asm__ volatile (

"1: sbiw %0,1" "\n\t"

"brne 1b"

: "=w" (__count)

: "0" (__count)

);

}

4、有了上面的基础就不难得出

#include // 头文件

// _delay_loop_1(XX); // 8-bit count,3 cycles/loop // _delay_loop_2(XXXX); // 16-bit count,4 cycles/loop #include // 头文件

_delay_loop_2(uint16_t __count)

1MHz时:MAX_DELAY_TIME = (1/1000000)*3*256 =

0.000768 S = 768 uS

8MHz时:MAX_DELAY_TIME = (1/8000000)*3*256 =

0.000096 S = 96 uS

............

F_CPU MAX_DELAY_TIME = (1/F_CPU)*3*256

依此类推。

_delay_loop_2(uint16_t __count)

1MHz时:MAX_DELAY_TIME = (1/1000000)*4*65535 = 0.26214 S = 262.1 mS

8MHz时:MAX_DELAY_TIME = (1/8000000)*4*65535 = 0.03277 S = 32.8 mS

............

F_CPU MAX_DELAY_TIME = (1/F_CPU)*4*65535

依此类推。

重要提示:_delay_loop_1(0)、_delay_loop_1(256)延时是一样的!!

同理,_delay_loop_2(0)、_delay_loop_2(65536)延时也是一样的!!这些函数的延时都是最长的延时。

重量级函数出场>>>>>>>>>>>>>_delay_us()

and _delay_ms() !!!<<<<<<<<<<<<<<<<< 先说_delay_us(double __us),不要以为该函数的形参是double 形就为所欲为,随便付值都不会溢出了,其实这个函数的调用是有限制的,不然就会出现延时不对的情况。函数的注释里说明如下:

The maximal possible delay is 768 us / F_CPU in MHz.

在1MHz时最大延时768us!!!!

也就是说double __us这个值在1M系统时钟时最大只能是768。如果大于768,比如这样调用延时函数_delay_us(780)会怎么样呢??那就会和调用_delay_loop_1(0)一样的效果了!能延迟多少各位可以算出来。具体在各种系统时钟之下这个值是多少可以通过一个公式算出来:

MAX_VALUE = 256*3000000/F_CPU

同理,分析程序,可以知道_delay_ms(double __ms)函数,在1MHz系统时钟下其最大延时是262.14 ms!在这里也给出该函数的形参的最大值,调用此函数时的实参都不要大于这个值,大于这个限制值的话就和调用_delay_loop_2(0)同样的延时效果!

MAX_VALUE = 65536*4000/F_CPU (1MHZ时,能输入的最大值为262)

从上面可以看出来,当用延时函数时,若不加注意会出错的(毕竟人们很难经常记住这两个最大值),那还有什么补偿的办法呢?

#include

// _delay_loop_2(XXXX); // 16-bit count,4 cycles/loop // _delay_loop_1(XX); // 8-bit count,3 cycles/loop

/*------------------------------------*/

void delay_1ms(void) //1ms延时函数主频为8MHz

{

_delay_loop_2(2000); // 16-bit count,4 cycles/loop

} // 2000*4/FREQ

//使用不同的晶振,可以自己来计算出()里的值

/*-------------------------------------*/

void delay_nms(unsigned int n) //N ms延时函数

{

unsigned int i=0;

for (i=0;i

delay_1ms();

}

/*-------------------------------------*/

来自:

https://www.360docs.net/doc/d39750965.html,/goby2004/blog/item/ab080c9407f34440 d1135e9d.html

KeilC51程序设计中几种精确延时方法

Keil C51程序设计中几种精确延时方法 2008-04-03 08:48 实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。 1 使用定时器/计数器实现精确延时 单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。 在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。 2 软件延时与时间计算 在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。 2.1 短暂延时 可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs 的延时函数可编写如下: void Delay10us( ) { _NOP_( ); _NOP_( ); _NOP_( ) _NOP_( );

对样条函数及其插值问题的一点认识

对样条函数及其插值问题的一点认识 样条函数是计算数学以及计算机辅助设计几何设计的重要工具。1946年,I. J. Schoenberg 著名的关于一元样条函数的奠定性论文“Contribution to the problem of application of equidistant data by analytic functions ”发表,建立了一元样条函数的理论基础。自此以后,关于样条函数的研究工作逐渐深入。随着电子计算机技术的不断进步,样条函数的理论以及应用研究得到迅速的发展和广泛的应用。经过数学工作者的努力,已经形成了较为系统的理论体系。 所谓(多项式)样条函数,乃指具有一定光滑性的分段(分片)多项式。一元n 次且n -1阶连续可微的样条函数具有如下的表示式: 1()()()()N n n j j j s x p x c x x x +==+--∞<<+∞∑[] 011,00,01,,...,,(1),...,(),,...,,n n n n N n N N u un u u u u x x x x x S x x x x ++++ +≥??=??

单片机一些常用的延时与中断问题及解决方法

单片机一些常用的延时与中断问题及解决方法 延时与中断出错,是单片机新手在单片机开发应用过程中,经常会遇到的问题,本文汇总整理了包含了MCS-51系列单片机、MSP430单片机、C51单片机、8051F的单片机、avr单片机、STC89C52、PIC单片机…..在内的各种单片机常见的延时与中断问题及解决方法,希望对单片机新手们,有所帮助! 一、单片机延时问题20问 1、单片机延时程序的延时时间怎么算的? 答:如果用循环语句实现的循环,没法计算,但是可以通过软件仿真看到具体时间,但是一般精精确延时是没法用循环语句实现的。 如果想精确延时,一般需要用到定时器,延时时间与晶振有关系,单片机系统一般常选用 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。 2、求个单片机89S51 12M晶振用定时器延时10分钟,控制1个灯就可以 答:可以设50ms中断一次,定时初值,TH0=0x3c、TL0=0xb0。中断20次为1S,10分钟的话,需中断12000次。计12000次后,给一IO口一个低电平(如功率不够,可再加扩展),就可控制灯了。 而且还要看你用什么语言计算了,汇编延时准确,知道单片机工作周期和循环次数即可算出,但不具有可移植性,在不同种类单片机中,汇编不通用。用c的话,由于各种软件执行效率不一样,不会太准,通常用定时器做延时或做一个不准确的延时,延时短的话,在c中使用汇编的nop做延时 3、51单片机C语言for循环延时程序时间计算,设晶振12MHz,即一个机器周期是1us。for(i=0,i<100;i++) for(j=0,j<100;j++) 我觉得时间是100*100*1us=10ms,怎么会是100ms 答: 不可能的,是不是你的编译有错的啊

TMS320F2812delay 延时完整程序

TMS320F2812的延时程序(完整) .def _DSP28x_usDelay ;==================================================== ;Delay Function ;The C assembly call will look as follows: ; ; extern void Delay(long time); ; MOV AL,#LowLoopCount ; MOV AH,#HighLoopCount ; LCR _Delay ; ;Or as follows (if count is less then 16-bits): ; ; MOV ACC,#LoopCount ; LCR _Delay .global __DSP28x_usDelay _DSP28x_usDelay: SUB ACC,#1 NOP NOP BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0 LRETR ;There is a 9/10 cycle overhead and each loop ;takes five cycles. The LoopCount is given by ;the following formula: ; DELAY_CPU_CYLES = 9 + 5*LoopCount ; LoopCount = (DELAY_CPU_CYCLES - 9) / 5 ;================================================== --

RE:我是这么调用的(C语言) extern void DSP28x_usDelay(long time); 在需要延时的地方加入 DSP28x_usDelay(0x100000);//根据延迟时间写入参数

STM32延时函数

#include #include "delay.h" ////////////////////////////////////////////////////////////////////////////////// //使用SysTick的普通计数模式对延迟进行管理 //包括delay_us,delay_ms //***************************************************************************** *** //V1.2修改说明 //修正了中断中调用出现死循环的错误 //防止延时不准确,采用do while结构! ////////////////////////////////////////////////////////////////////////////////// static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数 //初始化延迟函数 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void delay_init(u8 SYSCLK) { SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟HCLK/8 fac_us=SYSCLK/8; fac_ms=(u16)fac_us*1000; } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL=0x01 ; //开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nus //nus为要延时的us数.

单片机C延时时间怎样计算

C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时 应该使用unsigned char作为延时变量。以某晶振为12MHz的单片 机为例,晶振为12M H z即一个机器周期为1u s。一. 500ms延时子程序 程序: void delay500ms(void) { unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0;j--) for(k=81;k>0;k--); } 计算分析: 程序共有三层循环 一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值 1us = 3us 三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值 1us = 3us

循环外: 5us 子程序调用 2us + 子程序返回2us + R7赋值 1us = 5us 延时总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms 计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5 二. 200ms延时子程序 程序: void delay200ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); } 三. 10ms延时子程序 程序: void delay10ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--);

delay延时教程

delay延时教程(用的是12MHz晶振的MCS-51) 一、 1)NOP指令为单周期指令 2)DJNZ指令为双周期指令 3)mov指令为单周期指令 4)子程序调用(即LCALL指令)为双周期指令 5)ret为双周期指令 states是指令周期数, sec是时间,=指令周期×states,设置好晶振频率就是准确的了 调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能 二、编程最好: 1.尽量使用unsigned型的数据结构。 2.尽量使用char型,实在不够用再用int,然后才是long。 3.如果有可能,不要用浮点型。 4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。 5.在do…while,while语句中,循环体内变量也采用减减方法。 三、编辑注意: 1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。 2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。 3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。 四、a:delaytime为us级 直接调用库函数: #include// 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。 eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C 文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下: void Delay10us( ) { _NOP_( ); _NOP_( );

matlab中常用的函数

A abs 绝对值、模、字符的ASCII码值 acos 反余弦 acosh 反双曲余弦 acot 反余切 acoth 反双曲余切 acsc 反余割 acsch 反双曲余割 align 启动图形对象几何位置排列工具 all 所有元素非零为真 angle 相角 ans 表达式计算结果的缺省变量名any 所有元素非全零为真area 面域图 argnames 函数M文件宗量名asec 反正割 asech 反双曲正割 asin 反正弦 asinh 反双曲正弦 assignin 向变量赋值 atan 反正切 atan2 四象限反正切 atanh 反双曲正切 autumn 红黄调秋色图阵axes 创建轴对象的低层指令axis 控制轴刻度和风格的高层指令 B bar 二维直方图 bar3 三维直方图 bar3h 三维水平直方图barh 二维水平直方图 base2dec X进制转换为十进制bin2dec 二进制转换为十进制blanks 创建空格串 bone 蓝色调黑白色图阵box 框状坐标轴 break while 或for 环中断指令brighten 亮度控制 C capture ;3版以前?捕获当前图形cart2pol 直角坐标变为极或柱坐标cart2sph 直角坐标变为球坐标cat 串接成高维数组 caxis 色标尺刻度 cd 指定当前目录 cdedit 启动用户菜单、控件回调函数设计工具 cdf2rdf 复数特征值对角阵转为实数块对角阵 ceil 向正无穷取整 cell 创建元胞数组 cell2struct 元胞数组转换为构架数组celldisp 显示元胞数组内容cellplot 元胞数组内部结构图示char 把数值、符号、内联类转换为字符对象 chi2cdf 分布累计概率函数 chi2inv 分布逆累计概率函数chi2pdf 分布概率密度函数 chi2rnd 分布随机数发生器 chol Cholesky分解

单片机几个典型延时函数

软件延时:(asm) 晶振12MHZ,延时1秒 程序如下: DELAY:MOV 72H,#100 LOOP3:MOV 71H,#100 LOOP1:MOV 70H,#47 LOOP0:DJNZ 70H,LOOP0 NOP DJNZ 71H,LOOP1 MOV 70H,#46 LOOP2:DJNZ 70H,LOOP2 NOP DJNZ 72H,LOOP3 MOV 70H,#48 LOOP4:DJNZ 70H,LOOP4 定时器延时: 晶振12MHZ,延时1s,定时器0工作方式为方式1 DELAY1:MOV R7,#0AH ;;晶振12MHZ,延时0.5秒 AJMP DELAY DELAY2:MOV R7,#14H ;;晶振12MHZ,延时1秒DELAY:CLR EX0 MOV TMOD,#01H ;设置定时器的工作方式为方式1 MOV TL0,#0B0H ;给定时器设置计数初始值 MOV TH0,#3CH SETB TR0 ;开启定时器 HERE:JBC TF0,NEXT1 SJMP HERE NEXT1:MOV TL0,#0B0H MOV TH0,#3CH DJNZ R7,HERE CLR TR0 ;定时器要软件清零 SETB EX0 RET

C语言延时程序: 10ms延时子程序(12MHZ)void delay10ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } 1s延时子程序(12MHZ)void delay1s(void) { unsigned char h,i,j,k; for(h=5;h>0;h--) for(i=4;i>0;i--) for(j=116;j>0;j--) for(k=214;k>0;k--); }

二元函数插值的一般方法研究

《二元函数多项式插值的一般方法研究》的开题报告 一.课题研究的背景和意义 (一).插值问题的提出和发展过程 许多实际问题都用函数)(x f y =来表示某种内在规律的数量关系,其中相当一部分函数通过实验或观测得到的.虽然)(x f 在某个区间[]b a ,上是存在的,有的还是连续的,但却只能给出[]b a ,上一系列点i x 的函数值),...,1,0)((n i x f y i i ==,这只是一张函数表.有的函数虽有解析表达式,但由于计算复杂,使用不方便,通常也造一个函数表,如大家熟悉的三角函数表、对数表、平方根和立方根表等.为了研究函数的变化规律,往往需要求出不在表上的函数值.因此,我们希望根据给定的函数表做一个既能反应函数)(x f 的特性,又便于计算的简单函数)(x P ,用)(x P 近似)(x f .通常选一类较简单的函数(如代数多项式或分段代数多项式)作为)(x P ,并使)()(i i x f x P =对n i ,...,1,0=成立.这样确定的)(x P 就是我们希望得到的插值函数. 对于上述的)(x f y =的函数插值,前人们已经做过很多的研究,典型的有多项式插值、拉格朗日插值、牛顿插值、埃尔米特插值等.但是对于二元函数),(y x f z =的插值还没有一个较广的研究. (二).二元函数插值研究的意义 1. 理论意义: 一元函数插值主要有基函数法、拉格朗日插值法、牛顿插值法、埃尔米特插值等,但是对于二元函数插值乃至n 元插值是不能直接在一元函数插值的基础上直接推广的。多元插值是一个活跃的研究领域,至今已有非常多的多元插值公式,但是可供利用的公式十分少。 所以我们研究二元函数的插值时,可以为n 元函数插值提供新的研究思路,有助于复杂函数的偏导数的求解,也可以是对插值理论的完善。 2. 实际意义: 一元函数插值问题主要是平面的,而二元函数插值是在三维空间上的,这对我们构造三维空间图像有非常大的作用.例如,在现代机械工业中用计算机控制加工机械零件,根据设

单片机一些常用的延时与中断问题及解决方法

延时与中断出错,是单片机新手在单片机开发应用过程中,经常会遇到的问题,本文汇总整理了包含了MCS-51系列单片机、MSP430单片机、C51单片机、8051F的单片机、avr单片机、STC89C52、PIC单片机…..在内的各种单片机常见的延时与中断问题及解决方法,希望对单片机新手们,有所帮助! 一、单片机延时问题20问 1、单片机延时程序的延时时间怎么算的? 答:如果用循环语句实现的循环,没法计算,但是可以通过软件仿真看到具体时间,但是一般精精确延时是没法用循环语句实现的。 如果想精确延时,一般需要用到定时器,延时时间与晶振有关系,单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。 2、求个单片机89S51 12M晶振用定时器延时10分钟,控制1个灯就可以 答:可以设50ms中断一次,定时初值,TH0=0x3c、TL0=0xb0。中断20次为1S,10分钟的话,需中断12000次。计12000次后,给一IO口一个低电平(如功率不够,可再加扩展),就可控制灯了。 而且还要看你用什么语言计算了,汇编延时准确,知道单片机工作周期和循环次数即可算出,但不具有可移植性,在不同种类单片机中,汇编不通用。用c的话,由于各种软件执行效率不一样,不会太准,通常用定时器做延时或做一个不准确的延时,延时短的话,在c中使用汇编的nop做延时 3、51单片机C语言for循环延时程序时间计算,设晶振12MHz,即一个机器周期是1us。for(i=0,i<100;i++) for(j=0,j<100;j++) 我觉得时间是100*100*1us=10ms,怎么会是100ms 答: 不可能的,是不是你的编译有错的啊 我改的晶振12M,在KEIL 4.0 里面编译的,为你得出的结果最大也就是40ms,这是软件的原因, 不可能出现100ms那么大的差距,是你的软件的原因。 不信你实际编写一个秒钟,利用原理计算编写一个烧进单片机和利用软件测试的秒程序烧进单片机,你会发现原理计算的程序是正确的

STM32的几种延时方法

STM32的几种延时方法(基于MDK固件库3.0,晶振8M) 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms()。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。 //粗延时函数,微秒 void delay_us(u16 time) { u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; } } //毫秒级的延时 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; //自己定义 while(i--) ; } } 2.SysTick 定时器延时 CM3 内核的处理器,内部包含了一个SysTick定时器,SysTick是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。SysTick 在STM32 的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。 这里面也有两种方式实现: a.中断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。 volatile unsigned long time_delay; // 延时时间,注意定义为全局变量 //延时n_ms void delay_ms(volatile unsigned long nms) { //SYSTICK分频--1ms的系统时钟中断 if (SysTick_Config(SystemFrequency/1000))

多源信息融合数字模型

多源信息融合数字模型 研究员、博导 岳天祥 研究员、博导 刘纪远 (中国科学院地理学与资源研究所, 北京100101) 摘 要:研究结果表明,在目前基础条件下,多源信息融合数字模型的实现需要解决现行数字地面 模型和空间插值模型的误差问题、点—面信息有效融合问题、多尺度转换问题和多维GIS面临的理 论问题。建立多源信息融合数字模型的基本步骤可归纳为:(a)建立基于曲面论数字模型的基本方程,(b)运用遥感数据反演数字模型的首次近似表达形式,(c)如果有更新信息,重复以上过程,直至 理论模型与实际需求完全相符。 关键词:曲面论 遥感反演 多源信息融合 数字模型 A Digital Model for Multi-Sources Information Fusion Professor YUE Tianxiang Professor LIU Jiyuan (Institute of Geographical Sciences and Natural Resources Research,C AS,Beijing100101) A bstract:Our re search re sult shows that realization of the digital m odel for multi-sourc es information fusion needs to solve problems of e rrors of existing digital te rrain model and spatial inte rpolation model,virtual fusion of point and surface information,information transformation at various scales,and multi-dimension G I S.The basic ste ps of constructing the digital model include,(a)establishing basic equations of the digital model by means of surface the ory,(b)retrie ving first approximate formulation using remote sensing data,(c)if the re are more available information,the ste p above is repeated until requirement is re ache d. Key words:surface the ory,remote se nsing retrie val,information fusion,digital model 1 引言 七十年代初,美国研究机构发现,利用计算机技术对多个独立的连续声纳信号进行融合后,可以自动检测出敌方潜艇的位置[1]。这一发现使信息融合作为一门独立的技术首先在军事应用中得到青睐,美国相继研究开发了几十个军事融合系统。进入八十年代,研制出了应用于大型战略系统、海洋监视系统和小型战术系统的第一代信息融合系统,它们包括军用分析系统(TCAC)、多平台多传感器跟踪信息相关处理系统(INCA)、全员分析系统(PAAS)、海军战争状态分析显示系统(TOP)、辅助空中作战命令分析专家系统(DAGR)、空中目标确定和截击武器选择专家系统(TATR)、自动多传感器部队识别系统(AMSUI)和目标获取与武器输送系统(TR-WDS)。九十年代研制的主要数据融合系统包括全源信息分 中国科学院知识创新工程项目(No.kzc x2-308-02)

用单片机实现延时(自己经验及网上搜集).

标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。这在汇编语言中很容易实现,写几个nop就行了。 在keil C51中,直接调用库函数: #include // 声明了void _nop_(void; _nop_(; // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 在选择C51中循环语句时,要注意以下几个问题 第一、定义的C51中循环变量,尽量采用无符号字符型变量。 第二、在FOR循环语句中,尽量采用变量减减来做循环。 第三、在do…while,while语句中,循环体内变量也采用减减方法。 这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。 下面举例说明: unsigned char i; for(i=0;i<255;i++; unsigned char i; for(i=255;i>0;i--;

其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: MOV 09H,#0FFH LOOP: DJNZ 09H,LOOP 指令相当简洁,也很好计算精确的延时时间。 同样对do…while,while循环语句中,也是如此 例: unsigned char n; n=255; do{n--} while(n; 或 n=255; while(n {n--}; 这两个循环语句经过C51编译之后,形成DJNZ来完成的方法, 故其精确时间的计算也很方便。 其三:对于要求精确延时时间更长,这时就要采用循环嵌套的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。对于循环语句同样可以采用for,do…while,while结构来完成,每个循环体内的变量仍然采用无符号字符变量。 unsigned char i,j for(i=255;i>0;i--

AVR单片机常用的延时函数

AVR单片机常用的延时函数 /******************************************************************** *******/ //C header files:Delay function for AVR //MCU:ATmega8 or 16 or 32 //Version: 1.0beta //The author: /******************************************************************** *******/ #include void delay8RC_us(unsigned int time) //8Mhz内部RC震荡延时Xus { do { time--; } while(time>1); } void delay8RC_ms(unsigned int time) //8Mhz内部RC震荡延时Xms { while(time!=0) { delay8RC_us(1000); time--; } } /******************************************************************** **********/ void delay1M_1ms(void) //1Mhz延时1ms { unsigned char a,b,c; for(c=1;c>0;c--) for(b=142;b>0;b--) for(a=2;a>0;a--); } void delay1M_xms(unsigned int x) //1Mhz延时xms { unsigned int i; for(i=0;i

STM32的几种延时方法

STM32的几种延时方法(基于MDK固件库,晶振8M)单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。 断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。 volatile unsigned long time_delay; 中断方式 主要仿照原子的《STM32不完全手册》。SYSTICK 的时钟固定为HCLK 时钟的1/8,在这里我们选用内部时钟源72M,所以SYSTICK的时钟为9M,即SYSTICK 定时器以9M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器, 程序如下,相当于查询法。 //仿原子延时,不进入systic中断

void delay_us(u32 nus) { u32 temp; SysTick->LOAD = 9*nus; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } 三种方式各有利弊,第一种方式容易理解,但不太精准。第二种方式采用库函数,编写简单,由于中断的存在,不利于在其他中断中调用此延时函数。第三种方式直接操作寄存器,看起来比较繁琐,其实也不难,同时克服了以上两种方式的缺点,个人感觉比较好用。

单片机精确毫秒延时函数

单片机精确毫秒延时函数 实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。今天主要介绍软件延时以及单片机精确毫秒延时函数。 单片机的周期介绍在电子技术中,脉冲信号是一个按一定电压幅度,一定时间间隔连续发出的脉冲信号。脉冲信号之间的时间间隔称为周期;而将在单位时间(如1秒)内所产生的脉冲个数称为频率。频率是描述周期性循环信号(包括脉冲信号)在单位时间内所出现的脉冲数量多少的计量名称;频率的标准计量单位是Hz(赫)。电脑中的系统时钟就是一个典型的频率相当精确和稳定的脉冲信号发生器。 指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。 时钟周期:也称为振荡周期,一个时钟周期= 晶振的倒数。对于单片机时钟周期,时钟周期是单片机的基本时间单位,两个振荡周期(时钟周期)组成一个状态周期。 机器周期:单片机的基本操作周期,在一个操作周期内,单片机完成一项基本操作,如取指令、存储器读/写等。 机器周期=6个状态周期=12个时钟周期。 51单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/ 晶振频率)= x s。常用单片机的晶振为11.0592MHz,12MHz,24MHz。其中11.0592MHz 的晶振更容易产生各种标准的波特率,后两种的一个机器周期分别为1 s和2 s,便于精确延时。 单片机精确毫秒延时函数对于需要精确延时的应用场合,需要精确知道延时函数的具体延

CVAVR 软件中启动delay库,调用delay_ms()函数,自动带了喂狗程序

CV A VR 软件中启动delay.h库,调用delay_ms()函数,自动带了喂狗程序 近期在学习中发现个问题,CV A VR 中启动delay.h库,调用delay_ms()函数延时,系统怎么都不复位重启,即使打开看门狗熔丝位,看门狗也不会重启,找了很久原因,发现是调用调用系统自身带的delay_ms()函数引起的,换成自己的简单延时函数,问题就解决,看门狗可以正常工作,后面附带我自己写的简单延时函数。 后来查找问题,发现系统中的delay_ms()函数自带了喂狗程序,所以不会自动的重启,请大家放心使用,用延时函数看门狗不溢出是正常的。后面附带软件编辑后生产的汇编程序,一看就知道确实带了喂狗。 今天写出来供大家注意,不要犯我同样的问题。 /***************************************************** This program was produced by the CodeWizardA VR V1.25.9 Standard Chip type : A Tmega8L Program type : Application Clock frequency : 1.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include #include // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T

中图像函数大全2019年(版)

Matlab中图像函数大全 abs 绝对值、模、字符的ASCII码值acos 反余弦 acosh 反双曲余弦 acot 反余切 acoth 反双曲余切 acsc 反余割 acsch 反双曲余割 align 启动图形对象几何位置排列工具all 所有元素非零为真 angle 相角 ans 表达式计算结果的缺省变量名any 所有元素非全零为真 area 面域图 argnames 函数M文件宗量名 asec 反正割 asech 反双曲正割 asin 反正弦 asinh 反双曲正弦 assignin 向变量赋值 atan 反正切 atan2 四象限反正切 atanh 反双曲正切 autumn 红黄调秋色图阵 axes 创建轴对象的低层指令 axis 控制轴刻度和风格的高层指令 B b bar 二维直方图 bar3 三维直方图 bar3h 三维水平直方图 barh 二维水平直方图 base2dec X进制转换为十进制 bin2dec 二进制转换为十进制 blanks 创建空格串 bone 蓝色调黑白色图阵 box 框状坐标轴 break while 或for 环中断指令brighten 亮度控制

capture (3版以前)捕获当前图形 cart2pol 直角坐标变为极或柱坐标 cart2sph 直角坐标变为球坐标 cat 串接成高维数组 caxis 色标尺刻度 cd 指定当前目录 cdedit 启动用户菜单、控件回调函数设计工具cdf2rdf 复数特征值对角阵转为实数块对角阵ceil 向正无穷取整 cell 创建元胞数组 cell2struct 元胞数组转换为构架数组 celldisp 显示元胞数组内容 cellplot 元胞数组内部结构图示 char 把数值、符号、内联类转换为字符对象chi2cdf 分布累计概率函数 chi2inv 分布逆累计概率函数 chi2pdf 分布概率密度函数 chi2rnd 分布随机数发生器 chol Cholesky分解 clabel 等位线标识 cla 清除当前轴 class 获知对象类别或创建对象 clc 清除指令窗 clear 清除内存变量和函数 clf 清除图对象 clock 时钟 colorcube 三浓淡多彩交叉色图矩阵 colordef 设置色彩缺省值 colormap 色图 colspace 列空间的基 close 关闭指定窗口 colperm 列排序置换向量 comet 彗星状轨迹图 comet3 三维彗星轨迹图 compass 射线图 compose 求复合函数 cond (逆)条件数 condeig 计算特征值、特征向量同时给出条件数condest 范-1条件数估计 conj 复数共轭 contour 等位线 contourf 填色等位线

相关文档
最新文档