1、利用SysTick定时器编写倒计时程序,如初始设置为2分30秒,每秒在屏幕上输出一次时间,倒计时为0后,红灯亮,停止屏幕输出,并关闭SysTick定时器的中断。
修改main程序
//====================================================================
//文件名称:main.c(应用工程主函数)
//框架提供:SD-Arm(sumcu.suda.edu.cn)
//版本更新:2017.08, 2020.05
//功能描述:见本工程的<01_Doc>文件夹下Readme.txt文件
//====================================================================
#define GLOBLE_VAR
#include "includes.h" //包含总头文件
//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
uint8_t mFlag; //主循环使用的临时变量
uint8_t mSec; //记当前秒的值
//(1.2)【不变】关总中断
DISABLE_INTERRUPTS;
wdog_stop();
//(1.3)给主函数使用的局部变量赋初值
mFlag='A'; //主循环使用的临时变量:蓝灯状态标志
//(1.4)给全局变量赋初值
//"时分秒"缓存初始化(00:00:00)
gTime[0] = 0; //时
gTime[1] = 2; //分
gTime[2] = 30; //秒
mSec = 0; //记住当前秒的值
//(1.5)用户外设模块初始化
gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF); //初始化蓝灯
gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF); //初始化蓝灯
systick_init(10); //设置systick为10ms中断
//(1.6)使能模块中断
//(1.7)【不变】开总中
ENABLE_INTERRUPTS;
printf("------------------------------------------------------\n");
printf("金葫芦提示: \n");
printf(" (1)蓝灯闪烁\n");
printf(" (2)每10ms中断触发SysTick定时器中断处理程序一次。 \n");
printf(" (3)进入SysTick定时器中断处理程序后,静态变量10ms单元+1, \n");
printf(" (4)达到一秒时,调用秒+1,程序,计算“时、分、秒”。 \n");
printf(" (5)使用全局变量字节型数组gTime[3],分别存储“时、分、秒”。 \n");
printf(" (6)可通过时间测试程序C#2019测试30秒的时间间隔来校准Systick \n");
printf(" (7)注意其中静态变量的使用 \n");
printf("------------------------------------------------------\n");
//for(;;) { } //在此打桩,理解蓝色发光二极管为何亮起来了?
//(1)======启动部分(结尾)==========================================
//(2)======主循环部分(开头)=========================================
for(;;) //for(;;)(开头)
{
if (gTime[2] == mSec) continue;
mSec=gTime[2];
//以下是1秒到的处理,灯的状态切换(这样灯每秒闪一次)
//切换灯状态
if(gTime[0]==0 && gTime[1]==0 && gTime[2]==0)
{
gpio_set(LIGHT_BLUE,LIGHT_OFF);
gpio_set(LIGHT_RED,LIGHT_ON); //设置灯“亮”
printf("%d:%d:%d\n",gTime[0],gTime[1],gTime[2]);
DISABLE_INTERRUPTS;
break;
}
else if ( mFlag=='A') //若灯状态标志为'A'
{
gpio_set(LIGHT_BLUE,LIGHT_ON); //设置灯“亮”
printf("%d:%d:%d\n",gTime[0],gTime[1],gTime[2]);
mFlag='L'; //改变状态标志
}
else //否则,若灯状态标志不为'A'
{
gpio_set(LIGHT_BLUE,LIGHT_OFF); //设置灯“暗”
printf("%d:%d:%d\n",gTime[0],gTime[1],gTime[2]);
mFlag='A'; //改变状态标志
}
} //for(;;)结尾
//(2)======主循环部分(结尾)========================================
}
修改handler
//=====================================================================
//文件名称:isr.c(中断处理程序源文件)
//框架提供:SD-ARM(sumcu.suda.edu.cn)
//版本更新:20170801-20191020
//功能描述:提供中断处理程序编程框架
//=====================================================================
#include "includes.h"
//声明使用到的内部函数
//isr.c使用的内部函数声明处
void SecAdd1(uint8_t *p);
//=====================================================================
//函数名称:SYSTICK_USER_Handler(SysTick定时器中断处理程序)
//参数说明:无
//函数返回:无
//功能概要:(1)每10ms中断触发本程序一次;(2)达到一秒时,调用秒+1
// 程序,计算“时、分、秒”
//特别提示:(1)使用全局变量字节型数组gTime[3],分别存储“时、分、秒”
// (2)注意其中静态变量的使用
//=====================================================================
void SysTick_Handler()
{
//printf("***\n");
static uint8_t SysTickCount = 0;
SysTickCount++; //Tick单元+1
wdog_feed(); //看门狗“喂狗”
if (SysTickCount >= 100)
{
SysTickCount = 0;
SecAdd1(gTime);
}
}
//===========================================================================
//函数名称:SecAdd1
//函数返回:无
//参数说明:*p:为指向一个时分秒数组p[3]
//功能概要:秒单元+1,并处理时分单元(00:00:00-23:59:59)
//===========================================================================
void SecAdd1(uint8_t *p)
{
*(p+2)-=1; //秒+1
if(*(p+2)==255) //秒溢出
{
*(p+2)=59; //清秒
*(p+1)-=1; //分+1
if(*(p+1)==255) //分溢出
{
*(p+1)=59; //清分
*p-=1; //时+1
if(*p==255) //时溢出
{
*p=0; //清时
}
}
}
}
代码运行结果:
2、利用RTC显示日期(年月日、时分秒),每秒更新。并设置某个时间的闹钟。闹钟时间到时,屏幕上显示有你的姓名的文字,并点亮绿灯
修改闹钟的中断处理函数,实现亮绿灯及输出姓名
运行结果:
3、利用PWM脉宽调制,交替显示红灯的5个短闪和5个长闪。
初始化PWM
五次长闪和短闪交替实现,其中长闪是利用Delay_ms函数来实现的
运行结果:
4、GEC39定义为输出引脚,GEC10定义为输入引脚,用杜邦线将两个引脚相连,验证捕捉实验程序Incapture-Outcmp-20211110,观察输出的时间间隔。
用杜邦线将39和10两个引脚相连,并运行程序