不能使用软件产生518K+85HZ的标准方波
文章来源:http://gliethttp.cublog.cn[转载请声明出处]
结论:不能使用软件产生518K+85HZ的标准方波 //518K+85 //518K-85 //这要精确到HZ,也就是1个MCLK //我的at91rm9200处理器,59904000处理器频率,ICache打开 //要想实现,首先518K必须确保,之后,某种方式85个clk,延时,这是不可能实现的 //因为nop指令本身因为需要在SDRAM中执行,而SDRAM自身有读取时序数值, //经测试,在我的SDRAM配置下,一条nop指令需要耗费30ns, //1.指令花费时间不能满足 //1/(518K+85)=1.9301852012700618624357007054827us=1930.1852ns //1/(518K-85)=1.9308187636967456049737891352828us=1930.8187ns //所以需要步进增量值至少在0.1ns的指令,而30ns远远不够 //2.使用定时器同样不能满足 //59904000处理器频率,ICache打开,使用TIMER_CLOCK1模式,即:MCK/2 //59904000/(518K+85)=115.62581429688178580734821506124 //59904000/(518K-85)=115.66376722048984872034986435998 //所以需要定时器计数个数分辨率在0.038个时,才能满足要求,明显我们只能让tick最小值为1 //3.使用PCK产生 //PCK产生的方波很有局限性,但是确实是很精准,因为它直接有MCLK分频输出而得, //但是任何一款cpu外振,比如:18.432M,都对应几个很固定的PCK输出, //通过分析除非cpu外振选用定制的频率,但是如果选用非常特殊的个性定制频率, //那么at91rm9200上点自检测程序--即:固化在内部rom中的蹦C程序,将不能正常识别 //该外振,进而带来一系列调试上的麻烦. //------------------------------------------------------------------------- //综上:无论使用nop来硬凑延时,还是timer定时器,或者PCK,要想实现518K+85HZ方波的产生都是脱离实际的. //------------------------------------------------------------------------------------ 下面附上at91rm9200测试代码: void xSample_PinHZ_install(void) { AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA12; AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA12; //输入 AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA; AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA13; AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA13; //AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PIO_PA12);// | AT91C_PIO_PA13); } void xSample_PinHZ_Set(void) { AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA12; //AT91F_PIO_SetOutput(AT91C_BASE_PIOA, AT91C_PIO_PA12);//r0参数冲突 } void xSample_PinHZ_Clr(void) { AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA12; //AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PIO_PA12);//r0参数冲突 } uint32 xSample_GetInput(void) { return AT91C_BASE_PIOA->PIO_PDSR & AT91C_PIO_PA13; } static uint32 xSample_HardDog_count; /*__inline*/ void xSample_HardDog_ini(void) { xSample_HardDog_count = 0; } void xSample_HardDog_Process(void) {//2007-10-08 gliethttp //为了保证喂狗处理函数每次处理时间数值固定,需要采用下面的方式 //以下除xHardDog_ON()和xHardDog_OFF()可能出现处理时间上的差异之外, //产生的HZ的方波函数xSample_HardDog_Process所花费时间数值可以近似固定. //修正:gliethttp //不需要了 //MAX706,WDI最小秒冲50ns,对于60M,at91rm9200,+ICache,对io线赋值,足够 //++xSample_HardDog_count; //if(xSample_HardDog_count == 0x1000)AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB16;//xHardDog_ON(); //if(xSample_HardDog_count == 0x2000)AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB16;//xHardDog_OFF(); //xSample_HardDog_count %= 0x3000;//除法时间太长 //if(xSample_HardDog_count >= 0x3000)xSample_HardDog_count = 0; AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB16; AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB16; } void xSample_HardDog_Set(void) { AT91C_BASE_PIOB->PIO_SODR = AT91C_PIO_PB16; } void xSample_HardDog_Clr(void) { AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB16; } void xSample_PinHZ_Hold(void) { xSample_PinHZ_Set(); {uint32 i;for(i = 0;i < 0xfffff;i++);}//将io口电平保持若干ms,让硬件电路稳定 } uint8 xSample_518KHZ(void) {uint8 result; xSample_HardDog_ini(); xSample_PinHZ_Hold(); __asm { ;//GOOO之间产生的io方波,频率为6M ;//GOOO: ;//置1 ;//mov r0,#0x1000 ;//mov r1,#0 ;//str r0,[r1,#-0xbd0] ;//置0 ;//mov r0,#0x1000 ;//mov r1,#0 ;//str r0,[r1,#-0xbcc] ;//b GOOO mov r6,#1000000 ;//xSample_PinHZ_Set对应的汇编, ;//mov r0,#0x1000 ;//mov r1,#0 ;//str r0,[r1,#-0xbd0] ;//--2222222222222222222222222222222 TEST: bl xSample_PinHZ_Set ;//++1111111111111111111111111111111 ;//Hr7=7时,high电平=1.160M=862ns ;//r7加1将多68~70ns ;//(518K+85)*2=1.03617M=965.1ns ;//(956.1-862)/70=94.1/70 mov r7,#7+1 loop1: subs r7,r7,#1 bne loop1 nop ;//经测试1条nop指令耗时30ns ;//xSample_GetInput的汇编语句 ;//mov r0,#0 ;//ldr r0,[r0,#-0xbc4] ;//and r0,r0,#0x2000 mov r0,#0 ldr r0,[r0,#-0xbc4];//耗时的io1 ands r0,r0,#0x2000 beq ok ;// bl xSample_GetInput ;// cmp r0,#0 ;//--1111111111111111111111111111111 ;//++2222222222222222222222222222222 bl xSample_PinHZ_Clr;//只要出现io寄存器的地方,就需要for循环进行调整,读取io太耗时间 ;//0电平维持时间 ;//mov r7,#3 加1将多68~70ns ;//Lr7=3时,low电平=1.160M mov r7,#3+0 loop2: subs r7,r7,#1 bne loop2 bl xSample_HardDog_Process;//耗时的io2 ;// bl xSample_HardDog_Set ;// bl xSample_HardDog_Clr subs r6,r6,#1 beq exit b TEST ;//次数过限,退出 ok: mov r6,#0
exit: mov result,r6 } return result; }
|