一、任务要求
利用MSP430F247单片机的P4端口控制8个发光二极管D1~D8,实现四种模式的花样彩灯控制:
单个LED左移模式;
单个LED右移模式;
多个LED左移模式;
多个LED右移模式。
每个LED的点亮时间为0.5秒。
二、分析说明
此电路与“基于Proteus的MSP430单片机仿真实例2-彩灯控制”的类似,但是本电路中不需要开关输入,本例的重点在于单片机C语言的算法设计。
三、电路设计
打开Proteus开发环境,新建一个基于MSP430F247单片机的工程。
添加如下元件:单片机MSP430F247,排阻,发光二极管。
四、程序代码
#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))
/****************************************************************************/
#define SHIFT_NUM 8//移位循环次数 8次
enum LED_MODE
{
LEFT_SHIFT_ON,//单个LED左移模式
RIGHT_SHIFT_ON,//单个LED右移模式
LEFT_SHIFT_OFF,//多个LED左移模式
RIGHT_SHIFT_OFF,//多个LED右移模式
};
enum LED_MODE mode;//显示模式选择
/************************************************
函数名称:主函数
函数功能:彩灯控制
入口参数:无
出口参数:无
************************************************/
main()
{
unsigned int uiLEDValue=0x01;
unsigned char ucCounter;
_DINT(); //关中断
WDTCTL = WDTPW + WDTHOLD;//关看门狗
P4DIR = 0xff;//设置P4端口为输出端口
P4SEL = 0x00;//设置P4端口为普通I/O端口
P4OUT = 0xff;//设置P4端口为输出高电平
while(1)
{
for(ucCounter=0;ucCounter < SHIFT_NUM;ucCounter++)
{
switch(mode)
{
case LEFT_SHIFT_ON://单个LED左移模式
uiLEDValue <<= 1;
if(uiLEDValue == 0x100) uiLEDValue = 0x80;//下一个状态的初始值
break;
case RIGHT_SHIFT_ON://单个LED右移模式
uiLEDValue >>= 1;
if(uiLEDValue == 0x00) uiLEDValue = 0x01;//下一个状态的初始值
break;
case LEFT_SHIFT_OFF://多个LED左移模式
uiLEDValue <<= 1;
uiLEDValue |= 1;
if(uiLEDValue == 0x1ff) uiLEDValue = 0x7f;//下一个状态的初始值
break;
case RIGHT_SHIFT_OFF://多个LED右移模式
uiLEDValue >>= 1;
uiLEDValue &= ~0x80;
if(uiLEDValue == 0x00) uiLEDValue = 0x01;//下一个状态的初始值
break;
}
P4OUT = ~uiLEDValue;//LED输出
delay_ms1M(500);//延时
}
mode++;//显示模式转换
mode %= 4;//只有4种显示模式选择
}
}
五、程序说明
程序首先定义了一个枚举类型LED_MODE,定义了4种显示模式,分别是:单个LED左移模式;单个LED右移模式;多个LED左移模式;多个LED右移模式。利用枚举类型定义变量mode,该变量在程序中控制LED显示的方式。
主程序中首先关闭看门狗功能,P4端口输出全部为高电平,关闭所有LED。
主循环中利用for循环控制LED的点亮顺序。循环次数SHIFT_NUM为宏定义,这样的写法可以提高程序的可读性和可移植性。在for循环中首先是单个LED左移模式,uiLEDValue为P4端口输出的值,起始值为0x01,后面的一条语句 P4OUT = ~uiLEDValue;,将uiLEDValue的值取反赋值给P4端口,P4端口输出0xfe,使得p1.0对应的LED点亮,其它LED熄灭,uiLEDValue <<= 1;语句使得每次循环时uiLEDValue左移一位,即uiLEDValue的值从0x01-0x02-0x04-0x08-0x10-0x20-0x40-0x80,再左移一次,uiLEDValue的值变为0x100,注意uiLEDValue变量为无符号整型数据,为16位整数,不会因为移位8次后变为0,这时显示模式应转换为单个LED右移模式,初始值为0x80,。
|