并行数字输入输出端口的使用4文档格式.docx
《并行数字输入输出端口的使用4文档格式.docx》由会员分享,可在线阅读,更多相关《并行数字输入输出端口的使用4文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
7
6
5
4
3
2
1
位名称
PxSEL.7
PxSEL.6
PxSEL.5
PxSEL.4
PxSEL.3
PxSEL.2
PxSEL.1
PxSEL.0
操作方式
rw
复位值
PxSEL.x:
管脚功能选择
0普通并行数字输入/输出管脚
1外围功能模块管脚
MSP430系列微控制器的大部分管脚是复用管脚,即一个管脚可以扮演多种作用。
功能选择寄存器(PxSEL)用来配置管脚实现不同的功能。
每一个端口都具有功能选择寄存器,该寄存器的每一位控制1个管脚。
一些MSP430微控制器芯片的管脚具有更多功用,因此它们还具有功能选择寄存器2(PxSEL2),这时功能选择寄存器(PxSEL)和功能选择寄存器2(PxSEL2)联合实现对管脚功能的选择。
■方向控制寄存器(PxDIR)
PxDIR.7
PxDIR.6
PxDIR.5
PxDIR.4
PxDIR.3
PxDIR.2
PxDIR.1
PxDIR.0
无论管脚设置为普通并行数字输入/输出管脚,还是外围模块管脚,即无论功能选择寄存器中的位取何值,都必须合适地设置方向控制寄存器的位PxDIR.x内容,以决定管脚信号的流向。
PxDIR.x:
管脚信号传输方向选择
0输入
1输出
■输入寄存器(PxIN)
PxIN.7
PxIN.6
PxIN.5
PxIN.4
PxIN.3
PxIN.2
PxIN.1
PxIN.0
r
当管脚设置为普通并行数字输入/输出管脚,输入传输方向时,读输入寄存器中位PxIN.x内容就可以获得对应管脚的状态。
PxIN.x:
管脚输入状态
0低电平
1高电平
■输出寄存器(PxOUT)
PxOUT.7
PxOUT.6
PxOUT.5
PxOUT.4
PxOUT.3
PxOUT.2
PxOUT.1
PxOUT.0
w
当管脚设置为普通并行数字输入/输出管脚,输出传输方向时,写入输出寄存器位PxOUT.x内容将控制对应管脚的状态。
PxOUT.x:
管脚输出状态
4.2基于并行数据传输的数码管电路
4.2.1数码管
数码管是应用电路中常用的显示器件。
数码管内部包含8个发光二极管,它的原理图、外形图和电路符号图如图4.1所示。
数码管原理图如图4.1的(a)和(b)所示。
数码管分共阴极和共阳极两种类型。
共阴极数码管内部8个二极管的N极被连接在一起,再和管脚COM相接。
在使用时管脚COM应该接低电平,这样当数码管其余的某个管脚接高电平,则该管脚对应的发光二极管将被点亮,也就是数码管对应的发光段被点亮。
共阳极数码管内部8个二极管的P极被连接在一起,再和管脚COM相接。
在使用时管脚COM应该接高电平,这样当数码管其余的某个管脚接低电平,则该管脚对应的发光二极管将被点亮,也就是数码管对应的发光段被点亮。
数码管外形图如图4.1的(c)所示。
数码管有2个COM管脚,这两个管脚在数码管内部被连接在一起,在使用时,应用电路中只需要连接一个COM管脚即可。
数码管的电路符号图如图4.1的(d)所示。
图4.1数码管的原理图、外形图和电路符号图
数码管显示电路可以由图2.1所示的流水灯电路改装来实现。
从流水灯电路中去掉发光二极管,换上一个共阴极数码管,就成为基于MSP430微控制器芯片的P1并行输入/输出端口的数码管显示电路。
具体电路如图4.2所示。
这里数码管的各个管脚与MSP430芯片P1端口各个管脚的连接关系如表4.1所示。
表4.1数码管管脚与P1端口管脚的连接关系
P1口
P1.7
P1.6
P1.5
P1.4
P1.3
P1.2
P1.1
P1.0
数码管
a
b
c
d
e
f
g
dp
图4.2基于P1端口的数码管电路
在图4.2中,数码管也可以采用共阴极数码管,也可以采用共阳极数码管。
如果使用共阴极数码管,它的管脚COM应该通过一个限流电阻和接地线相接;
如果使用共阳极数码管,它的管脚COM应该通过一个限流电阻和电源线相接。
不使用数码管的小数点时,控制共阴极数码管发光段“dp”的管脚P1.7可以一直输出低电平。
这种情况下,数码管的显示字符与输入代码,即P1端口的输出数据,之间的关系如表4.2所示。
在表4.2中,共阳极数码管的显示字符与输入代码的关系也被同时列出。
注意,两种显示代码都不驱动小数点的发光段“dp”。
表4.2数码管的显示代码
显示字符
共阴极数码管
共阳极数码管
0xfc
0x03
9
0xf6
0x09
0x60
0x9f
0xee
0x11
0xda
0x25
0x3e
0xc1
0xf2
0x0d
C
0x9c
0x63
0x66
0x99
0x7a
0x85
0xb6
0x49
E
0x9e
0x61
0xbe
0x41
F
0x8e
0x71
0xe0
0x1f
“灭”
0x00
0xff
8
0xfe
0x01
“全亮”
硬件是软件的基础。
数码管接收的显示代码就是微控制器数字输出端口的输出数据,两者不同的连接关系将会具有不同的显示代码。
可以尝试采用更为方便的连接关系来组装电路,因为编写显示代码比在电路板上连线方便。
图4.2所示的数码管电路是由图2.1所示的流水灯电路改装来实现,数码管显示的控制程序同样可以由图2.8所示的MSP430系列微控制器开发软件的工作窗口中程序示例为模板写出。
逐个、顺序向P1端口输出寄存器(P1OUT)传送表4.2所示的数码管显示代码就可以实现数字的顺序、循环显示。
仿照图2.8中的程序示例,读者试着编写一个实现字符从0~F连续、循环显示的程序。
4.2.2显示数据的译码
以图2.8中的程序示例为模板写出的数码管显示程序可以实现字符从0~F连续、循环的显示,但是只能按照预先设定的模式进行显示。
如果希望使用数码管显示电路来显示一个测量结果,由于数据不可能事先知道,因此不可能在程序中向端口输出寄存器赋值对应的显示代码。
也不可以将测量数据直接送到端口输出寄存器,因为数据必须转换为对应的显示代码才能驱动数码管,实现希望的数据显示。
程序示例4.1能够自动地将希望显示的数据转换为相应的显示代码,这样就可以驱动数码管,实现数据显示的目的。
程序示例4.1
//程序名称:
seg1_1p
//程序功能:
1个8段共阴极数码管显示
//MSP430与数码管之间通过P1并行数据接口连接
#include<
MSP430.h>
//包含名称定义和对应地址或数据的头函数
constunsignedchardecoder_seg7[18]
={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,
0x9e,0x8e,0x00,0xff};
//共阴极数码管显示代码
//连接关系按表4.1所示
intmain(void)//主函数
{
unsignedchardata_seg7;
//声明显示数据变量
WDTCTL=WDTPW+WDTHOLD;
//关闭看门狗
P1SEL=0x00;
//设置P1端口为并行数字输入/输出口
P1DIR=0xff;
//设置P1端口为输出口
while
(1)//重复执行
{
for(data_seg7=0x00;
data_seg7<
0x10;
data_seg7++)
//利用循环语句产生显示数据
P1OUT=decoder_seg7[data_seg7];
//数据译码,显示代码送P1端口
}
}
对比图2.8所示的MSP430系列微控制器开发软件工作窗口中的程序示例,程序示例4.1在包含语句和主函数之间放置了1个常数表。
关键词“const”声明这个常数表将存储到程序存储器。
关键词“unsignedchar”声明这个常数表中数据的类型,这里为无符号字符型数据类型,也可以理解为无符号8位数据类型。
unsignedchar数据类型的值域为0x00~0xff,或者0~255。
“decoder_seg7”为给这个常数表起的名称。
名称后面中括号中的内容为这个常数表的容量。
主函数中的第1句
unsignedchardata_seg7;
//声明显示数据变量
关键词“unsignedchar”用来声明变量“data_seg7”的数据类型。
使用的数据,包括常量和变量,必须首先声明,然后再使用。
在程序中,通常将声明语句写在前面,将可执行语句写在声明语句的后面。
接着的语句用来关闭“看门狗”,这句的功用在第2章中已经介绍,这里不再重复。
再接着的2条语句涉及并行数字输入/输出端口相关寄存器的配置。
完成驱动数码管的并行数字输入/输出端口P1所需要的配置的语句如下
P1SEL=0x00;
//设置P1端口为并行数字输入/输出口
P1DIR=0xff;
//设置P1端口为输出口
向寄存器P1SEL赋值完成端口P1在并行数字输入/输出管脚,或者外围功能模块管脚之间的选择;
向寄存器P1DIR赋值完成信号传输方向为流出MSP430微控制器芯片,或者流入MSP430微控制器芯片之间的选择。
现在的选择为端口P1用作并行数字输入/输出管脚,信号传输方向从MSP430微控制器芯片流出。
上述配置工作完成以后,当向并行数字输入/输出端口P1的输出寄存器P1OUT写入数据将使得对应的管脚电平发生相应的反应,进而驱动数码管,显示所需要的字符。
在实现重复执行的语句while
(1)中存在一个循环语句。
for(data_seg7=0x00;
这里使用这个循环语句来产生显示数据,模拟希望显示的测量结果。
循环语句起始数据为0,结束数据为F,完成1次循环数据加1。
这样数据循环语句实现显示数据变量data_seg7从0x00到0x0f的顺序、循环变化。
循环体中的语句
P1OUT=decoder_seg7[data_seg7];
//数据译码,显示代码送P1端口
以显示数据变量data_seg7作为地址对常数表decoder_seg7查表。
常数表decoder_seg7中放置着按照图3.2进行连线的共阴极数码管的显示代码。
显示代码按照显示数据从0x00到0x0f的顺序放置,这样显示代码的地址就是它对应的显示数据。
常数表decoder_seg7,即显示代码表,中查出来的显示代码送到并行数字输入/输出端口P1的输出寄存器P1OUT。
由于已经将端口P1配置为普通数字输入/输出端口、数据输出方向,这样端口P1的管脚电平以2进制数据格式反映输出寄存器P1OUT中的内容。
管脚上的电压最终驱动数码管的发光段,显示相应的字符。
从一种数据编码形式转换为另一种数据编码形式的过程通常称为“译码”,程序示例4.1利用查表的方法完成显示数据编码到数码管的显示代码的转换,因此将这样的程序也称为译码程序。
注意,程序示例4.1只能进行模拟调试和单步仿真,不能进行全速仿真,也不能用来对芯片进行编程,因为程序执行的速度太快。
如果MSP430微控制器芯片全速运行程序示例4.1,数码管的所有发光段看起来就像全部都亮起来一样。
4.3延时函数
对于数码管显示,MSP430微控制器芯片的工作速度显得非常快,因此程序示例4.1不能全速运行。
如果在每次向并行数字输入/输出端口P1的输出寄存器P1OUT进行赋值以后,设法延迟一段时间,例如1s左右,然后再进行第二次赋值,这样就能观察到数码管的数字显示情况。
在C语言中,重复使用的语句块都写成函数形式,使得这个语句块能够在程序的不同地方使用。
使用函数能够提高程序存储器的使用效率,同时也简化程序的结构,提高程序的阅读性。
MSP430系列微控制器开发软件中,函数的声明、定义以及函数的调用格式将在本节结合一个可以独立运行的1位数码管演示程序予以说明。
4.3.1延时函数
实现1s左右时间的延迟函数如下。
voiddelay_1s(void)//1s延迟函数
unsignedlongdata_delay;
//声明循环次数变量
//利用循环语句实现时间延迟
for(data_delay=0;
data_delay<
126654;
data_delay++)
{
}
语句
voiddelay_1s(void)//1s延迟函数
中第1个关键词“void”用来声明这个函数无返回值。
“delay_1s”为函数名,函数名可以随便选取,但是不能使用关键词。
括号中的关键词“void”用来声明这个函数无参量,即调用这个函数不需要向函数传递数据。
延迟函数使用循环语句实现时间延迟,虽然现在循环体内部什么都没有做,但是即使空转也需要花费时间。
循环变量data_delay的循环终值控制循环次数。
具体的循环次数可以通过模拟调试获得。
按照所示的循环语句计数终值,调用函数delay_1s可以获得999999个机器周期的时间延迟。
当MSP430系统时钟频率为1MHz时,就可以获得非常接近于1s的时间延迟。
变量在使用之前必须声明,语句
unsignedlongdata_delay;
//声明循环次数变量
声明了变量data_delay,并指出这个变量的数据类型为无符号长整型,unsignedlong。
无符号长整型数据具有32位,取值范围为0~4294967295。
4.3.2函数的使用
在程序示例4.1中,通过使用具有1s左右时间延迟的函数delay_1s(),使得这段程序能够被下载到MSP430微控制器芯片之中,并能够独立运行。
下面的程序示例4.2包含了函数的声明、函数原型以及函数调用。
程序示例4.2
seg71p_delay
//显示数据之间插入1s延迟
//MSP430与数码管之间通过P1并行数据接口
//包含名称定义和对应地址或数据的头函数
voiddelay_1s(void);
//声明1s延迟函数
delay_1s();
//调用1s延迟函数
voiddelay_1s(void)//1s延迟函数
unsignedlongdata_delay;
//声明循环次数变量
for(data_delay=0;
{}
程序示例4.2中,接着包含语句的语句
voiddelay_1s(void);
//声明1s延迟函数
被用来声明延迟函数。
在对显示数据进行译码、并将显示代码送到并行数字输入/输出端口P1的输出寄存器P1OUT的语句之后的语句
delay_1s();
用来调用延迟函数。
由于调用的这个函数没有返回值,因此不需要向变量赋值,可以单独成行。
函数不需要传递参数,因此括号内为空。
程序示例4.2将延迟函数放在主函数之后。
函数也可以放在主函数之前。
如果函数放在主函数之前,这时就不需要在主函数之前对函数进行声明。
对于存在函数的程序调试,使用调试工具“StepInto”(快捷键F11),或者“StepOver”(快捷键F10)是有区别的。
“StepInto”调试工具与“StepOver”调试工具的区别是可以进入其它的函数内部逐条执行,完全描述微控制器内部程序的执行过程。
在被调用函数已经调试通过的情况下,使用工具“StepOver”可以加快调试速度。
程序示例4.2可以被下载到MSP430微控制器芯片,并独立运行。
4.4数据类型
变量在使用之前必须声明其数据类型,便于编译系统为这个变量分配存储空间。
MSP430系列微控制器开发软件支持的数据类型和存储各种数据类型数据占用的存储空间如表4.3所示。
表4.3数据类型和存储各种数据类型数据占用的存储空间
数据类型
值域
存储空间
unsignedchar
0~255
1个字节
signedchar
-128~127
unsignedint
0~65535
2个字节
signedint
-32768~32767
unsignedlong
0~4294967295
4个字节
signedlong
-2147483648~2147483647
float
±
1.176E-38~±
3.40E+38
(具有6位有效数字)
数据类型的选择必须合适,即不能发生数据溢出,也不要浪费存储器资源。
不必要地选择较大值域的数据类型,不仅浪费存储器资源,而且完成同样的运算还会花费过长的时间,这点尤其在选择浮点数数据类型的情况。
通过模拟调试程序示例4.3可以直观地观察到在选择不同的数据类型对存储空间的占用和完成同样的加法运算所花费的时间。
程序示例4.3
operate
检查不同数据类型对运算时间、存储器资源的影响
#include<
msp430.h>
//包含名称定义和对应地址或数据的头函数
intmain(void)//主函数
floatdata_a,data_b,data_c;
//声明显示数据变量
data_a=1