05嵌入式第四章作业

1、学习CH04示例程序,包括gpio.c和4个工程中的main.c


2、给出 gpio set(LIGHT _RED,LIGHT_OFF);语句中LIGHT RED和LIGHT OFF的值是多少?贴出每一步的查找截图

LIGHT_RED  和  LIGHT_OFF在..\CH04\GPIO-Output-Component\05_UserBoard\User.h中定义

可以看到#define  LIGHT_RED    (PTB_NUM|7)  //红灯,(GEC_56)其中PTB_NUM为端口号地址偏移量,在gpio.h可以看到其定义

可得PTB_NUM的值为 0B 1 0000 0000

故LIGHT_RED为0B 1 0000 0111

LIGHT_OFF为0B 0000 0001

3、用直接地址编程方式,实现红绿蓝三灯轮流闪烁

在..\CH04\GPIO-Output-DirectAddress_STM32L431_20200928的工程中的main.c中修改实现

  • 设置状态标志mFlag,其中'R'为红色,'G'为绿色,‘B’为蓝色,'L'为灯暗,初始化为R红色
  • B端口7、8、9引脚分别代表红、绿、蓝,将以上引脚都设置为01:通用输出模式
  • 根据状态标志mFlag的不同,使用gpio_brr复位寄存器,将对应引脚设置为低电平,即点亮该灯
  • 当红、绿、蓝三种灯都亮了一轮之后,使用gpio_bsrr将所有引脚都置为高电平,即将所有灯熄灭,此时置mFlag为‘L’,接着继续循环红、绿、蓝、灯暗
#define GLOBLE_VAR
#include "includes.h" 

int main(void)
{
    //(1)======启动部分(开头)==========================================
    //(1.1)声明main函数使用的局部变量
    uint32_t mMainLoopCount;  //主循环使用的记录主循环次数变量
    uint8_t  mFlag;            //主循环使用的临时变量
    
    //(1.2)【不变】关总中断
    DISABLE_INTERRUPTS;

    
    //(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount = 0;     //主循环使用的记录主循环次数变量
    mFlag='R';              //主循环使用的临时变量,'R'红色,'G'绿色,'B'蓝色
    
    //(1.4)给全局变量赋初值
    
    //(1.5)用户外设模块初始化
    // B口7脚(红灯,低电平点亮)
    // B口8脚(绿灯,低电平点亮)
    // B口9脚(蓝灯,低电平点亮)

    //(1.5.1)声明变量
    volatile uint32_t* RCC_AHB2;    //GPIO的B口时钟使能寄存器地址
    volatile uint32_t* gpio_ptr;    //GPIO的B口基地址
    volatile uint32_t* gpio_mode;   //引脚模式寄存器地址=口基地址  0x 4800 0400 UL
	volatile uint32_t* gpio_bsrr;   //置位/复位寄存器地址
	volatile uint32_t* gpio_brr;    //GPIO位复位寄存器

	//(1.5.2)变量赋值
    RCC_AHB2=(uint32_t*)0x4002104C;   //GPIO的B口时钟使能寄存器地址
	gpio_ptr=(uint32_t*)0x48000400;   //GPIO的B口基地址
	gpio_mode=gpio_ptr;    //引脚模式寄存器地址=口基地址
    gpio_bsrr=gpio_ptr+6;  //置位/复位寄存器地址
    gpio_brr=gpio_ptr+10;  //GPIO位复位寄存器

    //(1.5.3)GPIO初始化
    //(1.5.3.1)使能相应GPIOB的时钟
    *RCC_AHB2|=(1<<1);       //GPIOB的B口时钟使能
    
    // (1.5.3.1)设置 B7、B8、B9 引脚为 01:通用输出模式
    //  定义B口7脚为输出引脚(令D15、D14=01)
    *gpio_mode &= ~(3<<14); //15,14位 置0 
    *gpio_mode |=(1<<14);   //14位置1 

    //  定义B口8脚为输出引脚(令D17、D16=01)
    *gpio_mode &= ~(3<<16); //16,17位 置0 
    *gpio_mode |=(1<<16);   //16位置1

    //  定义B口9脚为输出引脚(令D19、D18=01)
    *gpio_mode &= ~(3<<18);  
    *gpio_mode |=(1<<18);   
    
    //(1.6)使能模块中断

    //(1.7)【不变】开总中断
    ENABLE_INTERRUPTS;
    
    printf("-----------------------------------------------------\r\n"); 
    printf("用直接地址编程方式,实现红绿蓝三灯轮流闪烁\r\n"); 
    printf("   广州大学--cqh\r\n");
    printf("----------------------------------------------------\r\n"); 
   
    //(1)======启动部分(结尾)==========================================
    
    //(2)======主循环部分(开头)=========================================
    for(;;)     //for(;;)(开头)
    {
        
        //(2.1)主循环次数+1,并判断是否小于特定常数
        mMainLoopCount++;                         //+1
        if (mMainLoopCount<=6556677)  continue;   //如果小于特定常数,继续循环
        //(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)
        mMainLoopCount=0;      //清主循环次数
        
        // 根据当前灯的状态标志切换灯状态
        switch (mFlag) {
            case 'R': 
                *gpio_brr |= (1 << 7);  //设置红灯亮
                printf("红灯:亮\r\n");
                mFlag = 'G'; //标志改为绿灯
                break;

            case 'G': 
                *gpio_brr |= (1 << 8);  //设置绿灯亮
                printf("绿灯:亮\r\n");
                mFlag = 'B';  //标志改为蓝灯
                break;

            case 'B':  // 蓝灯
                *gpio_brr |= (1 << 9);  // 点亮蓝灯
                printf("蓝灯:亮\r\n");
                mFlag = 'L';  // 灭灯
                break;

            case 'L':  // 灭灯
				*gpio_bsrr |= ((1 << 7) | (1 << 8) | (1 << 9));  // 设置灯暗
        		printf("所有灯暗\r\n\n");
                mFlag = 'R';  // 切换到红灯 循环
                break;
        }

    }    
}

4、用调用构件方式,实现红绿蓝的八种组合轮流闪烁

在..\CH04\GPIO-Output-Component_STM32L431_20200928中修改main.c函数实现

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

//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处
void Delay_ms(uint16_t u16ms);

//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
    //(1)======启动部分(开头)==========================================
    //(1.1)声明main函数使用的局部变量
    uint32_t mCount;			//延时的次数

    //(1.2)【不变】关总中断
    DISABLE_INTERRUPTS;
    
    //(1.3)给主函数使用的局部变量赋初值
    mCount=0;//记次数
    
    //(1.4)给全局变量赋初值
    
    //(1.5)用户外设模块初始化
    gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯
    gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);	//初始化绿灯
    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);	//初始化红灯

    uart_init(UART_User,115200);     //初始化串口模块
    
    //(1.6)使能模块中断
    uart_enable_re_int(UART_User);
    
    //(1.7)【不变】开总中断
    ENABLE_INTERRUPTS;
    
    printf("-----------------------------------------------------\r\n"); 
    printf("用调用构件方式,实现红绿蓝的八种组合轮流闪烁\r\n"); 
    printf("   广州大学--cqh\r\n");
    printf("----------------------------------------------------\r\n"); 
    
    //(1)======启动部分(结尾)==========================================
    
    //(2)======主循环部分(开头)========================================
    //每5秒变换一种颜色,一个循环共40秒
    for(;;)   //for(;;)(开头)
    {
        //延时1秒
        Delay_ms(1000);
        mCount++;
        //当秒数40秒时,重新开始计数
        //避免一直累加
        if (mCount > 40)
        {
            mCount=1;
        }
        if(mCount%5==0)
        {
          gpio_reverse(LIGHT_RED);
          printf(" LIGHT_RED:reverse--\n");   //串口输出灯的状态
          if(mCount/5==1)
          {
            printf("指示灯颜色为【红色】\n");
           }
           else if(mCount/5==3)
           {
            printf("指示灯颜色为【黄色】\n");
           }
           else if(mCount/5==5)
           {
            printf("指示灯颜色为【紫色】\n");
           }
           else if(mCount/5==7)
           {
            printf("指示灯颜色为【白色】\n");
           }
        }
        if (mCount%10==0)                    //判断灯的状态标志
        {
            gpio_reverse(LIGHT_GREEN);
            printf(" LIGHT_GREEN:reverse--\n");   //串口输出灯的状态
            if(mCount/10==1)
            {
             printf("指示灯颜色为【绿色】\n");
            }
            else if(mCount/10==3)
           {
            printf("指示灯颜色为【青色】\n");
           }
        }
        if (mCount%20==0)                    //判断灯的状态标志
        {
            gpio_reverse(LIGHT_BLUE);				
            printf(" LIGHT_BLUE:reverse--\n");   //串口输出灯的状态
            if(mCount/20==1)
            {
            printf("指示灯颜色为【蓝色】\n");
            }
            else if(mCount/20==2)
           {
            printf("指示灯颜色为【暗色】\n");
           }
        }
        
    }  //for(;;)结尾
    //(2)======主循环部分(结尾)========================================
}   //main函数(结尾)


//======以下为主函数调用的子函数===========================================
//======================================================================
//函数名称:Delay_ms
//函数返回:无
//参数说明:近似毫秒
//功能概要:延时 - 毫秒级
//======================================================================
void Delay_ms(uint16_t u16ms)
{
    for(volatile uint32_t i = 0; i < 8000*u16ms; i++) __asm("NOP");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值