SysCtlDelay()函数解析
来源:互联网 发布:康德 二律背反 知乎 编辑:程序博客网 时间:2024/06/03 13:43
最近经常用到SysCtlDelay()函数,觉得这函数不错,可以做到精确延时。不久前,做NRF905模块的时候,有一处要精确到610us。
#if defined(codered) || defined(gcc) || defined(sourcerygxx) //定义在codered、gcc、sourcerygcc编译环境下
void __attribute__((naked))
SysCtlDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne SysCtlDelay\n"
" bx lr");
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION) //在KEIL MDK的编译环境下
__asm void
SysCtlDelay(unsigned long ulCount)
{
subs r0, #1;
bne SysCtlDelay;
bx lr;
}
#endif SysCtlDelay(10 * (SysCtlClockGet( ) / 3000)); // 延时10ms // 定义系统时钟 8M
#define TheSysClock 8000000 复制代码
TI的资料中,此函数在Sysctl.c中是这样定义的:
#if defined(ewarm) || defined(DOXYGEN) //定义在IAR的编译环境中
void
SysCtlDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne.n SysCtlDelay\n"
" bx lr");
}
#endif
void
SysCtlDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne.n SysCtlDelay\n"
" bx lr");
}
#endif
#if defined(codered) || defined(gcc) || defined(sourcerygxx) //定义在codered、gcc、sourcerygcc编译环境下
void __attribute__((naked))
SysCtlDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne SysCtlDelay\n"
" bx lr");
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION) //在KEIL MDK的编译环境下
__asm void
SysCtlDelay(unsigned long ulCount)
{
subs r0, #1;
bne SysCtlDelay;
bx lr;
}
#endif
不管哪种环境下,发现用了三条汇编指令。我用的是KEIL MDK。
subs r0,#1; // 使用了16位的Thumb指令,无条件更新标志位。S后缀的使用要担心,16位的Thunb指令有可能会无条件更新标志位,也有可能不会。所以,但你需要更新标志位时,一定不要忘了加上S后缀。
bne SysCtlDelay; // 无条件跳转指令有两条,B和BX, BNE中的NE即NotEqual,对应于标志位Z==0;
表示不等的时候无条件转移到SysCtlDelay处对应的地址;
bx lr; //执行这条指令后,把返回地址存储到LR(R14)中;
关于SysCtlDelay()延时函数:
TI LM3S8962 默认的设置为采用主晶振6M, 所以,一个周期的时间是1/6us。
SysCtlDelay()函数里执行了三条指令。
1.微妙级的延时:
SysCtlDelay(2); // 延时1us;
SysCtlDelay(2*x); 延时x us;x=1000时,延时1ms;
另一种写法
#defined TheSysClock 6000000
SysCtlDelay(1*(TheSysClock/3000000)) //延时 1us
2.毫秒级的延时:
2.毫秒级的延时:
SysCtlDelay(SysCtlClockGet( ) / 3000); // 延时1ms
SysCtlClockGet( )=6000000 ;
另一种种写法
// 定义系统时钟 6M
#define TheSysClock 6000000
#define TheSysClock 6000000
SysCtlDelay(10 * (TheSysClock / 3000)); 延时10ms
#define TheSysClock 8000000
SysCtlDelay(10 * (TheSysClock / 3000)); 延时10ms
- /********************************************************************
- 程序名称:系统频率设置&精确延时
- 硬件环境:EKK-LM3S9B92-CD-572
- 软件环境:keil 4.12
- 创建日期:2010.11.7
- 修改日期:2010.11.8
- 作 者:牙小狼 QQ:398968891 Email:xiaolang.ya@gmail.com
- 版 本:R1.2
- 程序说明:
- 1、根据LED闪烁情况可以看出频率设置的效果。
- 2、延时函数在低频情况下可能有一定的误差,因为库函数的调用,以及延时的
- 计算会消耗一定的时间。
- 更新说明:
- 1、发现无法使用MAP_SysCtlDelay(),必须改为SysCtlDelay(),否则会跑死
- 原因暂时不明。
- ********************************************************************/
- //----------------------HEADER FILE 头文件-------------------------//
- #define TARGET_IS_TEMPEST_RC1
- #include "../inc/hw_memmap.h" //提供内存地址映射的支持
- #include "../inc/hw_types.h" //提供数据类型的支持
- #include "../driverlib/gpio.h" //提供GPIO的API支持
- #include "../driverlib/sysctl.h" //提供系统控制的API支持
- #include "../driverlib/rom.h" //提供ROM内API的支持
- #include "../driverlib/rom_map.h" //提供MAP_这种定义的支持
- //--------------------MAVRO DEFINITION 宏定义----------------------//
- #define DELAY_US(n) SysCtlDelay(n * (MAP_SysCtlClockGet() / 3000000))
- #define DELAY_MS(n) SysCtlDelay(n * (MAP_SysCtlClockGet() / 3000))
- #define DELAY_S(n) SysCtlDelay(n * (MAP_SysCtlClockGet() / 3))
- //-----------------FUNCTION PROTOTYPES 函数声明--------------------//
- void LED_blinking(unsigned long ultimes,unsigned long ulloop);
- /********************************************************************
- 函数名称:LED_blinking()
- 函数入口:ultimes:闪烁次数 ulloop:间隔的时钟周期
- 函数出口:无
- 函数说明:LED闪烁函数,实际效果和系统频率有关
- ********************************************************************/
- void LED_blinking(unsigned long ultimes,unsigned long ulloop)
- {
- unsigned long i,j;
- for(i=0x0000;i<ultimes;i++)
- {
- for(j=0x0000;j<ulloop;j++);
- MAP_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1);
- for(j=0x0000;j<ulloop;j++);
- MAP_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0);
- }
- }
- /********************************************************************
- 函数名称:main()
- 函数入口:务
- 函数出口:无
- 函数说明:系统主函数
- ********************************************************************/
- int main(void)
- {
- MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
- //使能PD端口
- MAP_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
- //PD0设置为输出
- MAP_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | \
- SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
- //外部频率16MHZ,PLL倍频至80HMZ
- LED_blinking(10,500000);
- MAP_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | \
- SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
- //外部频率16MHZ,不分频
- LED_blinking(10,500000);
- MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_OSC | \
- SYSCTL_OSC_INT);
- //内部晶振4分频,即4MHZ
- LED_blinking(10,500000);
- while (1)
- {
- MAP_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 1);
- DELAY_MS(500);
- MAP_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0);
- DELAY_MS(500);
- //LED按照指定的时间间隔进行闪烁
- }
- }
- SysCtlDelay()函数解析
- 函数调用约定解析
- 函数解析字符串(ZT)
- setsockopt函数解析(转)
- ARX函数解析
- 成员函数重载解析
- js 函数深入解析
- Linux wait函数解析
- 函数调用约定解析
- 钩子函数解析
- 虚函数解析
- 函数表达式解析器
- PartitionMotionSearch()函数解析
- fcntl函数解析
- main函数参数解析
- json解析函数。
- 虚函数详细解析
- 虚析构函数解析
- 点击返回键关闭应用程序的步骤
- Windows Store apps开发[6]访问Assets文件夹
- 用CVS控制文件中的小数有效数字
- CSS FTP上传网页图解教程
- 一个比较好用的java反编译工具
- SysCtlDelay()函数解析
- 在iOS用的.unity3d文件
- Linux NFS配置
- android-listview拖动时背景变黑的问题 分类: android开发
- 介绍Unicode的编码方式和实现方式
- 8.10总结『by AndyJ』
- 深复制与浅复制(深拷贝与浅拷贝)
- IETester必备浏览器测试工具
- 文件与目录管理