Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15322983
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类:

2007-10-09 14:14:29

不能使用软件产生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;
}

阅读(2627) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~