嵌入式系统第四章作业

文章讲述了在C语言编程中,如何使用直接地址操作和封装的方式控制红绿蓝灯的闪烁,以及如何通过主循环和GPIO寄存器实现灯的状态切换。特别强调了初始化的重要性,并展示了汇编语言实现的示例。
摘要由CSDN通过智能技术生成

题目:

2、两个变量的定义在文件user.h中

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

编程:在main函数中插入一下的代码

for(;;)     //for(;;)(开头)
    {
        
        //(2.1)主循环次数+1,并判断是否小于特定常数
        mMainLoopCount++;                         //+1
        if (mMainLoopCount<=6556677)  continue;   //如果小于特定常数,继续循环
        //(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)
        mMainLoopCount=0;      //清主循环次数
        //切换灯状态
        if (mFlag=='B')
        {
        	*gpio_bsrr|=(1<<8);     //设置绿灯“暗”
        	*gpio_mode &= ~(3<<18);
    		*gpio_mode |= (1<<18);
		    *gpio_brr|=(1<<9);     //设置蓝灯“亮”
            printf("蓝灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='R';             //改变状态标志
        }
        else if(mFlag=='R')
        {
        	*gpio_bsrr|=(1<<9);     //设置蓝灯“暗”
        	*gpio_mode &= ~(3<<14);
    		*gpio_mode |= (1<<14);
        	*gpio_brr|=(1<<7);     //设置红灯“亮”
            printf("红灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='G';             //改变状态标志
        }
        else if(mFlag=='G')      
        {
        	*gpio_bsrr|=(1<<7);     //设置红灯“暗”
        	*gpio_mode &= ~(3<<16);
    		*gpio_mode |= (1<<16);
        	*gpio_brr|=(1<<8);     //设置绿灯“亮”
            printf("蓝灯:暗\r\n");   //通过调试串口输出灯的状态
            mFlag='B';              //改变状态标志
        }	
    }     //for(;;)结尾

问题与思考:

在实验过程中出现过只有蓝灯亮、绿灯亮和不亮的情况,出现这样的原因是没有对红灯进行初始化。所以要在设置灯暗灯亮的操作时插入gpio_mode的设置。gpio_mode存储的是引脚模式的寄存器地址,即当前操作是的那个灯。

实验结果:

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

编程:在原本的main文件中插入下列代码,因为原本的代码自带循环来实现时间间隔我就直接枚举了

//(1)======启动部分(结尾)==========================================
	int i=0;
//(2)======主循环部分(开头)========================================
	for(;;)   //for(;;)(开头)
	{
//(2.1)主循环次数变量+1
        mMainLoopCount++;
//(2.2)未达到主循环次数设定值,继续循环
		if (mMainLoopCount<=12888999)  continue;
//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
		mMainLoopCount=0; 
	//实现八种模式
		
		if(i%8==0)
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯亮
			gpio_set(LIGHT_RED,LIGHT_ON); //红灯亮
			gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯亮
			printf("0\n");
		}
		else if(i%8==1)
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯灭
			gpio_set(LIGHT_RED,LIGHT_ON); //红灯亮
			gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯亮
			printf("1\n");
		}
		else if(i%8==2)
		{
			gpio_set(LIGHT_BLUE,LIGHT_ON); //蓝灯亮
			gpio_set(LIGHT_RED,LIGHT_OFF); //红灯灭
			gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯亮
			printf("2\n");
		}
		else if(i%8==3)
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯灭
			gpio_set(LIGHT_RED,LIGHT_OFF); //红灯灭
			gpio_set(LIGHT_GREEN,LIGHT_ON); //绿灯亮
			printf("3\n");
		}
		else if(i%8==4)
		{
			gpio_set(LIGHT_BLUE,LIGHT_ON); //蓝灯亮
			gpio_set(LIGHT_RED,LIGHT_ON); //红灯亮
			gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯灭
			printf("4\n");
		}
		else if(i%8==5)
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯灭
			gpio_set(LIGHT_RED,LIGHT_ON); //红灯亮
			gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯灭
			printf("5\n");
		}
		else if(i%8==6)
		{
			gpio_set(LIGHT_BLUE,LIGHT_ON); //蓝灯亮
			gpio_set(LIGHT_RED,LIGHT_OFF); //红灯灭
			gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯灭
			printf("6\n");
		}
		else if(i%8==7)
		{
			gpio_set(LIGHT_BLUE,LIGHT_OFF); //蓝灯灭
			gpio_set(LIGHT_RED,LIGHT_OFF); //红灯灭
			gpio_set(LIGHT_GREEN,LIGHT_OFF); //绿灯灭
			printf("7\n");
		}
		i++;
	
	}  //for(;;)结尾
	
//(2)======主循环部分(结尾)========================================
}   //main函数(结尾)

问题和思考:构建法就是将原本的直接地址操作进行封装了,实现了变成上的简单和简洁。在实验中不要忘记对红灯和绿灯初始化。

实验结果:

额外的工作:用汇编实现了三灯轮换

编程:将代码main_loop的代码换成一下部分

//(2)======主循环部分(开头)=====================================
main_loop:                         //主循环标签(开头)
//(2.1)主循环次数变量mMainLoopCount+1
        ldr r2,=mMainLoopCount     //r2←变量mMainLoopCount的地址
        ldr r1, [r2]               //r1←变量mMainLoopCount的内容
        movs r3,#1                 //r3←1 
        add r1,r3                  //变量+1
        str r1,[r2]                //放回地址中
//(2.2)未达到主循环次数设定值,继续循环
        ldr r2,=MainLoopNUM
        cmp r1,r2
        blO  main_loop             //未达到,继续循环
        
//	实现蓝灯,绿灯,红灯轮流亮灭,判断当前应该操作的是哪个灯,b为蓝灯,r为红灯,g为绿灯
//(2.3.1)清除循环次数变量
        ldr r2,=mMainLoopCount     //r2←mMainLoopCount的地址
        movs r1,#0
        str r1,[r2]
        
        
        //先让三个灯全灭
        ldr r0,=LIGHT_BLUE        //蓝灯暗灯
        ldr r1,=LIGHT_OFF
        bl  gpio_set  
        
        ldr r0,=LIGHT_RED        //红灯暗灯
        ldr r1,=LIGHT_OFF
        bl  gpio_set  
        
        ldr r0,=LIGHT_GREEN        //绿灯暗灯
        ldr r1,=LIGHT_OFF
        bl  gpio_set  
//	开始对灯进行操作
		ldr r2,=Lighttype
		ldr r6,[r2]
		cmp r6,#'b'
		bne red_do
		blO  bule_do
bule_do:
	    ldr r0,=LIGHT_BLUE        //亮灯
        ldr r1,=LIGHT_ON
        bl  gpio_set 
        ldr r0,=light_show1
        bl printf
        ldr r2,=Lighttype        //下一个红灯亮      
        movs r7,#'r'
        str r7,[r2]
        b main_exit 
red_do:
	ldr r2,=Lighttype
	ldr r6,[r2]
	cmp r6,#'r'
	bne green_do
	ldr r0,=LIGHT_RED
	ldr r1,=LIGHT_ON
	bl gpio_set
	ldr r0,=light_show2
    bl printf
	ldr r2,=Lighttype        //下一个绿灯亮      
    movs r7,#'g'
    str r7,[r2]
    b main_exit 
green_do:
    ldr r0,=LIGHT_GREEN
    ldr r1,=LIGHT_ON
    bl gpio_set
    ldr r0,=light_show3
    bl printf
    ldr r2,=Lighttype        //下一个蓝灯亮      
    movs r7,#'b'
    str r7,[r2]
    b main_exit 

main_exit:
    b main_loop                   //继续循环
//(2)======主循环部分(结尾)=====================================

问题和思考:

基本逻辑和上面的两个任务差不多,就是通过判断标识符来辨别当前那个灯亮。也需要去先初始化红灯个绿灯。

结果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值