Randy 发表于 2012-7-18 09:25:47

【大赛原创经验贴】正确理解PxDIR和PxIN、PxOUT之间的关系

看到大家都在论坛上发帖,分享自己的学习经验,让我收获颇大,感觉跟着你们的经验走,进步是比刚开始独自闷着看书要快啊。再次谢过各位了。
不知道大家对Px口的这三个寄存器是怎么理解的,在这里共享我的理解,如有不足,还望和大家一起讨论修改。

PxDIR是msp430单片机IO口的方向控制寄存器,

当把某一位置0时,此时次端口为输入模式,


当把某一位置1时,此时次端口为输出模式,


1、当作为输出模式时,这是就可对其可读可写了,通过对其写,就可以控制外围模块了。

2、当作为输入模式时,只能读它的状态,不能对起写入数据。

而PxIN和PxOUT分别是输入数据和输出数据寄存器。


程序应该先配置PxDIR为输入或输出才能对相应寄存器操作。

大家一定会想既然有了PxIN和PxOUT,为什么还要个PxDIR寄存器呢,直接对相应的寄存器操作就行了嘛,

我觉得是应为msp430单片机对输入输出的严格控制才这样设置的,

因为每一个端口在同一时间只能是输入或是输出状态的一种,


然后在根据具体是设置成什么状态,才能对相应的寄存器进行操作,这样更能精确的控制端口。/****************************************比如下面这段1602显示液晶程序的等待繁忙标志函数程序:************************************/
/*******************************************
函数名称:Wait
功    能:等待1602液晶完成内部操作
参    数:无
返回值:无
********************************************/
void Wait(void)
{
P4DIR &= 0x00;// 将P4口切换成输入状态

CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();

while((P4IN & busy) != 0);//监测忙标志,此时为输入状态,只能对其端口进行读取状态,不能对其进行写操作

CLR_EN;

P4DIR |= 0xFF;//将P4口设置为输出状态,现在就可以对P4口进行读写操作了。

}//The end.


/***************************下面是一个简单的1602显示液晶的简单显示程序,可以进行验证实验。上面的程序包涵在下面的程序中的***************************************/

#include <msp430x14x.h>

typedef unsigned char uint8;
typedef unsigned intuint16;

void Delay_5ms(void);
void Wait(void);
void W_data(uint8 data);
void W_cmd(uint8 cmd,uint8 cmf);
void Init_1602(void);
void main( void )
{
/*关闭所有的IO口*/
P1DIR = 0xFF;P1OUT = 0xFF;
P2DIR = 0xFF;P2OUT = 0xFF;
P3DIR = 0xFF;P3OUT = 0xFF;
P4DIR = 0xFF;P4OUT = 0xFF;
P5DIR = 0xFF;P5OUT = 0xFF;
P6DIR = 0xFF;P6OUT = 0xFF;

// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;

Init_1602();
W_cmd(0xC0,1);
W_data('&')


while(1);

}
/*******************************************
函数名称:Init_1602
功    能:对1602液晶模块进行复位、初始化操作
参    数:无
返回值:无
********************************************/
void Init_1602(void)
{
controlDIR |= 0x07;//控制线端口P3.0 P3.1 P3.2置高设置为输出状态
dataDIR    &= 0xFF;//数据线端口P4设置为输出状态

Delay_5ms();//规定的复位操作
W_cmd(0x38,0);
Delay_5ms();
W_cmd(0x38,0);
Delay_5ms();
W_cmd(0x38,0);

W_cmd(0x38,1);
W_cmd(0x08,1);
W_cmd(0x01,1);
W_cmd(0x06,1);
W_cmd(0x0C,1);

}

/*******************************************
函数名称:W_cmd
功    能:向液晶模块写入命令
参    数:cmd--命令,
          chk--是否判忙的标志,1:判忙,0:不判
返回值:无
********************************************/
void W_cmd(uint8 cmd,uint8 cmf)
{
if (cmf)
    Wait();//等待繁忙标志

CLR_RS;
CLR_RW;
_NOP();

dataOUT = cmd;//讲命令写入数据端口
_NOP();

SET_EN;//使能脉冲信号
_NOP();
_NOP();
CLR_EN;

}

/*******************************************
函数名称:W_data
功    能:向液晶显示的当前地址写入显示数据
参    数:data--显示字符数据
返回值:无
********************************************/
void W_data(uint8 data)
{
Wait();//等待液晶不忙

SET_RS;
CLR_RW;
_NOP();

dataOUT = data;//将显示数据写入数据端口
_NOP();

SET_EN;//使能脉冲信号
_NOP();
_NOP();
CLR_EN;
}

/*******************************************
函数名称:Wait
功    能:等待1602液晶完成内部操作
参    数:无
返回值:无
********************************************/
void Wait(void)
{
P4DIR &= 0x00;// 将P4口切换成输入状态

CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();

while((P4IN & busy) != 0);//监测忙标志

CLR_EN;

P4DIR |= 0xFF;//将P4口设置为输出状态

}

/*******************************************
函数名称:Delay_5ms
功    能:延时约5ms
参    数:无
返回值:无
********************************************/
void Delay_5ms(void)
{
uint16 i = 40000;
while (i != 0)
{
    i--;
}
}

页: [1]
查看完整版本: 【大赛原创经验贴】正确理解PxDIR和PxIN、PxOUT之间的关系