本帖最后由 Swallow_0322 于 2011-4-15 14:22 编辑
前天晚上有人在大群中讨论关于DrvSYS_Delay()的问题,我未加仔细研究便给出答复,最大时钟频率50MHz加上是24位的滴答定时器,所以其入口参数的最大值为335000,今天抽空调试了一下与我的作答有些出入,对于我未经确认没有十足把握就去误导网友深表歉意!下面是我对这个函数的理解,本人菜鸟,理解浅薄,如果错误望不吝指教,俺勇于接受大家抛过来的砖头,能把我从迷糊中砸醒也是好事,(*^__^*) 嘻嘻……
关于对函数DrvSYS_Delay()的理解:
① 本函数是使用系统定时器 (SysTick) ,也就是常说的滴答时钟或者系统脉搏时钟,SysTick 提供一种简单,24位计数器,可灵活控制;
② 通过获取SysTick 时钟源选择位(SYSCLK->CLKSEL0.STCLK_S)可知其为0x07即系统滴答的时钟源为内部 22MHz 振荡器 1/2分频;
③ 通过串口调试SystemCoreClock的值为22118400Hz。
对函数DrvSYS_Delay()浅析:
第一句调整为:SysTick->LOAD = (us * (SystemCoreClock/2 / 10000)) / 100; 因为(SystemCoreClock/2)才是真正的系统滴答时钟,该句的作用为赋值SysTick 重新加载值寄存器(SYST_RVR);
第二句SysTick->VAL = (0x00); 该句作用为软件清寄存器为0,其实该值为任何值均可;
第三句SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; 该句作用为使能系统滴答并将CLKSRC写1(1 : 如果没有外部时钟时,可用内核时钟作SysTick, 该位被读为1 ,不能写.0 : 时钟源为外部参考时钟 ),TICKINT写0(向下计数到0不会引起SysTick异常而挂起. 软件设置COUNTFLAG 来确定是否已经发生计数到0);
第四句:while((SysTick->CTRL & (1 << 16)) == 0);计数由1到0时,COUNTFLAG 置位,即等待设置的延时结束。
The Max value 我认为应该为:(1/(22118400/2))*224 *106= 1,521,114μs;
测试源文件:
- /**************************************************
- ** 文件名称:NUC120_HOT_DrvSYS_Delay_TEST.c
- ** 文件说明:NUC120助学板练习程序
- ** 创建日期:2011-04-15
- ** 修改日期:
- ** 备 注:DrvSYS_Delay()测试
- **************************************************/
- #include <stdio.h>
- #include "NUC1xx.h"
- #include "Driver\DrvGPIO.h"
- #include "Driver\DrvSYS.h"
- #include "Driver\DrvUART.h"
- #define Run_Led 2 //2----LED1 3----LED2 4----LED3 5----LED4
- #define Delay_Led 5 //延时函数波形测试辅助 2----LED1 3----LED2 4----LED3 5----LED4
- uint32_t Delay_Val = 1000; //DrvSYS_Delay()延时设置值默认为1000μs
- /***************
- ** 函数声明 **
- ***************/
- void Init_System (void);
- void Init_Uart (void);
- void UART_INT_HANDLE(uint32_t u32IntStatus);
- /*****************************
- ** Name: UART_INT_HANDLE
- ** Function: UART Callback function
- ** Input: u32IntStatus
- ** OutPut: None
- ** Data: 2011-03-17
- ** Note:
- ****************************/
- void UART_INT_HANDLE(uint32_t u32IntStatus)
- {
- uint8_t bInChar[1]={0xFF};
- if(u32IntStatus & DRVUART_RDAINT)
- {
- /* Get all the input characters */
- while(UART0->ISR.RDA_IF==1)
- {
- /* Get the character from UART Buffer */
- DrvUART_Read(UART_PORT0,bInChar,1);
- switch (bInChar[0])
- {
- case '1':
- Delay_Val = 1000;
- break;
- case '2':
- Delay_Val = 1000000;
- break;
- case '3':
- Delay_Val = 300000;
- break;
- default:
- printf("请确认输入指令是否正确!\n");
- break;
- }
-
- }
- }
- }
- /*****************************
- ** Name: Init_System
- ** Function: 系统初始化函数
- ** Input: None
- ** OutPut: None
- ** Data: 2011-03-17
- ** Note:
- ****************************/
- void Init_System(void)
- {
- /* Unlock the locked registers before access */
- UNLOCKREG(x); //寄存器锁定键地址寄存器(RegLockAddr) :有些系统控制寄存器需要被保护起来,以防止误操作而影响芯片运行,
- //这些寄存器在上电复位到用户解锁定之前是锁定的。用户可以连续依次写入“59h”, “16h” “88h”到0x5000_0100解锁定.
- /* Enable the 12MHz oscillator oscillation */
- DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1); //SYSCLK->WRCON.XTL12M_EN = 1;
- /* Waiting for 12M Xtal stable */
- //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1); //SYSCLK->CLKSTATUS.XTL12M_STB
- /*eClkSrc - [in] E_SYS_XTL12M / E_SYS_XTL32K / E_SYS_OSC22M / E_SYS_OSC10K / E_SYS_PLL */
- // Note: Only some of NuMicro NUC100 Series support this function.
- DrvSYS_Delay(5000);
- LOCKREG(x);
- //向“0x5000_0100”写入任何值,就可以重锁保护寄存器
- }
- /*****************************
- ** Name: Init_Uart
- ** Function: UART初始化函数
- ** Input: None
- ** OutPut: None
- ** Data: 2011-03-17
- ** Note:
- ****************************/
- void Init_Uart(void)
- {
- STR_UART_T param;
- /*
- 声明 UART设置的结构体 位于DRVUART.H
- 结构体如下
- typedef struct DRVUART_STRUCT
- {
- uint32_t u32BaudRate;
- E_DATABITS_SETTINS u8cDataBits;
- E_STOPBITS_SETTINS u8cStopBits;
- E_PARITY_SETTINS u8cParity;
- E_FIFO_SETTINGS u8cRxTriggerLevel;
- uint8_t u8TimeOut ;
- }STR_UART_T;
- */
- DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0); //使能UART时钟
- //SYSCLK->CLKSEL1.UART_S = 0; //UART时钟源选择. 00 =外部12MHz 晶振 01 = PLL 1x =内部 22MHz 振荡器
- DrvGPIO_InitFunction(E_FUNC_UART0); //GPB_MFP0-1-2-3置位 GPIO使能UART功能
- //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0xF<<0));
- param.u32BaudRate = 115200; // 波特率
- param.u8cDataBits = DRVUART_DATABITS_8; // 数据位
- param.u8cStopBits = DRVUART_STOPBITS_1; // 停止位
- param.u8cParity = DRVUART_PARITY_NONE; // 校验位
- param.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES; // FIFO存储深度 1 字节
- param.u8TimeOut = 0; // FIFO超时设定
- /* Set UART Configuration */
- if(DrvUART_Open(UART_PORT0,¶m) != E_SUCCESS) // 串口开启、结构体整体赋值
- printf("UART0 open failed\n");
- /* u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 /UART_PORT2 */
- /* sParam -[in] the struct parameter to configure UART */
- /* Enable Interrupt and install the call back function */
- DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);
- /*u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 / UART_PORT2 */
- /*u32InterruptFlag -[in] DRVUART_LININT/DRVUART_WAKEUPINT/DRVUART_BUFERRINT/DRVUART_RLSINT */
- /* DRVUART_MOSINT/DRVUART_THREINT/DRVUART_RDAINT/DRVUART_TOUTINT */
- /*pfncallback -[in] A function pointer for callback function */
- }
- int main (void)
- {
- uint8_t test = 250;
- Init_System();
- Init_Uart();
- DrvGPIO_Open(E_GPA,Run_Led, E_IO_OUTPUT); //程序运行指示
- DrvGPIO_ClrBit(E_GPA,Run_Led);
- DrvGPIO_Open(E_GPA,5, E_IO_OUTPUT); //延时函数波形测试
- printf("\n");
- printf("/*==========================\n");
- printf("======菜农 %d 助学计划======\n",test);
- printf("========NUC120助学板========\n");
- printf("======程序参考新唐BSP=======\n");
- printf("=======2011年04月15日=======\n");
- printf("===DrvSYS_Delay()函数实验===\n");
- printf("HCLK: %dHZ\n ",DrvSYS_GetHCLKFreq());
- printf("SystemCoreClock: %dHZ\n",SystemCoreClock);
- printf("SelectSysTickSource: 0x0%x\n",SYSCLK->CLKSEL0.STCLK_S);
- printf("发送'1'延时值为1000,'2'延时值为1000000,'3'延时值为300000.\n");
- printf("==========================*/\n");
- while(1)
- {
- DrvGPIO_ClrBit(E_GPA,Delay_Led);
- DrvSYS_Delay(Delay_Val);
- DrvGPIO_SetBit(E_GPA,Delay_Led);
- DrvSYS_Delay(Delay_Val);
-
- }
- }
工程结构:
串口调试截图:
延时值设置为1000μs测试波形图:
延时值设置为300000μs测试波形图:
延时值设置为1000000μs测试波形图:
程序很简单,就不上传工程文件了,浪费二姨空间!
|