教学内容与重难点
【内容01】利用定时器控制跑马灯的程序设计思路。
【内容02】利用前后台的程序设计思想处理按键与定时中断的逻辑。
【内容03】完成实训项目:基于定时器的跑马灯。
——–学生实践实操,老师讲解演示。
【内容04】专创融合专题。
【重点】实训项目:基于定时器的跑马灯。
【难点】利用前后台的程序设计思想处理按键与定时中断的逻辑。
教学单元核心内容与学习资源
实训案例:基于定时器的跑马灯控制
新建工程,编写代码,在XMF09B/XMF09C开发套件上,完成以下任务:
1-选择内部16MHz时钟的128分频作为计数器1的计数信号。
2-以模模式启动定时器1,进行0.1秒的间隔定时。
3-上电后4个LED灯全部熄灭。第1次按下SW2按键,D4亮,0.5秒后,D3亮,0.5秒后,D6亮,0.5秒后,D5亮,0.5秒后,全部灯灭。第2次按下SW2按键,D5亮,其余灭,0.5秒后,D6亮,其余灭,0.5秒后,D3亮,其余灭,0.5秒后,D4亮,其余灭,0.5秒后,全部灯灭,如此往复。

#define D3 P1_0
#define D4 P1_1
#define D5 P1_3
#define D6 P1_4
#define SW2 P0_1
unsigned int count = 0;
unsigned char F_time = 0;
unsigned char F_key = 0;
/*=====================定时器1初始化函数=======================*/
void Init_Timer1()
{
//1-设置最大计数值 0x30D4,16MHz时钟下定时100ms
T1CC0L = 0xD4;
T1CC0H = 0x30;
//2-开启通道0的比较模式
T1CCTL0 |= 0x04;
//3-使能定时器相应中断控制
T1IE = 1;
EA = 1;
//4-启动定时器1
T1CTL = 0x0E; //0000 1110
}
/*====================定时器1中断服务函数======================*/
#pragma vector = T1_VECTOR
__interrupt void Service_timer1()
{
if(F_time == 1)
{
count++; //0.1秒定时累计
}
}
/*=======================跑马灯控制函数========================*/
void LED_Running()
{
switch(F_key) //选择跑马灯的控制模式
{
case 1: //模式1
if(count == 5)
{
D3 = 1;
}
else if(count == 10)
{
D6 = 1;
}
else if(count == 15)
{
D5 = 1;
}
else if(count == 20)
{
D4 = 0;
D3 = 0;
D6 = 0;
D5 = 0;
F_time = 0;
count = 0;
}
break;
case 2: //模式2
if(count == 5)
{
D6 = 1;
}
else if(count == 10)
{
D3 = 1;
}
else if(count == 15)
{
D4 = 1;
}
else if(count == 20)
{
D4 = 0;
D3 = 0;
D6 = 0;
D5 = 0;
F_time = 0;
count = 0;
F_key = 0;
}
break;
}
}
/*=======================按键扫描处理函数======================*/
void Scan_Keys()
{
if(SW2 == 0)
{
Delay(200); //去抖动处理
if(SW2 == 0) //确认按键按下
{
while(SW2 == 0); //等待按键松开
F_time = 1; //启动0.1秒定时累计
if(F_key == 0) //切换跑马灯控制模式
{
F_key = 1;
D4 = 1;
}
else if(F_key == 1)
{
F_key = 2;
D5 = 1;
}
}
}
}
/*==========================主函数============================*/
void main()
{
Init_Port(); //端口初始化
Init_Timer1(); //定时器1初始化
while(1)
{
Scan_Keys(); //循环扫描按键
LED_Running(); //循环实现跑马灯控制
}
}
