大学嵌入式系统课程学习记录(五)

1、利用SysTick定时器编写倒计时程序,如初始设置为2分30秒,每秒在屏幕上输出一次时间,倒计时为0后,红灯亮,停止屏幕输出,并关闭SysTick定时器的中断。

程序源码:

main.c:

#define GLOBLE_VAR
#include "includes.h"      //包含总头文件

//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程见书稿)
int main(void)
{
    //关总中断
    DISABLE_INTERRUPTS;
    wdog_stop();
    
   	//"时分秒"缓存初始化(00:02:30)
   	gTime[0] = 0;       //时
   	gTime[1] = 2;	 	//分
   	gTime[2] = 30;	 	//秒
 
    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);
    gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);
    gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);    //初始化灯,全灭
    
    //初始化 SysTick
    SysTick->CTRL = 0;	//清零,包括禁止中断以及计时
    SysTick->LOAD = SystemCoreClock * 0.1;	//写入重载值,计时时长为0.1秒
    SysTick->VAL = 999UL;	//清除当前值
    while(SysTick->VAL != 0);	//等待 SysTick 当前值清零完成
    printf("SysTick 当前值:%d\n", SysTick->VAL);
    SysTick->CTRL |= (1UL << 2U);	//选择内核时钟
    SysTick->CTRL |= (1UL << 1) | 1UL;	//使能 SysTick 中断和计时
    
    //开总中断
    ENABLE_INTERRUPTS;
    
    printf("LH,32106100047\n");
    printf("倒计时:%d:%d:%d\n",gTime[0],gTime[1],gTime[2]);
    gpio_set(LIGHT_BLUE,LIGHT_ON);   //设置蓝灯亮。
 
    //主循环部分
    for(;;)
    {
    }
}

isr.c:

void SysTick_Handler()
{
	static uint8_t SysTickCount = 0; // 静态变量,记录SysTick中断次数
	SysTickCount++;		// Tick单元+1
	wdog_feed();		// 喂狗,重置看门狗计时器
	if (SysTickCount >= 10) // 如果SysTickCount达到10次(即10ms)
	{
		SysTickCount = 0; // 重置SysTickCount
		if(gTime[2] == 0) // 如果秒数为0
		{
			if(gTime[1] == 0) // 如果分钟数为0
			{
				if(gTime[0] == 0) // 如果小时数为0
				{
					printf("倒计时结束,红灯亮\n"); // 输出倒计时结束,红灯亮
					gpio_set(LIGHT_BLUE,LIGHT_OFF);	// 设置蓝灯暗
					gpio_set(LIGHT_RED,LIGHT_ON);		// 设置红灯亮
					SysTick->CTRL = 0;					// 关闭SysTick定时器
					printf("LH,32106100047\n"); // 输出标识符
					return; // 结束函数
				}
				gTime[0]--; // 小时数减1
				gTime[1] = 59U; // 分钟数重置为59
			}
			gTime[1]--; // 分钟数减1
			gTime[2] = 59U; // 秒数重置为59
		}
		else
		{		
			gTime[2]--; // 秒数减1
		}
		printf("倒计时:%d:%d:%d\n",gTime[0],gTime[1],gTime[2]); // 输出当前倒计时时间
		if((gTime[2] % 2) == 0) // 如果当前秒数为偶数
		{
			gpio_set(LIGHT_BLUE,LIGHT_ON);		// 设置蓝灯亮
		}
		else
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF);	// 设置蓝灯暗
		}
	}
}

运行结果:

顺利地编写了倒计时程序。


2、利用RTC显示日期(年月日、时分秒),每秒更新。并设置某个时间的闹钟。闹钟时间到时,屏幕上显示有你的姓名的文字,并点亮绿灯。

main.c:

//(1.4)给全局变量赋初值
    g_RTC_Flag=0;
//(1.5)用户外设模块初始化
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON);	//初始化蓝灯
uart_init(UART_User,115200);
    RTC_Init();         //RTC初始化
	RTC_Set_Time(11,17,00);         //设置时间为11:17:0
    RTC_Set_Date(24,6,7,5);         //设置日期
//(1.6)使能模块中断
    RTC_PeriodWKUP_Enable_Int();                               //使能唤醒中断
    uart_enable_re_int(UART_User);
    RTC_Alarm_Enable_Int(0);

	RTC_Set_Alarm(0,5,11,18,0);     //设置闹钟时间为11:18:0
//(1.7)【不变】开总中断
	ENABLE_INTERRUPTS;
    RTC_Set_PeriodWakeUp(1);                            //配置WAKE UP中断,每秒中断一次

isr.c:

void RTC_Alarm_IRQHandler(void)
{
	
	if(RTC_Alarm_Get_Int(A))            //闹钟A的中断标志位
	{
		gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);
		RTC_Alarm_Clear(A);       //清闹钟A的中断标志位
		printf("闹钟触发\n");
		gpio_set(LIGHT_GREEN,LIGHT_ON);
		printf("LH-32106100047\n");
	}
}

运行后结果:

闹钟可以正确触发

3、利用PWM脉宽调制,交替显示红灯的5个短闪和5个长闪。

main.c:

gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);    //初始化红灯
    pwm_init(PWM_USER,1500,1000,10.0,PWM_CENTER,PWM_MINUS);   //PWM输出初始化
    
    //(1.6)使能模块中断
    
    //(1.7)【不变】开总中断
    ENABLE_INTERRUPTS;
   m_K=0;
    m_duty=20.0;
    uint8_t flag = 1;
    uint8_t i=1;
// 无限循环
for (;;)
{
    // 更新 PWM(脉冲宽度调制)信号,设置占空比为 m_duty
    pwm_update(PWM_USER, m_duty);
    // 将占空比每次递增5
    m_duty = m_duty + 5.0;
    // 当占空比大于等于90后置为1,重新进行循环。
    if (m_duty >= 90.0)
        m_duty = 1.0;
    // 循环执行3次,控制未知周期内相同占空比的波形只打印三次
    for (m_i = 0; m_i < 3; m_i++)
    {
        // 重置 m_K,以确保每次输出完整的 PWM 波形后再进入下一个循环
        m_K = 0;
        do
        {
            // 获取 PWM_USER 端口的状态标志
            mFlag = gpio_get(PWM_USER);
            // 如果当前状态为高电平且之前状态也为高电平
            if ((mFlag == 1) && (Flag == 1))
            {
                // 将标志位 Flag 设为低电平
                Flag = 0;
                // m_K 自增
                m_K++;
                // 小灯反转
                gpio_reverse(LIGHT_RED);
                // 如果 flag 等于 1
                if (flag == 1)
                {
                    // 延时 1000 毫秒
                    Delay_ms(1000);
                    // 打印长闪信息,并增加 i
                    printf("第%d次长闪\n", i);
                    // flag 设为 0
                    flag = 0;
                    // 继续执行循环
                    continue;
                }
                // flag 设为 1
                flag = 1;
                // 打印短闪信息,并增加 i
                printf("第%d次短闪\n", i);
                i++;
            }
            // 如果当前状态为低电平且之前状态也为低电平
            else if ((mFlag == 0) && (Flag == 0))
            {
                // 将标志位 Flag 设为高电平
                Flag = 1;
                // m_K 自增
                m_K++;
                // 反转小灯状态
                gpio_reverse(LIGHT_RED);
            }
        }
        // 等待直到输出完整的 PWM 波形
        while (m_K < 1);
    }
}

运行后结果:

4、GEC39定义为输出引脚,GEC10定义为输入引脚,用杜邦线将两个引脚相连,验证捕捉实验程序Incapture-Outcmp-20211110,观察输出的时间间隔。

用杜邦线连接开发板上的39和10孔

运行捕捉实验程序Incapture-Outcmp-20211110

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值