(一)MSP430f5529 通用I/O口的设置
2021-02-04 来源:eefocus
1. I/O口的简介
特点:
(1)多种复用和设置(即可控制是否输入、是否输出、是否接上下拉电阻、是否可接受中断)
(2)一般情况下,P1和P2都具有中断能力的。从P1和P2接口的各个I/O管脚引入的中断可以独立的被使能并且设置为上升沿或者下降沿触发,对应的中断向量表分别为P1IV和P2IV,他们只能进行字操作,并且PAIV这个寄存器是不存在的。
(3)P1、P2可合为PA,P3、P4可合为PB…。所以P1为8位BCD 0X00,PA为16位BCD 0X0000。当进行字操作写入PA口时,所有的16位都被写入这个端口;当利用字节操作写入PA口的低字节时,高字节保持不变;
(4)由于430很多I/O和外围电路接线,所以这里常用位操作。如事先定义(接下来也会用到,先在此声明),BIT0=0X01、BIT1=0X02、BIT3=0X04…,那么将
P1.1、P1.3---》1(高电平):P1OUT |=(BIT1+BIT3),
P1.1、P1.3---》0(低电平):P1OUT &=~(BIT1+BIT3),
电平翻转即按位异(取反):P1OUT ^=(BIT1+BIT3)。
(5)没有使用到的I/O口,统一拉低,当读入的数据长短小于端口最大长度时,那些没有用到的为会被视为0;
2. I/O口的简单配置(一)
430 I/O的配置是用软件来实现的,是通过相应的配置寄存器来实现的。(用到某个I/O时,一定要先配置好该I/O,否则易出错)
2.1.1 I/O方向设定寄存器PxDIR
如设定P1.1和P1.2为输出状态有以下三种设置模式:
P1DIR |=(BIT1+BIT2)
PADIR |=(BIT1+BIT2)
PADIR_L |=(BIT1+BIT2
== 拉高设定为输出,拉低设定为输入(默认)==
2.1.2 I/O输入设定寄存器PxIN
如设定P1.1和 P1.2的输入为低电平:
P1IN &=~(BIT1+BIT2)。
2.1.3 I/O输出设定寄存器PxOUT
(1)当只用为简单的输出时:如设定P1.1和P1.2输出为高电平:
P1OUT |=(BIT1+BIT2);
(2)如果该引脚为正常I/O功能,且当前已设定为输入方向,且上拉/下拉电阻寄存器是有效的,那么PxOUT可以用来配置上拉和下拉电阻。低电平为下拉电阻,高电平为上拉电阻。
2.1.4 上拉/下拉电阻使能寄存器PxREN
低电平该寄存器无效状态
高电平该寄存器有效状态
2.1.5 输出驱动能力设置寄存器PxDS
弱化驱动可以减弱电磁干扰EMI,全力驱动会增强电磁干扰。默认为减弱驱动。
低电平表示减弱的驱动(默认)。
高电平表示全力的驱动。
2.1.6 功能选择寄存器PxSEL(引脚复用)
用来声明该端口是要应用于外围电路的特殊功能(不决定输入输出方向),默认为低电平。
低电平表示普通的I/O口(默认);如:
P1SEL |=BIT0;
高电平表示该引脚将有连接外围电路的特殊用途。如:
P5SEL |=(BIT2+BIT3)
这句话的意思是声明P5.2和P5.3将有特殊用途,实际上这两个I/O接的是外部的高频时钟晶振(之后还是要设定为输入状态才可以)。此外需要注意的是。一旦某个I/O的PxSEL置高了,那么该引脚将不能再被用为中断引脚。
外部中断应用实例
/*实现LED的闪烁LED位于每个触摸按键的下方,具体接口请查询原理图
#include /** * main.c * 流水灯 */ int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer P1DIR |=(BIT2+BIT3+BIT4);//P1.2、P1.3、P1.4为输出方向 P1OUT &=~(BIT2+BIT3+BIT4);//置零 int i=0,j=0; while(1){ if(i>5) i=0; else{ switch(i){ case 0:break; case 1:break; case 2:P1OUT=0X04;break; case 3:P1OUT=0X08;break; case 4:P1OUT=0X10;break; } } i++; for(j=20000;j>0;j--);//延时 } } 3.通用I/O口的简单配置(二) 外部中断是MSP430优先级最低的中断而且是可屏蔽中断。 3.1.1简单的端口中断(外部中断) (1)P1、P2的所有端口都具有中断能力,可以通过寄存器PxIFG,PxIE和PxIES来配置。其他端口则需要参照具体的引脚说明书。所有的P1中断标志是最优先的(相比其它引脚的外部中断),其中P1IFG.0又最优。 (2)PxIV中断向量寄存器:只有P1IV和P2IV。最高优先级使能中断在P1IV寄存器中产生一个序号,这个数字会被程序计数器识别或者加入其中,然后自动的执行合适的中断服务程序。关闭P1口中断不会影响P1IV寄存器的值。P2口具有相同的功能。PxIV寄存器只能字访问。 (3)PxIFGx中断标志寄存器:只有相应的中断使能PxIE打开且总中断GIE打开,该寄存器才有效。 低电平表示没有中断请求等待响应; 高电平表示有中断请求等待响应; 注意: (1)使用端口的中断功能期间,如果进行PxIN、PxOUT等操作可能使中断变化。 (2)中断标志需要软件清零。有一种情况例外:两个中断同时发生,先响应优先级高的中断,当该中断服务程序结束后,该位的中断标志会自动清零,然后去响应另外一个中断。 PxIE中断使能寄存器 低电平表示中断关闭; 高电平表示中断允许; PxIES中断触发方式选择寄存器 低电平表示上升沿触发; 高电平表示下降沿触发; #include /** * main.c * 采用中断的方式,开关P2.1控制LED--》P1一个一个点亮 */ int s=0;//s用来表示按键次数 int num =0;//num表示LED值 int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer P1DIR=0XFF;//P1全部接输出 P1OUT=0X00;//接LED初始化故全拉低,这样开始灯是灭的 P2DIR=0X00;//P2全部设为输入,因为要接受外部中断 P2IFG=0X00;//清除P2口的中断标志 P2IE=BIT1;//P2.1开启中断 P2IES=0XFF;//P2为下降沿触发 P2IN=BIT1;//P2.1输入拉高,因此开关闭合时会拉低产生下降沿(即中断) P2OUT=0XFF; P2REN=0XFF;//作为输入时配置上拉电阻 __enable_interrupt();//开启中断 while(1){ num=s%5; switch(num){ case 0:P1OUT=0X04;break; case 1:P1OUT=0X08;break; case 2:P1OUT=0X10;break; case 3:P1OUT=0X20;break; case 4:P1OUT=0X40;break; } } } #pragma vector=PORT2_VECTOR//固定格式,声明中断向量地址 __interrupt void Port_2(void) {//中断子程序 unsigned int temp;//局部变量 int i; for(i=0;i<12000;i++);//延时消抖 if((P2IN & 0XFF)!=0XFF){//如果有按键按下 temp=P2IFG;//读取中断标志 P2IFG=0X00;//标志位清零 if(temp==0x02)//如果P2.1产生中断 s++; } }