这两天搞时钟,一直没懂系统时钟频率是怎么算出来的,
想给板子写个秒,毫秒,微妙的延时函数,但写出来误差太大,不知如何得到精准延时!!!
请看看这个程序问题在哪里!!!
时钟设置如下:
void clockInit(void)
{
SysCtlLDOSleepSet(SYSCTL_LDO_1_20V); // 配置PLL前须将LDO设为1.20V
TheSysClock=SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | // 外接25MHz晶振
SYSCTL_OSC_MAIN | // 主振荡器
SYSCTL_USE_PLL | // 系统时钟设置,采用PLL
SYSCTL_CFG_VCO_480), 100000000); // 分频结果为100MHz
//TheSysClock = SysCtlClockGet( ); //获取当前的系统时钟频率,该函数只有TM4C123中调用有效,
//在TM4C129中蜸ysCtlClockFreqSet()函数的返回值
}
/****************************************************************************/
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器为:
//SYSCLK单位为Hz,nms单位为ms
/**************************实现函数********************************************
*函数原型: void delay_ms(u16 nms)
*功 能: 毫秒级延时 延时nms
*******************************************************************************/
void delay_ms(uint32_t nms)
{
uint32_t i;
uint32_t temp=0;
for(i=0;i<=nms;i++)
{
SysTickPeriodSet(1000000);
SysTickEnable();
temp=SysTickValueGet();
if(temp==0)
SysTickDisable();
}
}
//延时nus
//nus为要延时的us数.
/**************************实现函数********************************************
*函数原型: void delay_us(u32 nus)
*功 能: 微秒级延时 延时nus
*******************************************************************************/
void delay_us(uint32_t nus)
{
uint32_t i;
uint32_t temp=0;
for(i=0;i<=nus;i++)
{
SysTickPeriodSet(1000);
SysTickEnable();
temp=SysTickValueGet();
if(temp==0)
SysTickDisable();
}
}
/**************************实现函数********************************************
*函数原型: void delay_ns(u32 ns)
*功 能: 秒级延时 延时ns
*******************************************************************************/
void delay_ns(uint32_t ns)
{
uint32_t i,j;
uint32_t temp=0;
for(i=0;i<=ns;i++)
{
for(j=0;j<=1000;j++)
{
SysTickPeriodSet(1000000);
SysTickEnable();
temp=SysTickValueGet();
if(temp==0)
SysTickDisable();
}
}
}
//——————End of File—————————-
为主函数:
int main(void)
{
jtagWait();
clockInit();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION );
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0|GPIO_PIN_1);
for(;;)
{
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0xff);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0x00);
delay_ns(1);//延时1s
//SysCtlDelay(TheSysClock/4 );
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0x00);
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0xff);
delay_ns(1);//延时1s
//SysCtlDelay(TheSysClock/4 );
}
}
Michael Sun:
SysCtlDelay(1)的时间是三个时钟周期。一般来说要求不太精确的延迟可以用这个去做,
具体也可以自己通过翻转GPIO去测试实际的延迟然后再微调。
如果要求非常准确的延迟就要用定时器来实现了。
wenhua song:
回复 Michael Sun:
void clockInit(void)
{
SysCtlLDOSleepSet(SYSCTL_LDO_1_20V); // 配置PLL前须将LDO设为1.20V
TheSysClock=SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | // 外接25MHz晶振
SYSCTL_OSC_MAIN | // 主振荡器
SYSCTL_USE_PLL | // 系统时钟设置,采用PLL
SYSCTL_CFG_VCO_480), 100000000); // 分频结果为100MHz
//TheSysClock = SysCtlClockGet( ); //获取当前的系统时钟频率,该函数只有TM4C123中调用有效,
//在TM4C129中蜸ysCtlClockFreqSet()函数的返回值
}
我在这个函数中设置的系统时钟为100MHz
那在西面这个void delay_ms(uint32_t nms)
void delay_ms(uint32_t nms)
{
uint32_t i;
uint32_t temp=0;
for(i=0;i<=nms;i++)
{
SysTickPeriodSet(1000000);
SysTickEnable();
temp=SysTickValueGet();
if(temp==0)
SysTickDisable();
}
} 这个延时应该是ms吧?但实际上输出的相差很大,我就不知道问题在哪里!!!
wenhua song:
回复 Michael Sun:
在SysCtlDelay函数定义处总会有这几个错误提示是怎么回事
Michael Sun:
回复 wenhua song:
用的啥IDE?看起来编辑界面不认识汇编。
编译器能认识就行,能编译通过就OK
wenhua song:
回复 Michael Sun:
用的是MDK
wenhua song:
回复 Michael Sun:
是想用SysTick实现1ms延时,应为为了后面方便调用延时程序,我就把它写成了delay形式,可是弄来弄去,用LED闪烁来大致判断时钟,感觉还是很不准确,所以很纠结
Michael Sun:
回复 wenhua song:
用什么方式实现没问题的。时间的精确度最好还是拿示波器去量,会更准一些。
上面提到的Keil MDK对汇编代码的提示直接忽视就好了。
Sun DaSheng Sun:
回复 Michael Sun:
//! Provides a small delay.//!//! \param ui32Count is the number of delay loop iterations to perform.//!//! This function provides a means of generating a constant length delay. It//! is written in assembly to keep the delay consistent across tool chains,//! avoiding the need to tune the delay based on the tool chain in use.//!//! The loop takes 3 cycles/loop.//!//! \return None.
这是这个函数的介绍,可是延时SysCtlDelay(主频/3)为什么是延时1ms呢?不应该是1s吗?
xyz549040622:
回复 Sun DaSheng Sun:
拿个示波器大概量量就知道了,1s和1ms差的有点远,我也觉得像是1ms