/***********************************************
程序功能:实现流水灯以三种流动方式和四种流动速度
的不同组合而进行点亮"流动"
------------------------------------------------
测试说明:观察流水灯流动顺序和速度的变化
************************************************/
#include
#include "BoardConfig.h"
uint i = 0,j = 0,dir = 0;
uint flag = 0,speed = 0; //flag--灯光流动方式,speed--灯光流动速度
/****************主函数****************/
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
BoardConfig(0xf0);
CCTL0 = CCIE; //使能CCR0中断
CCR0 = 50000;
TACTL = TASSEL_2 + ID_3 + MC_1; //定时器A的时钟源选择SMCLK,增计数模式
P2DIR = 0xff; //设置P2口方向为输出
P2OUT = 0xff;
_EINT(); //使能全局中断
LPM0; //CPU进入LPM0模式
}
/*******************************************
函数名称:timer_A
功 能:定时器A的中断服务函数,在这里通过标志
控制流水灯的流动方向和流动速度
参 数:无
返回值 :无
********************************************/
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
if(flag == 0)
{
P2OUT = ~(0x80>>(i++)); //灯的点亮顺序D8 -> D1
}
else if(flag == 1)
{
P2OUT = ~(0x01<<(i++)); //灯的点亮顺序D1 -> D8
}
else
{
if(dir) //灯的点亮顺序 D8 -> D1,D1 -> D8,循环绕圈
{
P2OUT = ~(0x80>>(i++));
}
else
{
P2OUT = ~(0x01<<(i++));
}
}
if(i == 8)
{
i = 0;
dir = ~dir;
}
j++;
if(j == 40)
{
i = 0;
j = 0;
flag++;
if(flag == 4) flag = 0;
switch(speed)
{
case 0:
TACTL &=~ (ID0 + ID1);
TACTL |= ID_3;
break;
case 1:
TACTL &=~ (ID0 + ID1);
TACTL |= ID_2;
break;
case 2:
TACTL &=~ (ID0 + ID1);
TACTL |= ID_1;
break;
case 3:
TACTL &=~ (ID0 + ID1);
TACTL |= ID_0;
break;
default:
break;
}
if(flag != 3) speed++;
if(speed == 4) speed = 0;
}
}
/*********************************************
程序功能:MCU控制蜂鸣器演奏歌曲《祝你平安》
----------------------------------------------
测试说明:聆听蜂鸣器“唱出”的乐曲
*********************************************/
#include
#include "BoardConfig.h"
#include "music.h"
#define Buzzer BIT7
#define Buzzer_Port P6OUT
#define Buzzer_DIR P6DIR
uchar counter;
void Play_Song(void);
/***************主函数****************/
void main(void)
{
uchar i;
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
/*------选择系统主时钟为8MHz-------*/
BCSCTL1 &= ~XT2OFF; // 打开XT2高频晶体振荡器
do
{
IFG1 &= ~OFIFG; //清除晶振失败标志
for (i = 0xFF; i > 0; i--); // 等待8MHz晶体起振
}
while ((IFG1 & OFIFG)); // 晶振失效标志仍然存在?
BCSCTL2 |= SELM_2 + SELS; //主时钟和从时钟都选择高频晶振
BoardConfig(0xf8); //关闭数码管、流水灯、电平转换
//设置定时器A每10ms中断一次
CCTL0 = CCIE;
CCR0 = 10000;
TACTL |= TASSEL_2 + ID_3;
//设置控制蜂鸣器的IO方向为输出
Buzzer_DIR |= Buzzer;
//打开全局中断
_EINT();
//循环演奏歌曲
while(1)
{
Play_Song();
}
}
/*******************************************
函数名称:TimerA_ISR
功 能:定时器A的中断服务函数
参 数:无
返回值 :无
********************************************/
#pragma vector = TIMERA0_VECTOR
__interrupt void TimerA_ISR(void)
{
counter++;
}
/*******************************************
函数名称:Delay_Nms
功 能:延时N个ms的函数
参 数:n--延时长度
返回值 :无
********************************************/
void Delay_Nms(uchar n)
{
uchar i,j;
for( i = 0;i < n; i++ )
{
for( j = 0;j < 3;j++ )
_NOP();
}
}
/*******************************************
函数名称:Play_Song
功 能:播放《祝你平安》的乐曲
参 数:无
返回值 :无
********************************************/
void Play_Song(void)
{
uchar Temp1,Temp2;
uchar addr = 0;
counter = 0; //中断计数器清0
while(1)
{
Temp1 = SONG[addr++];
if ( Temp1 == 0xFF ) //休止符
{
TACTL &=~MC_1; //停止计数
Delay_Nms(100);
}
else if ( Temp1 == 0x00 ) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[addr++];
TACTL |=MC_1; //开始计数
while(1)
{
Buzzer_Port ^= Buzzer;
Delay_Nms(Temp1);
if ( Temp2 == counter )
{
counter = 0;
break;
}
}
}
}
}
//《祝你平安》对应的编码
const unsigned char SONG[]=
{
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,
0x10,0x20,0x80,0x26,0x20,0x30,0x20,0x30,0x20,
0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x0,0x20,
0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,
0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,
0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,
0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,
0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x6,0x10,
0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,
0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,
0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,
0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
0x20,0x20,0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,
0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,
0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,
0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,
0x10,0x30,0x20,0x39,0x20,0x26,0x10,0x2b,0x10,
0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,
0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,
0x00
};
/**********************************************
程序功能:在六位数码管上显示六个数字012345
-----------------------------------------------
测试说明:观察数码管显示
***********************************************/
#include
#include "BoardConfig.h"
//数码管7位段码:0--f
uchar scandata[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//记录显示位数的全局变量
uchar cnt = 0;
/********************主函数********************/
void main(void)
{
WDTCTL = WDT_ADLY_1_9; // 设置内部看门狗工作在定时器模式,1.9ms中断一次
IE1 |= WDTIE; // 使能看门狗中断
BoardConfig(0x88);
P4DIR = 0xff; //设置P4,P5的IO方向为输出
P5DIR = 0xff;
P4OUT = 0x00; //设置P4,P5的输出初值
P5OUT = 0xff;
_BIS_SR(LPM3_bits + GIE); //CPU进入LPM3低功耗模式,同时打开全局中断
}
/*******************************************
函数名称:watchdog_timer
功 能:看门狗中断服务函数,在这里输出数码管的
段选和位选信号
参 数:无
返回值 :无
********************************************/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
P5OUT = 0xff;
P4OUT = scandata[cnt]; //输出段选信号
P5OUT &= ~(1 << cnt); //输出位选信号
cnt++; //位计数变量在0~5之间循环
if(cnt == 6) cnt = 0;
}
/***************************************************
程序功能:用扫描方式读取四个独立式按键的键值,同时将
按键的键值在数码管上显示出来
----------------------------------------------------
测试说明:按动K1~k4四个按键,观察数码管显示
***************************************************/
#include
#include "BoardConfig.h"
#define keyin (P1IN & 0x0f)
//数码管7位段码:0--f
uchar scandata[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(void);
/********************主函数********************/
void main( void )
{
uchar temp,keyval = 0;
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
BoardConfig(0x88); //打开数码管,关闭流水灯和电平转换
P1DIR = BIT7; //设置P1.0~P.3为输入状态,P.7为输出
P1OUT = 0;
P3DIR |= BIT4; //设置P3.4为输出状态
P3OUT |= BIT4; //P3.4输出1
P4DIR = 0xff;
P5DIR = 0xff;
P4OUT = 0x3f;
P5OUT = 0xf7;
while(1)
{
if(keyin != 0x0f) //如果有键被按下
{
delay(); //延时消抖
if(keyin != 0x0f) //再次检测按键状态
{
temp=keyin;
while(keyin != 0x0f); //等待按键被放开
switch(temp) //转换键值
{
case 0x0e:
keyval = 1;break;
case 0x0d:
keyval = 2;break;
case 0x0b:
keyval = 3;break;
case 0x07:
keyval = 4;break;
default:
keyval = 0;break;
}
P4OUT = scandata[keyval]; //用一位数码管显示
P3OUT &= ~BIT4; //P3.4连接的LED闪烁一下
delay();delay();
P3OUT |= BIT4;
}
}
}
}
/*******************************************
函数名称:delay
功 能:用于消抖的延时
参 数:无
返回值 :无
********************************************/
void delay(void)
{
uint tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
|