最新日志

发表于:2008-4-30 10:40:34
标签:51  ARM  GPIO  

0

51-PIC-ARM的I/O口比较

**********************
51
I/O口:
1
:准双向口
2
:单独控制I/O口输出的置位或清零(位方式CLRSETB
3
:复位后上拉成高电平,可以用做输入
4
:带载能很弱(未考虑变异产品)
P1
等直接控制

**********************
PIC
I/O口:
1
:真正的双向口
2
:单独控制I/O口输出的置位或清零(位方式BSFBCF
3
:所有I/O口在复位后默认为输入
4
:带载能力强
2个寄存器控制(忽略其他功能)以PORTC为例
TRISC
I/O口方向控制寄存器 输入为1,输出为0
PORTC
I/O引脚值寄存器       

***********************
ARM7
I/O口:
1
:真正的双向口
2
:单独控制I/O口输出的置位或清零(其实还是字方式)
3
:所有I/O口在复位后默认为输入
4
:带载能力不强
4个寄存器控制(忽略其他功能)
IOPIN
IO引脚值寄存器,引脚的当前状态可从该寄存器中读出
       
(不管I/O口是输入还是输出)其实PIC的也一样
IOSET
I/O输出置位寄存器,写入1输出高电平,写入0无效
       
好象不存在读-修改-写的问题,这个比较特殊
IOCLR
I/O输出清0寄存器,作用同上
IODIR
I/O口方向控制寄存器(同PICTRISC等)
       
输入为0,输出为1(同PIC的相反)
注:IOSETIOCLR是一对
***************
***************


I/O
口优缺点(个人愚见):

1
:输出10
   51
SETB P1.0
   PIC
BSF  PORTC,0
        

        BCF  PORTC,0
        
要注意其他端口的情况(读-修改-写的问题)
   ARM
:如要求在P0.0输出1,只要IO0SET=0x00000001即可
        
不用担心其他引脚的情况
2
:取反(例对第0)
   51
可以用异或也可用取反(因为有布尔取反指令)
   PIC
:用异或 PORTB="PORTB"^0x01;
   ARM
:只能分开搞了
        if(IO0SET&0x00000001==0)
         {IO0SET=0x00000001;}
        else
         {IO0CLR=0x00000001;}
3
:同时改变P0口的某几位为1,某几位为0
   
如原P0=0x00000055,现要求P0=0x000000aa
   51
P0=0xaa;
   PIC
PORTC=0xaa;
   ARM
:比较麻烦了
        
写法1:IO0SET=0x0000aaaa
              IO0CLR=0xffff5555
        
不但要分2次写,而且还出现了中间状态
        
这种情况在51PIC中是不会出现的
4
:读I/O口状态
   51
必须先对端口写1SETB  P1.0
        
然后再判断是1还是0    
   PIC
:先设为输入,然后判断
   ARM
:先设为输入,然后判断

4
:驱动能力
   51
最低,PIC最强
   
例:在I/O口与地间接一个100欧的电阻
       I/O
口输出1,然后读此I/O口,只有PIC可读回高电平
       
如果ARM读的是IOSET则读到高电平,如果读IOPIN则读到
       
低电平,输出和实际电平不符

 

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(238)
发表于:2008-4-16 15:16:39
标签:无标签

0

关于C51的中断编程

8051 系列 MCU 的基本结构包括:32 个 I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中断发生后,MCU 转到 5 个中断入口处之一,然后执行相应的中断服务
处理程序。中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下:
中断源 中断向量
---------------------------
上电复位 0000H
外部中断0 0003H
定时器0 溢出 000BH
外部中断1 0013H
定时器1 溢出 001BH
串行口中断 0023H
定时器2 溢出 002BH

interrupt 和 using 都是 C51 的关键字。C51 中断过程通过使用 interrupt 关键字和中断号(0 到 31)来实现。中断号指明编译器中断程序的入口地址中断序号对应着 8051中断使能寄存器IE 中的使能位,对应关系如下:
IE寄存器 C51中的 8051的
的使能位 中断号 中断源
--------------------------------
IE.0 0 外部中断0
IE.1 1 定时器0 溢出
IE.2 2 外部中断1
IE.3 3 定时器1 溢出
IE.4 4 串口中断
IE.5 5 定时器2 溢出

有了这一声明,编译器不需理会寄存器组参数的使用和对累加器A、状态寄存器、寄存器B、数据指针和默认的寄存器的保护。只要在中断程序中用到,编译器会把它们压栈,在中断程序结束时将他们出栈。C51 支持所有 5 个 8051 标准中断从 0 到 4 和在 8051 系列(增强型)中多达 27 个中断源。
using 关键字用来指定中断服务程序使用的寄存器组。用法是:using 后跟一个0 到3 的数,对应着 4 组工作寄存器。一旦指定工作寄存器组,默认的工作寄存器组就不会被压栈,这将节省 32 个处理周期,因为入栈和出栈都需要 2 个处理周期。这一做法的缺点是所有调用中断的过程都必须使用指定的同一个寄存器组,否则参数传递会发生错误。因此对于using,在使用中需灵活取舍。

如果在中断服务函数 ISR 中使用寄存器,那么必须处理好 using 的使用问题:
1、中断服务函数使用 using 指定与主函数不同的寄存器组(主函数一般使用 Register bank 0)。
2、中断优先级相同的ISR 可用 using 指定相同的寄存器组,但优先级不同的 ISR 必须使用不同的寄存器组,在 ISR 中被调用的函数也要使用 using 指定与中断函数相同的寄存器组。
3、如果不用 using 指定,在 ISR 的入口,C51 默认选择寄存器组0,这相当于中断服务程序的入口首先执行指令:
MOV PSW #0
这点保证了,没使用 using 指定的高优先级中断。可以中断使用不同的寄存器组的低优先级中断。
4、使用 using 关键字给中断指定寄存器组,这样直接切换寄存器组而不必进行大量的 PUSH 和 POP 操作,可以节省RAM空间,加速 MCU 执行时间。寄存器组的切换,总的来说比较容易出错,要对内存的使用情况有比较清晰的认识,其正确性要由你自己来保证。特别在程序中有直接地址访问的时候,一定要小心谨慎!至于“什么时候要用到寄存器组切换”,一种情况是:当你试图让两个(或以上)作业同时运行,而且它们的现场需要一些隔离的时候,就会用上了。在 ISR 或使用实时操作系统 RTOS 中,寄存器非常有用。
寄存器组使用的原则:
1、8051 的最低32 个字节分成 4 组 8 寄存器。分别为寄存器R0 到R7。寄存器组由PSW 的低两位选择。在 ISR 中,MCU 可以切换到一个不同的寄存器组。对寄存器组的访问不可位寻址,C51 编译器规定使用 using 或 禁止中断的函数(#pragma disable )均不能返回 bit 类型的值。
2、主程序(main函数)使用一组,如 bank 0;低中断优先级的所有中断均使用第二组,如 bank 1;高中断优先级的所有中断均使用再另外一组,如 bank 2。显然,同级别的中断使用同一组寄存器不会有问题,因为不会发生中断嵌套;而高优先级的中断则要使用与低优先级中断不同的一组,因为有可能出现在低优先级中断中发生高优先级中断的情况。编译器会自动判断何时可使用绝对寄存器存取。
3、在 ISR 中调用其它函数,必须和中断使用相同的寄存器组。当没用 NOAREGS 命令做明确的声明,编译器将使用绝对寄存器寻址方式访问函数选定(即用 using 或 REGISTERBANK 指定)的寄存器组,当函数假定的和实际所选的寄存器组不同时,将产生不可预知的结果,从而可能出现参数传递错误,返回值可能会在错误的寄存器组中。
举一例子:当需要在中断内和中断外调用同一个函数,假定按照程序的流程控制,不会出现函数的递归调用现象,这样的调用会不会出现问题?若确定不会发生重入情况,则有以下两种情况:
1、如果 ISR 和主程序使用同一寄存器组(主程序缺省使用BANK 0,若 ISR 没有使用 using 为其指定寄存器区,则缺省也使用 BANK 0),则不需其他设置。
2、如果 ISR 和主程序使用不同的寄存器组(主程序缺省使用BANK 0,ISR 使用 using 指定了其他 BANK),则被调用函数必须放在:
#pragma NOAREGS
#pragma AREGS
控制参数对中,指定编译器不要对该函数使用绝对寄存器寻址方式;或者也可在 Options->C51,选中“Dont use absolute register accesses”,使所有代码均不使用绝对寄存器寻址方式(这样,执行效率将稍有降低)。不论以上的哪一种情况,编译器均会给出重入警告,需手工更改 OVERLAY 参数,做重入说明。
3、还有一种办法:如果被调用函数的代码不是很长,还是将该函数复制一份,用不同的函数名代替,这种情况适合ROM有足够多余的空间。
因此,对using关键字的使用,如果没把握,宁可不用,交给编译系统自己去处理好了。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(1) | 阅读(192)
总共 , 当前 /