关于“为何avr使用写1作为清0中断标志位的手段”这个问题我看过很多的相关资料。在avr的手册中并没有给出为什么的解释,只是强调了“写1清0中断标志位”。同时我也看到很多新的芯片,如dsp等,也是采用写1清零标志位的。但没有找到更专业的,或从根源上的说明,如果那位有这方面的知识或资料,欢迎深入的讨论学习。
下面是我个人的分析和解释,供参考。
1。首先从硬件上的考虑,通常的读写处理单元是以8bit字节为单位的,因为数据总线一般是8位的倍数。这样对位的操作就不方便,不能直接写1位(会改变其它的位),需要先读到寄存器,然后改动1位,最后回写,需要更多的时间。
2。对于ram操作一般采用直接写的方式,所以对ram基本上没有直接的位操作指令。而对于寄存器是可以直接位操作的,但如果对所有的寄存器都能实现位操作,那么硬件结构上就非常复杂和庞大了,所以必须采用一种折中的处理方法。
3。现在的趋势是采用c语言编写系统程序,而标准的c中,没有位变量的概念,最小的单位也是字节。因此硬件的设计上面也要考虑能发挥c语言的优势。
以上是我分析的原因。因为已经超出了我研究的方向(我侧重于应用),可能不全面或有偏差。下面回到avr本身。
我们可以注意到:
1。avr没有“位”空间,也就是说没有单独的“位”地址,所有的位寻址是基于8位的寄存器的,所以基本寻址方式是以寄存器为主的。
2。因此avr没有专门的位寻址指令,它本身的位操作指令很少,都是在寄存器寻址的基础上,对寄存器的某位进行操作。
3。除了对状态寄存器sreg中的位有直接的操作指令外(sreg太特殊了,必须要有专用的位操作指令),能够对其它寄存器的位操作的指令只有2个。
a)bst、bld。这个指令的周期是1ck,他是将sreg中的t标志位与32个通用寄存器的位之间交换数据的指令。如果要对32个寄存器的1位进行设置的话(比如置1),必须先使用指令将sreg中的t置1,然后使用bld指令将t的值写到寄存器的某位。需要2个ck时间。
b)sbi、cbi。这2条指令是对前32个(注意:仅对前32个i/o空间!)i/o空间的寄存器的位进行设置的指令。这2个指令的执行时间是2个ck。avr对寄存器操作的指令大多数都是1个ck,而这2个指令为何需要2个ck?原因在与写的时候还是8位一起写,因此改变1位需要先读,修改1位,再回写。这样保证了其它位不变,但时间需要2个ck了。
4。正是由于第3点(b),所以pa、pb、pc、pd等i/o口的寄存器均在前32个i/o空间,这样就实现了方便的单独的按位控制i/o口了。
5。不同c编译器,位处理是不同的。icc、iar基本没有扩展位处理,按标准c来处理,因为他们考虑的可移植性更加多些。而cvavr扩展了位变量(放在32个工作寄存器中)和位操作(仅能对i/o空间前32个寄存器),因此用户使用起来更方便些。但要注意,对i/o空间后32个寄存器,cvavr也不能实现位操作的。
最后看一下中断标志位的处理。在avr中对中断标志位的处理是根据不同情况采用不同的处理方法的,在上面的英文说明中已经给出了解释。有的是进入执行中断由硬件清除,有的是读某个寄存器后由硬件清除。而软件清除通常是写“1”,为什么?
看一下m16的手册,发现外部中断标志寄存器gifr(0x3a)、和t/c的中断标志寄存器tifr(0x38),都在i/o空间的后32个地址中,而且全部是中断标志寄存器。因此不管是icc、iar、还是cvavr,肯定不能使用sbi、cbi指令对位操作了,只能是对1个寄存器8位同时写操作了。
那么,通常在c中如何改变1位置1呢?通常大家认为正确的语句是:xxxx |= 0b00000001;其功能是将xxxx先读出,然后同0b00000001或,使最低位为1,其它位保持不变。实际需要3条汇编指令的。改变1位置0:xxxx &= 0b11111110;同样需要3条汇编指令的。
avr采用写“1”清“0”中断标志位(写“0”不影响标志位),那么语句就可以直接使用tifr = 0b00000001了,只需要2条汇编。将最低位的标志位清“0”,同时保证了其它标志位的不变。(!!!注意,反而使用tifr |= 0b00000001是错误的!!!因为,如果其它的位本身是1的话,这样反而也被清掉了)
另外,写“0”清“0”中断标志位的话,那么写“1”到中断标志位的话应该如何定义呢?中断标志位应该是硬件置1的,如果软件可以置1,会带来更多的麻烦。
实际上,上面的英文解释还是不全面的,容易引起一些误解。
a)只能对于tifr、gifr使用tifr = 0b00000001这样的语句,因为只有这两个寄存器中,全部都是中断标志位。
b)而对于一些其它的中断标志位,如果它所在的寄存器中还有一些是非中断标志位的,就必须使用xxxx |= 0b00000001的写法了。
c)对于非中断标志位的设置,还是必须使用xxxx |= 0b00000001这样的形式的。
汽车电子产业链已决定以原有玩家为主的状况
模拟光端机和数字光端的特点及应用范围分析
苹果获得一项适用于Apple Watch的温度传感器专利
产业链揭示华为Mate30备货到位 四摄手机性能超越苹果新机
基本逻辑运算
为什么AVR单片机需要写1作为清0中断标志位
调查:95%以上日本被访者对VR感兴趣
接地电缆箱如何使用?它是怎么安装的
CCD视觉检测外观缺陷,漏检率和误检率如何评估
摩托罗拉3月5日上新品,全新Moto Mods模块
基于FPGA+MCU的大型LED显示屏系统设计
ORAN与传统RAN 成本怎么比较?
人工智能的跨越发展怎样实现
浅谈PCB制作工艺过程
超高亮LED迷你台灯电路
谨慎5G骗局新花样,中国铁塔辟谣集资
10种聚类算法和Python代码2
大数据产业增量蓝海市场正在逐步打开,展现出巨大潜力
微带线传输阻抗匹配实例分析
Parrot推出新款产品ANAFI:史上最安静无人机发布,售价为699 美元