第四章作业

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

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

LIGHT_RED的值为(PTB_NUM|7)

LIGHT_OFF的值是 1   

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

修改文件GPIO-Output-DirectAddress_STM32L431_20200928的代码。

由书中可得绿和红灯引脚

查找文件,修改模式

   //(1.5.3.1)定义B口9脚为输出引脚(令D19、D18=01)方法如下:蓝灯

    *gpio_mode &= ~(3<<18);  //0b11111111111100111111111111111111;

    *gpio_mode |=(1<<18);    //0b00000000000001000000000000000000;

    // 1.5.3.1)定义B口8脚为输出引脚(令D17、D16=01)方法如下:绿灯

    *gpio_mode &= ~(3<<16);   

    *gpio_mode |=(1<<16);     

     //1.5.3.1)定义B口7脚为输出引脚(令D15、D14=01)方法如下: 红灯

    *gpio_mode &= ~(3<<14);   

*gpio_mode |=(1<<14);   

修改代码,在循环前关闭所有灯

//====================================================================

//文件名称: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函数使用的局部变量

    uint32_t mMainLoopCount;  //主循环使用的记录主循环次数变量

    uint8_t  mFlag;            //主循环使用的临时变量

    

    //(1.2)【不变】关总中断

    DISABLE_INTERRUPTS;



    

    //(1.3)给主函数使用的局部变量赋初值

    mMainLoopCount = 0;     //主循环使用的记录主循环次数变量

    mFlag='A';              //主循环使用的临时变量:蓝灯状态标志

    

    //(1.4)给全局变量赋初值

    

    //(1.5)用户外设模块初始化

    // B口9脚(蓝灯,低电平点亮)

    //(1.5.1)声明变量

    volatile uint32_t* RCC_AHB2;    //GPIO的B口时钟使能寄存器地址

    volatile uint32_t* gpio_ptr;    //GPIO的B口基地址

    volatile uint32_t* gpio_mode;   //引脚模式寄存器地址=口基地址

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)定义B口9脚为输出引脚(令D19、D18=01)方法如下:蓝灯

    *gpio_mode &= ~(3<<18);  //0b11111111111100111111111111111111;

    *gpio_mode |=(1<<18);    //0b00000000000001000000000000000000;

    

    // 1.5.3.1)定义B口8脚为输出引脚(令D17、D16=01)方法如下:绿灯

    *gpio_mode &= ~(3<<16);   

    *gpio_mode |=(1<<16);     

    

     //1.5.3.1)定义B口7脚为输出引脚(令D15、D14=01)方法如下: 红灯

    *gpio_mode &= ~(3<<14);   

    *gpio_mode |=(1<<14);    

    //(思考:为什么这样赋值?答案见本文件末尾注①)

    

    //(1.6)使能模块中断



    //(1.7)【不变】开总中断

    ENABLE_INTERRUPTS;

    

    printf("-----------------------------------------------------\r\n");

    printf("金葫芦提示:直接地址方式进行GPIO输出\r\n");

    printf("    这个编程有点难以看懂,使用构件编程就简单多了,\r\n");

    printf("    但是构件制作要经过这一关,因此,我们把构件制作与\r\n");

    printf("    基于构件的编程分成不同过程。学习嵌入式系统,\r\n");

    printf("    以理解GPIO、UART、定时器、Flash、ADC、...\r\n");

    printf("    知识要素为出发点,学会正确运用构件进行应用编程,\r\n");

    printf("    理解和掌握2~3个简单构件的制作方法即可。\r\n");

    printf("----------------------------------------------------\r\n");

    

    //for(;;) {  }     //在此打桩,理解蓝色发光二极管为何亮起来了?

    

    //(1)======启动部分(结尾)==========================================

    

    //(2)======主循环部分(开头)=========================================

    for(;;)     //for(;;)(开头)

    {

        

        //(2.1)主循环次数+1,并判断是否小于特定常数

        mMainLoopCount++;                         //+1

        if (mMainLoopCount<=6556677)  continue;   //如果小于特定常数,继续循环

        //(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)

        mMainLoopCount=0;      //清主循环次数

        //切换灯状态

        if (mFlag=='A')   //若灯状态标志为'A'

        {

         *gpio_bsrr|=(1<<9);

         *gpio_bsrr|=(1<<8);

         *gpio_bsrr|=(1<<7); 

         *gpio_brr|=(1<<8);     

         printf("绿灯:亮\r\n");  //通过调试串口输出灯的状态

            mFlag='B';             //改变状态标志

        }

        else   if      (mFlag=='B')         
        {

             *gpio_bsrr|=(1<<9);

       *gpio_bsrr|=(1<<8);

       *gpio_bsrr|=(1<<7);

       *gpio_brr|=(1<<9);    
  
        printf("蓝灯:亮\r\n");   //通过调试串口输出灯的状态
   
            mFlag='C';              //改变状态标志

        }

          else            //否则,若灯状态标志不为'A'    

        {

             *gpio_bsrr|=(1<<9);

     *gpio_bsrr|=(1<<8);

     *gpio_bsrr|=(1<<7);

     *gpio_brr|=(1<<7);    

            printf("红灯:亮\r\n");   //通过调试串口输出灯的状态

            mFlag='A';              //改变状态标志

        }

    }     //for(;;)结尾

    //(2)======主循环部分(结尾)========================================

}

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

 

修改GPIO-Output-Component_STM32L431_20200928初始化三种颜色的灯,再设置每种灯的颜色

//======================================================================
//文件名称:main.c(应用工程主函数)
//框架提供:SD-Arm(sumcu.suda.edu.cn)
//版本更新:20191108-20200419
//功能描述:见本工程的..\01_Doc\Readme.txt
//移植规则:【固定】
//======================================================================
#define GLOBLE_VAR
#include "includes.h"      //包含总头文件

//----------------------------------------------------------------------
//声明使用到的内部函数
//main.c使用的内部函数声明处

//----------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
int main(void)
{
//(1)======启动部分(开头)==========================================
//(1.1)声明main函数使用的局部变量
	uint32_t mMainLoopCount;  //主循环次数变量
	uint8_t  mFlag;           //灯的状态标志
	uint32_t mLightCount;     //灯的状态切换次数

//(1.2)【不变】关总中断
	DISABLE_INTERRUPTS;

//(1.3)给主函数使用的局部变量赋初值
    mMainLoopCount=0;    //主循环次数变量
	mFlag='A';           //灯的状态标志
	mLightCount=0;       //灯的闪烁次数

//(1.4)给全局变量赋初值
   
//(1.5)用户外设模块初始化
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_ON);	//初始化蓝灯
	gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_ON);	//初始化蓝灯
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON);	//初始化蓝灯
   
//(1.6)使能模块中断
    
   
//(1.7)【不变】开总中断
	ENABLE_INTERRUPTS;
	
	printf("------------------------------------------------------\n");   
    printf("金葫芦提示:构件法输出控制小灯亮暗   \n");
    printf("    第一次用构件方法点亮的蓝色发光二极管,\n");
    printf("    这是进行应用编程的第一步,可以在此基础上,\n");
    printf("   “照葫芦画瓢”地继续学习实践。\n");
    printf("    例如:改为绿灯;调整闪烁频率等。\n");
    printf("------------------------------------------------------\n"); 
    
    //asm ("bl .");
    
    //for(;;) {  }     //在此打桩,理解蓝色发光二极管为何亮起来了?
    
        
//(1)======启动部分(结尾)==========================================

//(2)======主循环部分(开头)========================================
	for(;;)   //for(;;)(开头)
	{
//(2.1)主循环次数变量+1
        mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
		if (mMainLoopCount<=12888999)  continue;
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
		mMainLoopCount=0; 
//(2.3.2)如灯状态标志mFlag为'L',灯的闪烁次数+1并显示,改变灯状态及标志
		if (mFlag=='L')                    //判断灯的状态标志
		{
			mLightCount++;  
			printf("灯的循环次数 mLightCount = %d\n",mLightCount);
			mFlag='A';                       //灯的状态标志
			gpio_set(LIGHT_BLUE,LIGHT_ON);  //灯“亮”
			gpio_set(LIGHT_RED,LIGHT_OFF);
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			printf(" 蓝灯\n");   //串口输出灯的状态
		}
//(2.3.3)如灯状态标志mFlag为'A',改变灯状态及标志
		else if (mFlag=='A')    
		{
			mFlag='B';                        
			gpio_set(LIGHT_BLUE,LIGHT_OFF);  
			gpio_set(LIGHT_RED,LIGHT_ON);  
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			printf(" 红灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='B')    
		{
			mFlag='C';                        
			gpio_set(LIGHT_BLUE,LIGHT_OFF);  
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			printf(" 绿灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='C')    
		{
			mFlag='D';                        
			gpio_set(LIGHT_BLUE,LIGHT_ON);  
			gpio_set(LIGHT_RED,LIGHT_ON);  
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			printf(" 紫灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='D')    
		{
			mFlag='E';                        
			gpio_set(LIGHT_BLUE,LIGHT_ON);  
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);  
			printf(" 青灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='E')    
		{
			mFlag='F';                        
			gpio_set(LIGHT_BLUE,LIGHT_OFF);  
			gpio_set(LIGHT_RED,LIGHT_ON);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			printf(" 黄灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='F')    
		{
			mFlag='G';                        
			gpio_set(LIGHT_BLUE,LIGHT_ON);  
			gpio_set(LIGHT_RED,LIGHT_ON);  
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			printf(" 白灯\n");   //串口输出灯的状态
		}
		else if (mFlag=='G')    
		{
			mFlag='L';                        
			gpio_set(LIGHT_BLUE,LIGHT_OFF);  
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			printf(" 灯暗\n");   //串口输出灯的状态
		}
	}  //for(;;)结尾
//(2)======主循环部分(结尾)========================================
}   //main函数(结尾)


//======以下为主函数调用的子函数===========================================


//========================================================================

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值