一个“&”占用了超过6个指令周期!!!可能吗?讨论中……(附图,附程序)熟悉汇编的友友请进

2020-02-08 09:30发布

指令时钟与定时器时钟同步,为FOSC/4
我在用定时器为定时的候,设置了一个等待程序,想通过定时器计时发生中断的时候执行下面指令:

TMR4=9;
……
while(TMR4>16);
……

但在实际调试用发现,根本不会等,就自自往下执行了,调开寄存器一看,在执行"while(TMR4>16);"的时候,TMR4已经为20了,造成程序混乱。
看了一下ProgramMemory的汇编指令,发现:
一条这样的指令,竟然使用了6个指令周期:

Conversion&=CMOUT;
系统外部时钟是:13.56MHZ
指令周期:4/13.56MHZ=0.295us
定时时钟也是:0.295us

for(ReceiCount=1;ReceiCount<ReceiLenth;ReceiCount++)
上面这样一个for循环就更可怕了,占到13个指令周期,时间大概是:13*0.295=3.83us了。

现在想解决问题是:能不能有什么办法减少这些周期数,或者编译平台能否进行优化。

        Conversion=0;                  //计数器
        PR4 =32;                 //128 clock  
        TMR4=9;
        for(ReceiCount=1;ReceiCount<ReceiLenth;ReceiCount++)
        {
                temp>>=1;
                temp&=0x7F;
                Conversion=0x20;
                while(TMR4>16);
                Conversion&=CMOUT;  //检测高电平
                Conversion&=CMOUT;
                Conversion&=CMOUT;
                Conversion&=CMOUT;
                temp|=Conversion;  //保存数据
                if((ReceiCount%8)==0)
                {
                        t=ReceiCount/8;
                        Receiver[t-1]=temp;
                }
        }
能在9个us内完成这样一个for循环周期去检测脉冲信号?求高见!~~~~

以下附实验图片,可供参考。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
20条回答
worksnfkpynn99
1楼-- · 2020-02-09 09:51
回复【4楼】wangjiati 叶子
回复【楼主位】worksnfkpynn99 如影客
系统外部时钟是:13.56mhz  
指令周期:4/13.56mhz=0.295us  
定时时钟也是:0.295us  
....
能在9个us内完成这样一个for循环周期去检测脉冲信号?求高见!~~~~  
-----------------------------------------------------------------------
9/0.295us  = 31条指令
for(receicount=1;receicount&lt;receilenth;receicount++)
"receicount=1"赋值运算  如果"receicount" 是16位  汇编怎么说也要6-7条吧?  
一句就去了十几条了.下面再写起来就难了..
receicount%8 这样的一句就去了估计20条.
感觉命题需求不......
-----------------------------------------------------------------------



是的,你说的对,照按现行方案根本满足不了现行的需求。

昨天重新认真分析了一下,想按这样的时钟速度跑这个程序嵌套,是根本没法完成的。而且还有一个除法的运算:t=ReceiCount/8;
但是,我就是看过有朋友这样做出来过,不知道是不是用C语言,或者C再嵌套汇编,再或者纯汇编。
我想要的需求很单一,在一数据流中,每9.4个us左右读取一位,然后保存下来。大概最多的时候有40个位,所以要保证每读一个位的时间周期要精确,就只能想到用定时器,但是现行时钟和定时器分辨率是远远无法满足的,再者也不可能再增大时钟了……友友们帮我讨论下解决方案啦……

期待……
OpCode
2楼-- · 2020-02-09 12:21
 精彩回答 2  元偷偷看……
worksnfkpynn99
3楼-- · 2020-02-09 13:18
回复【8楼】OpCode
每9.4个us左右读取一位,不知道为什么要这样设计,时间实在太短,中断里随便处理下指令就不止这么点时间,还有除8为什么不弄成位移操作。什么样的信号必须用精确时间来读取?晕!
-----------------------------------------------------------------------

是一种读卡程序,因为它返回数据的速度就是有这么快的,返回的是一串数据,然后每9.4个us为一个周期代表一个位,所以只能这样了。。。。

以下是发送和返回数据流:

发送

(原文件名:数据流.jpg)

返回

(原文件名:返回数据流.jpg)
millwood0
4楼-- · 2020-02-09 18:32
"能在9个us内完成这样一个for循环周期去检测脉冲信号?"

yes, if you run your mcu at 1Ghz.





























seriously, you need to find a better way to approach your "problem", and it is only your problem because of the way you have approached it.
wangjiati
5楼-- · 2020-02-09 20:04
回复【9楼】worksnfkpynn99 如影客
-----------------------------------------------------------------------
天呢.. 你走弯路了..  怎么能用位检测的方法是去做串口通信呢??
这个应该一个MCU的通信功能实现..
worksnfkpynn99
6楼-- · 2020-02-09 23:56
回复【11楼】wangjiati 叶子
回复【9楼】worksnfkpynn99 如影客
-----------------------------------------------------------------------
天呢.. 你走弯路了..  怎么能用位检测的方法是去做串口通信呢??  
这个应该一个mcu的通信功能实现..
-----------------------------------------------------------------------

嗯嗯嗯……
是错了,想知道用什么方法去读这些脉冲信号呀,
频率:106K
解码方式:曼码即:01=0,10=1

我使用定时器+比较器的方法,
比较器输出:#define EMad1 C1OUT
定时器:TMR0(13.56/4指令时钟的32预分频),128*T0=9.4us
以下是我的程序,友友们帮我分析一下啦,不胜感激。

unsigned char readBIT(unsigned char LongNum)
{
        unsigned char temp;
        unsigned char t,i;
        t=0;
        while(EMda0){}                 //无比较输出 等待……
        TMR0=0;
        for(i=0;i<LongNum;i++)
        {       
                while(EMda0){}        //无比较输出 等待……
                t=TMR0;
                if(t<50) temp|=0x80;  //在前半周期出现高电平:解为1 保存在temp
                if(t>80) temp&=0x7F;  //在后半周期出现低电平:解为0 保存在temp
                temp>>=1;             //保存一位
                while(TMR0<120){}     //等待一个周期完成
                TMR0=0;
        }
        return 1;
}

帮我提一下可行意见,好吗?在线……

一周热门 更多>