第四章作业

一、题目

二、过程

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

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

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

完整代码:
//====================================================================
//文件名称: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='B';              //主循环使用的临时变量:蓝灯状态标志
    
 
    //(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.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)======主循环部分(开头)=========================================
    
//    gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON);
 
 
    for(;;)     //for(;;)(开头)
    {
        
        //(2.1)主循环次数+1,并判断是否小于特定常数
        mMainLoopCount++;                         //+1
        if (mMainLoopCount<=6556677)  continue;   //如果小于特定常数,继续循环
        //(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)
        mMainLoopCount=0;      //清主循环次数
        //切换灯状态
        
 
        if (mFlag=='B')   //若灯状态标志为'B'
        {
         	*gpio_bsrr|=(1<<7);     //设置灯“暗”
			*gpio_brr|=(1<<9);     //设置灯“亮”	
        	
            printf("蓝灯:亮\r\n");   //通过调试串口输出灯的状态
            mFlag='G';              //改变状态标志
        
//        	gpio_set(LIGHT_RED,LIGHT_OFF);
//        	gpio_set(LIGHT_BLUE,LIGHT_ON);
			
        }
        
       else  if(mFlag=='G')                //否则,若灯状态标志为'G'    
        {
//        	gpio_set(LIGHT_RED,LIGHT_OFF);
//        	gpio_set(LIGHT_GREEN,LIGHT_ON);
 
			*gpio_bsrr|=(1<<9);     //设置灯“暗”
			*gpio_brr|=(1<<8);     //设置灯“亮”	
 
            printf("绿灯:亮\r\n");   //通过调试串口输出灯的状态
            mFlag='R';              //改变状态标志
        }	
       else 
        {
//        	gpio_set(LIGHT_GREEN,LIGHT_OFF);
//        	gpio_set(LIGHT_RED,LIGHT_ON);
        	*gpio_bsrr|=(1<<8);     //设置灯“暗”
			*gpio_brr|=(1<<7);     //设置灯“亮”	
			
            printf("红灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='B';             //改变状态标志
 
        }
        
    }     //for(;;)结尾
    //(2)======主循环部分(结尾)========================================	
}
 
/*
注① 这样做的目的在于更改了D19、D18两位的值,而不改变其他位的值,不这样的话,	
     可能把不需要改变的位也改变了!
*/
//======以下为主函数调用的子函数存放处=====================================
 
//======以下为主函数调用的子函数===========================================
 
 
//========================================================================
/*
 知识要素:
 (1)main.c是一个模板,该文件所有代码均不涉及具体的硬件和环境,通过调用构件
      实现对硬件的干预。
 (2)本文件中对宏GLOBLE_VAR进行了定义,所以在包含"includes.h"头文件时,会定
      义全局变量,在其他文件中包含"includes.h"头文件时,
      编译时会自动增加extern
 */
结果,三种灯交替闪烁:

  

(4)用调用构件方式,实现红绿蓝的八种闪烁

尝试仿照以前的知识:

核心修改代码:
 for(::)//for(::)(开头)
 {
//先把红灯熄灭
*gpio_bsrr|=(1<<7)://设置灯“暗”
*gpio_bsrr&= (1<<23):
//蓝灯闪烁
*gpio_bsrr|=(1<<25)//设置灯“亮”
*gpio_bsrr&= (1<<9);
 printf  ("灯亮\r\n");//通过调试串口输出灯的状态for(LoopCount=0;LoopCount<6556677;LoopCount++);
    *gpio_bsrr|=(1<<9)://设置灯“暗”
    *gpio_bsrr&=~(1<<25);
    printf("灯暗\r\n")://通过调试串口输出灯的状态
for(LoopCount=0;LoopCount<6556677;LoopCount++);
    *gpio_bsrr|=(1<<24)://设置灯“亮”
    *gpio_bsrr&=~(1<<8);
    printf("灯亮\r\n")://通过调试串口输出灯的状态
    for(LoopCount=0;LoopCount<6556677;LoopCount++);
    *gpio_bsrr|=(1<<8)://设置灯“暗”
    *gpio_bsrr&=~(1<<24);
    printf("灯暗\r\n")://通过调试串口输出灯的状态
     for(LoopCount=0;LoopCount<6556677;LoopCount++);
    *gpio_bsrr|=(1<<23)://设置灯“亮”
    *gpio_bsrr&=~(1<<7);
    printf("灯亮\r\n")://通过调试串口输出灯的状态
     for(LoopCount=0;LoopCount<6556677;LoopCount++);
    *gpio_bsrr|=(1<<7)://设置灯“暗”
    *gpio_bsrr&=~(1<<23);
    printf("灯暗\r\n")://通过调试串口输出灯的状态
     for(LoopCount=0;LoopCount<6556677;LoopCount++);
     
     }//ffor(:;)结尾
结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值