一、任务要求
利用MSP430F247单片机的P4端口控制8个发光二极管D1~D8,发光二极管根据P0口接入的开关完成不同的花样显示变换。
当K1闭合时,LED1和LED2点亮,延迟0.5秒后,LED2和LED3点亮......最后是LED7和LED8点亮。
当K2闭合时,LED1~LED8相当于8位二进制数,延迟0.8秒后,加1并点亮对应的LED。
当K3闭合时,先是LED1~LED4点亮,延迟0.5秒后,LED5~LED8点亮,随后LED1,LED2和LED5、LED6点亮,延迟0.5秒后,LED3、LED4和LED7、LED8逐次点亮,最后LED1、LED3、LED4、LED6点亮,延迟0.5秒后,LED2、LED4、LED6、LED8点亮。
当K4闭合时,先点亮LED1~LED4,然后让LED从右向左移动,当LED8点亮后,下一步重新点亮LED1,依次循环。
当K5闭合时,四个LED同时循环点亮。
二、电路设计
打开Proteus开发环境,新建一个基于MSP430F247单片机的工程。
添加如下元件:单片机MSP430F247,排阻,发光二极管,开关,电阻。
基于Proteus的MSP430单片机仿真实例4-按键控制的花样彩灯
三、程序代码
#include "msp430f247.h"
#include "stdlib.h"
#include "string.h"
/*****************************************软件延时,主频1M*******************/
#define CPU_F1 ((double)1000000)
#define delay_us1M(x) __delay_cycles((long)(CPU_F1*(double)x/1000000.0))
#define delay_ms1M(x) __delay_cycles((long)(CPU_F1*(double)x/1000.0))
/****************************************************************************/
/************************************************
函数名称:主函数
函数功能:彩灯控制
入口参数:无
出口参数:无
************************************************/
main()
{
unsigned char uiLEDValue=0;
unsigned char ucCounter;
unsigned char ucLEDDispaly1=0x80;
unsigned char ucLEDDispaly2=0x01;
unsigned char ucMode=4;
static unsigned char LedState=0x0f;
_DINT(); //关中断
WDTCTL = WDTPW + WDTHOLD;//关看门狗
P4DIR = 0xff;//设置P4端口为输出端口
P4SEL = 0x00;//设置P4端口为普通I/O端口
P4OUT = 0xff;//设置P4端口为输出高电平
while(1)
{
if((P2IN&0x1f) == 0x1e)
{
uiLEDValue = 0x03;
for(ucCounter=0;ucCounter<8;ucCounter++)
{
P4OUT = uiLEDValue;//
uiLEDValue <<= 1;
delay_ms1M(500);
}
}
if((P2IN&0x1f) == 0x1d)
{
P4OUT = ~(uiLEDValue++);//
delay_ms1M(500);
}
if((P2IN&0x1f) == 0x1b)
{
switch(ucMode)
{
case 4:
P4OUT = 0xf0;
delay_ms1M(500);
P4OUT = 0x0f;
delay_ms1M(500);
break;
case 2:
P4OUT = 0xcc;
delay_ms1M(500);
P4OUT = 0x33;
delay_ms1M(500);
break;
case 1:
P4OUT = 0x55;
delay_ms1M(500);
P4OUT = 0xaa;
delay_ms1M(500);
break;
}
ucMode /= 2;
if(ucMode == 0) ucMode = 4;
}
if((P2IN&0x1f) == 0x17)
{
P4OUT = ~(ucLEDDispaly1|ucLEDDispaly2);
ucLEDDispaly1 >>= 1;
ucLEDDispaly2 <<= 1;
delay_ms1M(500);
if((ucLEDDispaly1|ucLEDDispaly2) == 0x00)
{
ucLEDDispaly1 = 0x80;
ucLEDDispaly2 = 0x01;
}
}
if((P2IN&0x1f) == 0x0f)
{
P4OUT = LedState;
delay_ms1M(500);
if(((LedState&0x01) == 0x01) && (LedState != 0x0f))
{
LedState = LedState<<1;
LedState += 1;
}
else
LedState = LedState<<1;
if(LedState == 0xe0) LedState += 1;
}
P4OUT = 0xff;
}
}
四、程序说明
程序利用五个开关是否闭合来控制LED花样显示。循环中利用了多种不同的算法来处理花样显示。
花样1是利用左移来输出两位LED的变换。
花样2利用二进制数直接累加输出给端口的方式虽较为简单,但是显示效果较好。
花样3利用了直接给端口赋值的方式。
花样4利用两个8位的数左移和右移后或运算,得到两个LED相对前进的效果。
花样5是一种蛇行变换方式,利用了左移运算和或运算得到四个LED同时循环点亮的效果。