STC 1T单片机实现精确到 0.004微秒级同步信号输出

文章探讨了使用STC单片机实现RFID ISO15693标签读写时,精确生成周期为9.44us的同步信号遇到的挑战。通过汇编代码分析,提出了使用switch语句实现误差补偿的方法,并详细解释了代码汇编过程及优化策略。

最近因为需要使用STC 1T单片机进行RFID ISO15693 标签读写

 
调制发送信号时需要周期为 9.44us 左右的精确的同步信号

 
STC单片机使用 22.1184M 晶振,单周期指令执行时间约为 0.04521us 所以 9.44us时间段大约可执行 208.8 条单周期指令

 
所以有以下代码


while(1)
{

    TL0=0;

 

     //.. 可伸缩地执行少量其它代码

 

    while(TL0<205);

    OUTPIN = ~OUTPIN;

}

但实际用示波器对OUTPIN 上信号波形进行观察,发现存在不稳定的现像, 偏差最大时约 0.28us


对该段代码汇编后的汇编语句进行分析, 发现 while(TL0<205); 居然要4条语句才能实现

0034         ?C0057:
0034 E58A    MOV     A,TL0
0036 C3      CLR     C
0037 947F    SUBB    A,#07FH
0039 40F9    JC      ?C0057


对如上汇编代码,如果 MOV A,TL0 执行时TL0 值恰好为 204

 

哪么多执行一轮就得多耗掉 6个指令周期 恰好为 0.28us


显然无论怎么实现,要测试TL0中值至少得4个指令周期 误差最大为 T x 2 - 2 = 6 周期  这个避免不了

 

while(x<y) _nop_();   这样的代码是也存在同样问题。

 

使用C语的情况下暂时有且只发现switch可以实现误差补偿

while(1)
{

     TL0=0;

 

     //.. 可伸缩地执行少量其它代码

 

    while(TL0<(205-16)); // 这个 16可跟据输出进行微调

    uTime -= TL0;

    switch(uTime)
    {
       case 8: _nop_();
       case 7: _nop_();
       case 6: _nop_();
       case 5: _nop_();
       case 4: _nop_();
       case 3: _nop_();
       case 2: _nop_();
       case 1: _nop_();
       case 0: break;
    }    

    OUTPIN = ~OUTPIN;

}


以上代码对的汇编语句容易看出, 执行 NOP 句代数目在uTime-=TL0(SUBB A,TL0)哪一刻就确定了

003B C3                CLR     C
003C E500        R     MOV     A,uTime
003E 958A              SUBB    A,TL0
0040 F500        R     MOV     uTime,A
0042 14                DEC     A
0043 B41400            CJNE    A,#014H,?C0168
0046         ?C0168:
0046 505E              JNC     ?C0059

0048 900000      R     MOV     DPTR,#?C0169
004B 75F003            MOV     B,#03H
004E A4                MUL     AB
004F C583              XCH     A,DPH
0051 25F0              ADD     A,B
0053 C583              XCH     A,DPH
0055 73                JMP     @A+DPTR
0056         ?C0169:
0056 020000      R     LJMP    ?C0079
0059 020000      R     LJMP    ?C0078
005C 020000      R     LJMP    ?C0077
005F 020000      R     LJMP    ?C0076
0062 020000      R     LJMP    ?C0075
0065 020000      R     LJMP    ?C0074
0068 020000      R     LJMP    ?C0073
006B 020000      R     LJMP    ?C0072
006E 020000      R     LJMP    ?C0071
0071 020000      R     LJMP    ?C0070
0074 020000      R     LJMP    ?C0069
0077 020000      R     LJMP    ?C0068
007A 020000      R     LJMP    ?C0067
007D 020000      R     LJMP    ?C0066
0080 020000      R     LJMP    ?C0065
0083 020000      R     LJMP    ?C0064
0086 020000      R     LJMP    ?C0063
0089 020000      R     LJMP    ?C0062
008C 020000      R     LJMP    ?C0061
008F 020000      R     LJMP    ?C0060


009D         ?C0071:
009D 00                NOP
009E         ?C0072:
009E 00                NOP
009F         ?C0073:
009F 00                NOP
00A0         ?C0074:
00A0 00                NOP
00A1         ?C0075:
00A1 00                NOP
00A2         ?C0076:
00A2 00                NOP
00A3         ?C0077:
00A3 00                NOP
00A4         ?C0078:
00A4 00                NOP
00A5         ?C0079:
00A5 00                NOP

 


大家还有没更好办法?欢迎一起来讨论。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值