嵌入式第七章作业

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

#define GLOBLE_VAR
#include "includes.h" 
int main(void)
{
    uint8_t mSec; // 记当前秒的值
    DISABLE_INTERRUPTS;
    wdog_stop();
    gTime[0] = 0;    // 时
    gTime[1] = 2;    // 分
    gTime[2] = 30;   // 秒
    mSec = gTime[2]; // 记住当前秒的值
    gpio_init(LIGHT_RED, GPIO_OUTPUT, LIGHT_OFF); // 初始化红灯暗
    systick_init(10);                             // 设置systick为10ms中断
    ENABLE_INTERRUPTS;
    printf("                GZHU 32106100165 MYJ                  \n");
    for (;;)
    {
        if (gTime[2] == mSec)
            continue;
        mSec = gTime[2];
        printf("%d:%d:%d\n", gTime[0], gTime[1], gTime[2]);
        if (gTime[0] == 0 && gTime[1] == 0 && gTime[2] == 0)
        {
            gpio_set(LIGHT_RED, LIGHT_ON); // 设置灯“亮”
            systick_close();
            printf("红灯亮!");
            break;
        }
    }
}

#include "includes.h"
void SecSub1(uint8_t *p);
void SysTick_Handler()
{
    static uint8_t SysTickCount = 0;
    SysTickCount++; // Tick单元+1
    wdog_feed();    // 看门狗“喂狗”
    if (SysTickCount >= 100)
    {
        SysTickCount = 0;
        SecSub1(gTime);
    }
}
void SecSub1(uint8_t *p)
{
    *(p + 2) -= 1; // 秒-1
    if (*(p + 2) <= 0)
    {
        if (*(p + 1) <= 0)
        { // 计时结束
            return;
        }
        *(p + 2) = 60; // 重置为60秒
        *(p + 1) -= 1; // 分-1
        if (*(p + 1) <= 0)
        {
            if (*p <= 0)
            {
                return;
            }
            *(p + 1) = 60; // 清分
            *p -= 1;       // 时-1
            if (*p <= 24)
            {
                return;
            }
        }
    }
}

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

#define GLOBLE_VAR
#include "includes.h"

int main(void)
{
    uint32_t mMainLoopCount; // 主循环次数变量
    DISABLE_INTERRUPTS;
    mMainLoopCount = 0; // 主循环次数变量
    g_RTC_Flag = 0;
    gpio_init(LIGHT_GREEN, GPIO_OUTPUT, LIGHT_OFF); // 初始化蓝灯
    uart_init(UART_User, 115200);
    RTC_Init();               // RTC初始化
    RTC_Set_Time(13, 11, 13); // 设置时间为0:0:0
    RTC_Set_Date(1, 1, 1, 1); // 设置日期
    RTC_PeriodWKUP_Enable_Int();   // 使能唤醒中断
    uart_enable_re_int(UART_User); // 使能接收中断
    RTC_Alarm_Enable_Int(0);       // 使能闹钟中断
    ENABLE_INTERRUPTS;
    RTC_Set_PeriodWakeUp(1);         // 配置WAKE UP中断,每秒中断一次
    RTC_Set_Alarm(0, 1, 13, 11, 53); // 配置闹钟时间
    printf(" GZHU 32106100165 MYJ \n");
    for (;;)
    {
        mMainLoopCount++;
        if (mMainLoopCount <= 12888999)
            continue;
        mMainLoopCount = 0;
        if (g_RTC_Flag == 1) // 根据串口接收的数据设置基准时间
        {
            g_RTC_Flag = 0;
            gcRTC_Date_Time.Year = (uint8_t)((gcRTCBuf[1] - '0') * 10 + (gcRTCBuf[2] - '0'));
            gcRTC_Date_Time.Month = (uint8_t)((gcRTCBuf[4] - '0') * 10 + (gcRTCBuf[5] - '0'));
            gcRTC_Date_Time.Date = (uint8_t)((gcRTCBuf[7] - '0') * 10 + (gcRTCBuf[8] - '0'));
            gcRTC_Date_Time.Hours = (uint8_t)((gcRTCBuf[10] - '0') * 10 + (gcRTCBuf[11] - '0'));
            gcRTC_Date_Time.Minutes = (uint8_t)((gcRTCBuf[13] - '0') * 10 + (gcRTCBuf[14] - '0'));
            gcRTC_Date_Time.Seconds = (uint8_t)((gcRTCBuf[16] - '0') * 10 + (gcRTCBuf[17] - '0'));
            gcRTC_Date_Time.Weekday = (uint8_t)((gcRTCBuf[23] - '0'));
            RTC_Set_Time(gcRTC_Date_Time.Hours, gcRTC_Date_Time.Minutes, gcRTC_Date_Time.Seconds);                    // 设置时间
            RTC_Set_Date(gcRTC_Date_Time.Year, gcRTC_Date_Time.Month, gcRTC_Date_Time.Date, gcRTC_Date_Time.Weekday); // 设置日期
        }
    }
}

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

#define GLOBLE_VAR
#include "includes.h" 
int main(void)
{
    uint8_t  mFlag;           //灯的状态标志
    uint8_t Flag;             //希望采集的电平高低标志
    double  m_duty;          //占空比
    uint32_t m_i;           //控制在未知周期内不同占空比的波形只打印有限次
    uint8_t m_K;           //确保每次能正确打印输出PWM波形
    DISABLE_INTERRUPTS;
    Flag=1;      
    mFlag=0;     //灯的状态标志
    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);    //初始化红灯暗
    pwm_init(PWM_USER,1500,1000,10.0,PWM_CENTER,PWM_MINUS);   //PWM输出初始化
    ENABLE_INTERRUPTS;
    printf(" GZHU 32106100165 MYJ\n");
    m_K=0;
    m_duty=10.0;  //占空比设置为10%
    for(;;)  
    {
        pwm_update(PWM_USER,m_duty);         //调节占空比
        for (m_i=0;m_i<10;m_i++)            //m_i<10为了控制小灯闪烁5次
        {
            m_K=0;                        //保证每次输出打印完整的PWM波,再进入下一个循环                 
            do 
            {
                mFlag=gpio_get(PWM_USER); //获取灯的状态标志
                if ((mFlag==1)&&(Flag==1))
                {
                    printf("高电平:1\n");
                    Flag=0;
                    m_K++;
                    gpio_reverse(LIGHT_RED);//小灯反转
                }
                else if ((mFlag==0)&&(Flag==0))
                {
                    printf("低电平:0\n");
                    Flag=1;
                    m_K++;
                    gpio_reverse(LIGHT_RED);
                }
                
            }
            while (m_K<1);
        }
        m_duty = 100.0-m_duty; //不断循环每5次灯闪烁调节占空比
    }
}

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

#define GLOBLE_VAR
#include "includes.h" 
void Delay_ms(uint16_t u16ms);

int main(void)
{
    uint8_t mFlag; // 灯的状态标志
    uint8_t flag;  // 标记高低电平
    DISABLE_INTERRUPTS;
    mFlag = 'A'; // 灯的状态标志
    gTime[0] = 0;  // 分钟
    gTime[1] = 0;  // 秒
    gTime[2] = 0;  // 毫秒
    period = 1000; // 自动重装载寄存器初始值
    gpio_init(LIGHT_BLUE, GPIO_OUTPUT, LIGHT_ON);       // 初始化蓝灯
    outcmp_init(OUTCMP_USER, 3000, 200, 50.0, CMP_REV); // 输出比较初始化
    incapture_init(INCAP_USER, 375, 1000, CAP_DOUBLE);  // 上升沿捕捉初始化
    systick_init(1);                                    // 设置systick为1ms中断
    cap_enable_int(INCAP_USER); // 使能输入捕捉中断
    ENABLE_INTERRUPTS;
    printf("------------------------------------------------------\n");
    printf("金葫芦提示:                                           \n");
    printf(" (1)蓝灯每秒闪烁一次,作为运行指示\n");
    printf(" (2)设置GEC39为输出比较引脚,\n");
    printf("      设置GEC10为输入捕捉引脚,沿跳变捕捉\n");
    printf(" (3)用导线将GEC39与GEC10连接 \n");
    printf(" (4)程序使得输出比较引脚输出高低电平,输入捕捉引脚捕捉\n");
    printf("      后用printf输出,PC机程序据此显示波形引脚捕捉\n");
    printf("-----GZHU 32106100165 MYJ-----\n");
    for (;;) // for(;;)(开头)
    {
        flag = gpio_get(INCAP_USER);
        // 灯状态标志mFlag为'L',改变灯状态及标志
        if (mFlag == 'L' && flag == 1) // 判断灯的状态标志
        {
            mFlag = 'A';                    // 灯的状态标志
            gpio_set(LIGHT_BLUE, LIGHT_ON); // 灯“亮”
        }
        // 如灯状态标志mFlag为'A',改变灯状态及标志
        else if (mFlag == 'A' && flag == 0) // 判断灯的状态标志
        {
            mFlag = 'L';                     // 灯的状态标志
            gpio_set(LIGHT_BLUE, LIGHT_OFF); // 灯“暗”
        }
    } // for(;;)结尾
}

void Delay_ms(uint16_t u16ms)
{
    uint32_t u32ctr;
    for (u32ctr = 0; u32ctr < 8000 * u16ms; u32ctr++)
    {
        __ASM("NOP");
    }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值