嵌入式系统第四章作业

学习CH04示例程序

注释:

//=====================================================================
//文件名称:main.s
//功能概要:汇编编程调用GPIO构件控制小灯闪烁(利用printf输出提示信息)
//版权所有:苏大嵌入式(sumcu.suda.edu.cn)
//版本更新:201808-202311
//=====================================================================
.include "include.inc"    //头文件中主要定义了程序中需要使用到的一些常量

//(0)数据段与代码段的定义

//(0.1)定义数据存储data段开始,实际数据存储在RAM中
.section .data

//(0.1.1)定义需要输出的字符串,标号即为字符串首地址,\0为字符串结束标志
hello_information:           //字符串标号
    .ascii "--------------------------------------------------------------\n"
    .ascii "金葫芦提示:                                                   \n"
    .ascii "LIGHT:ON--第一次用纯汇编点亮的蓝色发光二极管,太棒了!          \n"
    .ascii "          这只是万里长征第一步,但是,万事开头难,              \n"
    .ascii "          有了第一步,坚持下去,定有收获!                     \n"
    .ascii "--------------------------------------------------------------\n\0"

data_format:
    .ascii "%d\n\0"                 //printf使用的数据格式控制符

light_show1:
    .ascii "LIGHT_BLUE:ON--\n\0"    //灯亮状态提示   

light_show2:
    .ascii "LIGHT_BLUE:OFF--\n\0"   //灯暗状态提示

light_show3:
    .ascii "闪烁次数mLightCount=\0"  //闪烁次数提示

//(0.1.2)定义变量
.align 4                  //.word格式四字节对齐

mMainLoopCount:           //定义主循环次数变量
    .word 0

mFlag:                   //定义灯的状态标志,1为亮,0为暗
    .byte 'A'    

.align 4

mLightCount:
    .word 0

//(0.2)定义代码存储text段开始,实际代码存储在Flash中
.section   .text
.syntax unified        //指示下方指令为ARM和thumb通用格式
.thumb                 //Thumb指令集
.type main function    //声明main为函数类型                     
.global main           //将main定义成全局函数,便于芯片初始化之后调用
.align 2               //指令和数据采用2字节对齐,兼容Thumb指令集

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

//--------------------------------------------------------------------
//主函数,一般情况下可以认为程序从此开始运行(实际上有启动过程,参见书稿)
main:
//(1)======启动部分(开头)主循环前的初始化工作======================
//(1.1)声明main函数使用的局部变量

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

//(1.3)给主函数使用的局部变量赋初值
    
//(1.4)给全局变量赋初值
    
//(1.5)用户外设模块初始化
//  初始化蓝灯, r0、r1、r2是gpio_init的入口参数
    ldr r0,=LIGHT_BLUE       //r0指明端口和引脚(用=,因常量>=256,需用ldr)
    movs r1,#GPIO_OUTPUT     //r1指明引脚方向为输出
    movs r2,#LIGHT_OFF       //r2指明引脚的初始状态为亮
    bl  gpio_init            //调用gpio初始化函数

//  初始化串口UART_User1
    movs r0,#UART_User       //串口号
    ldr r1,=UART_BAUD        //波特率
    bl uart_init             //调用uart初始化函数

//(1.6)使能模块中断
    movs r0,#UART_User       //串口号
    bl  uart_enable_re_int   //调用uart中断使能函数

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

//显示hello_information定义的字符串
    ldr r0,=hello_information     //待显示字符串首地址
    bl  printf                    //调用printf显示字符串
    
    //bl .   //在此打桩(.表示当前地址),理解发光二极管为何亮起来了?
    
//(1)======启动部分(结尾)=======================================

//(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             //未达到,继续循环

//(2.3)达到主循环次数设定值,执行下列语句,进行灯的亮暗处理
//(2.3.1)清除循环次数变量
        ldr r2,=mMainLoopCount     //r2←mMainLoopCount的地址
        movs r1,#0
        str r1,[r2]    

//(2.3.2)如灯状态标志mFlag为'L',灯的闪烁次数+1并显示,改变灯状态及标志    
        //判断灯的状态标志
        ldr r2,=mFlag           
        ldr r6,[r2]
        cmp r6,#'L'            
        bne main_light_off        //mFlag不等于'L'转

        //mFlag等于'L'情况
        ldr r3,=mLightCount       //灯的闪烁次数mLightCount+1
        ldr r1,[r3]
        movs r4,#1
        add r1,r4                
        str r1,[r3]
        
        ldr r0,=light_show3       //显示“灯的闪烁次数mLightCount=”
        bl  printf                
        
        ldr r0,=data_format       //显示灯的闪烁次数值
        ldr r2,=mLightCount
        ldr r1,[r2]
        bl  printf    
        
        ldr r2,=mFlag             //灯的状态标志改为'A'
        movs r7,#'A'
        str r7,[r2]             
        
        ldr r0,=LIGHT_BLUE        //亮灯
        ldr r1,=LIGHT_ON
        bl  gpio_set          
        
        ldr r0, =light_show1      //显示灯亮提示
        bl  printf    
        
        //mFlag等于'L'情况处理完毕,转
        b main_exit  

//(2.3.3)如灯状态标志mFlag为'A',改变灯状态及标志
main_light_off:
        ldr r2,=mFlag             //灯的状态标志改为'L'        
        movs r7,#'L'
        str r7,[r2]   
        
        ldr r0,=LIGHT_BLUE        //暗灯
        ldr r1,=LIGHT_OFF
        bl  gpio_set  
        
        ldr r0, =light_show2      //显示灯暗提示
        bl  printf    

main_exit:
    b main_loop                   //继续循环

//(2)======主循环部分(结尾)=====================================
.end     //整个程序结束标志(结尾)

给出gpio_set(LIGHT_RED,LIGHT_OFF);语句中,LIGHT_RED和LIGHT_OFF的值是多少?

main.c:

user.h:

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

    //(1)======启动部分(结尾)==========================================
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON);
    //(2)======主循环部分(开头)=========================================
    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'; //改变状态标志
        }
        else if(mFlag=='G') //若灯状态标志为'G'
        {
            *gpio_bsrr|=(1<<9); //设置蓝灯“暗”
            *gpio_brr|=(1<<8); //设置绿灯“亮”
            printf("绿灯:亮\r\n"); //通过调试串口输出灯的状态
            mFlag='R'; //改变状态标志
        }  
        else if(mFlag=='R') //若灯状态标志为'R'
        {
            *gpio_bsrr|=(1<<8); //设置绿灯“暗”
            *gpio_brr|=(1<<7); //设置红灯“亮”
            printf("红灯:亮\r\n"); //通过调试串口输出灯的状态
            mFlag='B'; //改变状态标志
        }
    }     //for(;;)结尾

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

//(1)======启动部分(结尾)==========================================
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_ON);
//(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=='R')		// 红色
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='G';                       //灯的状态标志
			gpio_set(LIGHT_RED,LIGHT_ON);  //灯“亮”
			printf(" LIGHT_RED:ON--\n\n");   //串口输出灯的状态
		}
//(2.3.3)如灯状态标志mFlag为'G',改变灯状态及标志
		else if (mFlag=='G')		// 绿色
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='B';                       //灯的状态标志
			gpio_set(LIGHT_RED,LIGHT_OFF);  //灯“暗”
			gpio_set(LIGHT_GREEN,LIGHT_ON);  //灯“亮”
			printf(" LIGHT_GREEN:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='B')		// 蓝色
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='Y';                       //灯的状态标志
			gpio_set(LIGHT_GREEN,LIGHT_OFF);  //灯“暗”
			gpio_set(LIGHT_BLUE,LIGHT_ON);  //灯“亮”
			printf(" LIGHT_BLUE:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='Y')		// 黄色(红绿)
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='P';                       //灯的状态标志
			gpio_set(LIGHT_BLUE,LIGHT_OFF); 
			gpio_set(LIGHT_RED,LIGHT_ON);   
			gpio_set(LIGHT_GREEN,LIGHT_ON);  
			printf(" LIGHT_YELLOW:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='P')		// 紫色(红蓝)
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='C';                       //灯的状态标志
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			gpio_set(LIGHT_RED,LIGHT_ON); 
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			printf(" LIGHT_PURPLE:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='C')		// 青色(蓝绿)
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='W';                       //灯的状态标志
			gpio_set(LIGHT_RED,LIGHT_OFF);
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			printf(" LIGHT_CYAN:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='W')		// 白色(红绿蓝)
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='D';                       //灯的状态标志
			gpio_set(LIGHT_BLUE,LIGHT_ON);   
			gpio_set(LIGHT_GREEN,LIGHT_ON);
			gpio_set(LIGHT_RED,LIGHT_ON);  
			printf(" LIGHT_WHITE:ON--\n\n");   //串口输出灯的状态
		}
		else if (mFlag=='D')		// 暗色
		{
			mLightCount++;  
			printf("灯的闪烁次数 mLightCount = %d\n",mLightCount);
			mFlag='R';                       //灯的状态标志
			gpio_set(LIGHT_GREEN,LIGHT_OFF);
			gpio_set(LIGHT_BLUE,LIGHT_OFF); 
			gpio_set(LIGHT_RED,LIGHT_OFF);  
			printf(" DARK:ON--\n\n");   //串口输出灯的状态
		}
	}  //for(;;)结尾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值