图14.14 P1SKIP:端口1跳过寄存器
图14.5 XBR0:端口I/O交叉开关寄存器0
25
图14.6 XBR1:端口I/O交叉开关寄存器1
2.4.2 端口 I/O 初始化
端口 I/O 初始化包括以下步骤:
1. 用端口输入方式寄存器(PnMDIN)选择所有端口引脚的输入方式(模拟或数字)。 2. 用端口输出方式寄存器(PnMDOUT)选择所有端口引脚的输出方式(漏极开路或
推挽)。
3. 用端口跳过寄存器(PnSKIP)选择应被交叉开关跳过的那些引脚。 4. 将引脚分配给要使用的外设。 5. 使能交叉开关(XBARE = ?1?)。
所有端口引脚都必须被配置为模拟或数字输入。被用作比较器或ADC输入的任何引脚都应被配置为模拟输入。当一个引脚被配置为模拟输入时,它的弱上拉、数字驱动器和数字接收器都被禁止,这可以节省功耗并减小模拟输入的噪声。被配置为数字输入的引脚可以被模拟外设使用,但不建议这样做。
此外,应将交叉开关配置为跳过所有被用作模拟输入的引脚(通过将PnSKIP寄存器中的对应位置?1?来实现)。端口输入方式在PnMDIN寄存器中设置,其中?1?表示数字输入,?0?表示模拟输入。复位后所有引脚的缺省设置都是数字输入。对PnMDIN寄存器的详细说明见图14.8。
26
图14.8 P0MDIN:端口0输入方式寄存器
图14.12 P1MDIN:端口1输入方式寄存器
I/O引脚的输出驱动器特性由端口输出方式寄存器PnMDOUT中的对应位决定,每个端口输出驱动器都可被配置为漏极开路或推挽方式。不管交叉开关是否将端口引脚分配给某个数字外设,都需要对端口驱动器的输出方式进行设置。唯一的例外是SMBus引脚(SDA,SCL),不管PnMDOUT的设置如何,这两个引脚总是被配置为漏极开路。
图14.9 P0MDOUT:端口0输出方式寄存器
图14.13 P1MDOUT:端口1输出方式寄存器
27
当XBR1寄存器中的WEAKPUD位为?0?时,输出方式为漏极开路的那些引脚的弱上拉被使能。WEAKPUD不影响被配置为推挽方式的端口I/O。当漏极开路输出被驱动为逻辑?0?时,弱上拉被自动关断(禁止)以避免不必要的功率消耗。
寄存器XBR0和XBR1必须被装入正确的值以选择所需要的数字I/O功能。置?1?XBR1中的XBARE位将使能交叉开关。不管XBRn寄存器的设置如何,在交叉开关被使能之前,外部引脚保持标准端口I/O方式(输入)。对于给定的XBRn设置,可以使用优先权译码表确定I/O引脚分配;另一种方法是使用Silicon Labs IDE软件的配置向导功能来确定基于XBRn寄存器设置的端口I/O引脚分配。
注意:为使端口引脚工作在标准端口I/O输出方式,交叉开关必须被使能。当交叉开关被禁止时,端口输出驱动器被禁止。
2.4.3 通用端口 I/O
未被交叉开关分配的端口引脚和未被模拟外设使用的端口引脚都可以作为通用I/O。通过对应的端口数据寄存器访问端口P2-0,这些寄存器既可以按位寻址也可以按字节寻址。
向端口写入时,数据被锁存到端口数据寄存器中,以保持引脚上的输出数据值不变。 读端口数据寄存器(或端口位)将总是返回引脚本身的逻辑状态,而与XBRn的设置值无关,即使在引脚被交叉开关分配给其它信号时,端口寄存器总是读其对应的端口I/O引脚。但在对端口SFR执行下面的读-修改-写指令(ANL、ORL、XRL、JBC、CPL、INC、DEC、DJNZ)和对端口SFR中的某一位执行MOV、CLR、SETB期间例外。这些指令读端口寄存器(而不是引脚)的值,修改后再写回端口SFR。
图14.7 P0:端口0寄存器
28
3 C8051F330单片机系统软件设计要点
3.1 单片机的初始化设置
C8051F单片机的软件设计基本上和标准的8051单片机是一样的,但是略有差异。这些差异主要是由C8051F单片机所引入的一些新特性所引起的,如时钟系统、看门狗、交叉开关等。因此,在软件设计时首先要对单片机进行初始化,包括以下几点:
? 看门狗初始化-开启还是禁止、如果开启则喂狗周期为多少; ? 时钟系统的初始化-确定系统的工作时钟源及频率;
? I/O引脚输入输出方式初始化-输入:模拟还是数字、输出:推挽还是开漏;? 数字外设的配置和交叉开关设置; 以下为一段例程。
void SysClkInit(void) //配置系统时钟 {
OSCICN|=0x03;
OSCICL=OSCICL+22; //设置片内振荡器为22.1184MHZ }
void SystemInit(void) //系统配置 { PCA0MD&=~0x40; //禁止看门狗定时器 EA=1; }
void PortInit(void) //端口配置 {
P0SKIP=0x02; XBR0=0x05; //设置交叉开关 XBR1=0x43; P0MDIN=0xff; //配置P0、P1口输入输出方式 P0MDOUT=0x00; P1MDIN=0xff; P1MDOUT=0xB8; }
void main(void) { unsigned char KeyBuff,TimeNum,KeyValue; code unsigned char LEDA[]={0x08,0x10,0x20,0}; code unsigned char LEDB[]={0x10,0x28,0,0}; code unsigned char LEDC[]={0x38,0,0x38,0};
29
}
SystemInit(); //系统配置 SysClkInit(); //配置系统时钟 PortInit(); //端口配置 …
3.2 软件延时程序
由于C8051F单片机的系统工作时钟是可编程的,因此在编写软件延时程序时要注意系统时钟变化对软件延时的影响。以下为一个延时子程序的例子。
void DelayMs(unsigned int n) //延时(n)MS,系统时钟为22.1184MHz { unsigned int i; for(;n>0;n--) { for(i=2211;i>0;i--); } }
30