嵌入式作业4

一、学习CH04示例程序,包括gpio.c和main.c。

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

打开CH04中的GPIO-BlueLight_20230328/07_AppPrg/main.c,找到gpio_set(LIGHT_RED,LIGHT_OFF),选中LIGHT_RED,右键选择查看定义。

跳转到user.h,可以看到LIGHT_RED的值为(PTB_NUM|7),选中PTB_NUM,右键选择查看定义

跳转到gpio.h,看到PTB_NUM的值为(1<<8)也就是256,故LIGHT_RED的值(PTB_NUM|7)为263

在user.h中可以看到LIGHT_OFF的值为1


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

在GPIO-Output-DirectAddress_STM32L431_20200928的main.c的基础上修改

1、将灯状态标志初始化为:‘B’

2、定义B口7、8、9脚为输出引脚

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口7、8、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.2)定义B口7、8、9脚为输出引脚方法如下:
    *gpio_mode &= ~(0b111111<<14);  //0b11111111111100000011111111111111;清零
    *gpio_mode |=(1<<14);    //0b00000000000000000100000000000000;
    *gpio_mode |=(1<<16);    //0b00000000000000010000000000000000;
    *gpio_mode |=(1<<18);    //0b00000000000001000000000000000000;
    // (1.5.4)初始化三色小灯全暗
    *gpio_bsrr &=(7<<7);
    //(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("    gzhu lfd制作\r\n");
    printf("----------------------------------------------------\r\n"); 
    //(1)======启动部分(结尾)==========================================
    
    //(2)======主循环部分(开头)=========================================
   for(;;)     //for(;;)(开头)
    {
        //(2.1)主循环次数+1,并判断是否小于特定常数
        mMainLoopCount++;                         //+1
        if (mMainLoopCount<=6556677)  continue;   //如果小于特定常数,继续循环
        //(2.2)主循环次数超过特定常数,灯状态进行切换(这样灯会闪烁)
        mMainLoopCount=0;      //清主循环次数
        //切换灯状态
        if (mFlag=='B')   //若灯状态标志为'R'
        {
         	*gpio_bsrr|=(1<<9);     //设置蓝灯“灭”
		    *gpio_brr|=(1<<7);     //设置红灯“亮”
            printf("红灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='R';             //改变状态标志
        }
        else if (mFlag=='R')   //若灯状态标志为'G'
        {
         	*gpio_bsrr|=(1<<7);     //设置红灯“灭”
		    *gpio_brr|=(1<<8);     //设置绿灯“亮”
            printf("绿灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='G';             //改变状态标志
        }
        else if (mFlag=='G')	 //若灯状态标志为'B'
        {
		   *gpio_bsrr|=(1<<8);     //设置绿灯“灭”
		    *gpio_brr|=(1<<9);     //设置蓝灯“亮”
            printf("蓝灯:亮\r\n");  //通过调试串口输出灯的状态
            mFlag='B';             //改变状态标志
        }	
    }     //for(;;)结尾
    //(2)======主循环部分(结尾)========================================
}

/*
注① 这样做的目的在于更改了D19、D18两位的值,而不改变其他位的值,不这样的话,
     可能把不需要改变的位也改变了!
*/
//======以下为主函数调用的子函数存放处=====================================

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


//========================================================================
/*
 知识要素:
 (1)main.c是一个模板,该文件所有代码均不涉及具体的硬件和环境,通过调用构件
      实现对硬件的干预。
 (2)本文件中对宏GLOBLE_VAR进行了定义,所以在包含"includes.h"头文件时,会定
      义全局变量,在其他文件中包含"includes.h"头文件时,
      编译时会自动增加extern
 */

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

在GPIO-Output-Component_STM32L431_20200928的main.c的基础上修改

1、用户外设模块初始化

2、主循环

完成上面的修改后可以实现小灯按照暗、红、绿、黄、蓝、紫、青、白的顺序交替变换

开发板亮灯情况展示

小灯按暗、红、绿、黄、蓝、紫、青、白颜色的顺序交替变换

源码

//======================================================================
//文件名称: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;  //主循环次数变量
	uint32_t mFlag;           //灯的状态标志
	uint32_t mLightCount;     //灯的状态切换次数

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

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

//(1.4)给全局变量赋初值
   
//(1.5)用户外设模块初始化
	gpio_init(LIGHT_RED,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯
	gpio_init(LIGHT_GREEN,GPIO_OUTPUT,LIGHT_OFF);	//初始化绿灯
	gpio_init(LIGHT_BLUE,GPIO_OUTPUT,LIGHT_OFF);	//初始化蓝灯

   
//(1.6)使能模块中断
    
   
//(1.7)【不变】开总中断
	ENABLE_INTERRUPTS;
	
	printf("------------------------------------------------------\n");   
    printf("金葫芦提示:构件法输出控制小灯亮暗   \n");
    printf("    第一次用构件方法点亮的蓝色发光二极管,\n");
    printf("    这是进行应用编程的第一步,可以在此基础上,\n");
    printf("   “照葫芦画瓢”地继续学习实践。\n");
    printf("    例如:改为绿灯;调整闪烁频率等。\n");
    printf("    gzhu lfd 制作\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; 
		printf("\n灯的闪烁次数 mLightCount = %d\n",mLightCount);
		mFlag=mLightCount % 8;			//计算当前小灯要显示的颜色
		if(mFlag == 0)
			printf("暗\n");
		else if(mFlag == 1)
			printf("红\n");
		else if(mFlag == 2)
			printf("绿\n");
		else if(mFlag == 3)
			printf("黄\n");
		else if(mFlag == 4)
			printf("蓝\n");
		else if(mFlag == 5)
			printf("紫\n");
		else if(mFlag == 6)
			printf("青\n");
		else if(mFlag == 7)
			printf("白\n");
		//重置串口输出灯
		gpio_set(LIGHT_RED,LIGHT_OFF); 
		gpio_set(LIGHT_GREEN,LIGHT_OFF);
		gpio_set(LIGHT_BLUE,LIGHT_OFF);
		if(mFlag == 1 || mFlag == 3 || mFlag == 5 || mFlag == 7)
		{
			gpio_set(LIGHT_RED,LIGHT_ON);  	//红灯“亮”
			printf(" LIGHT_RED:ON--\n");   	//串口输出灯的状态
		}
		if(mFlag == 2 || mFlag == 3 || mFlag == 6 || mFlag == 7)
		{
			gpio_set(LIGHT_GREEN,LIGHT_ON);  	//绿灯“亮”
			printf(" LIGHT_GREEN:ON--\n");   	//串口输出灯的状态
		}
		if(mFlag == 4 || mFlag == 5 || mFlag == 6 || mFlag == 7)
		{
			gpio_set(LIGHT_BLUE,LIGHT_ON);  	//蓝灯“亮”
			printf(" LIGHT_BLUE:ON--\n");   	//串口输出灯的状态
		}
		if(mFlag == 0)
		{
			gpio_set(LIGHT_RED,LIGHT_OFF); 	//红灯“暗”
			printf(" LIGHT_RED:OFF--\n");  	//串口输出灯的状态
			gpio_set(LIGHT_GREEN,LIGHT_OFF); 	//绿灯“暗”
			printf(" LIGHT_GREEN:OFF--\n");  	//串口输出灯的状态
			gpio_set(LIGHT_BLUE,LIGHT_OFF); 	//蓝灯“暗”
			printf(" LIGHT_BLUE:OFF--\n");  	//串口输出灯的状态
		}
		mLightCount++;  
	}  //for(;;)结尾
//(2)======主循环部分(结尾)========================================
}   //main函数(结尾)


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


//========================================================================
/*
 知识要素:
 (1)main.c是一个模板,该文件所有代码均不涉及具体的硬件和环境,通过调用构件
      实现对硬件的干预。
 (2)本文件中对宏GLOBLE_VAR进行了定义,所以在包含"includes.h"头文件时,会定
      义全局变量,在其他文件中包含"includes.h"头文件时,
      编译时会自动增加extern
 */

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
XJTU嵌入式作业2要求实现一个简单的温度转换程序。该程序需要输入一个摄氏温度值,并将其转换为华氏温度和开氏温度后输出。 为了完成这个任务,我们首先需要使用C语言编写一个能够进行温度转换的函数。该函数可以接受用户输入的摄氏温度值,并根据转换公式将其转换为华氏温度和开氏温度。 转换摄氏温度到华氏温度的公式如下: 华氏温度 = 摄氏温度 * 9/5 + 32 转换摄氏温度到开氏温度的公式如下: 开氏温度 = 摄氏温度 + 273.15 在程序中,我们可以使用scanf函数来接受用户输入的摄氏温度值。然后,我们可以声明并初始化华氏温度和开氏温度的变量,并根据转换公式进行计算。 最后,我们可以使用printf函数来输出转换后的华氏温度和开氏温度值。 除了实现温度转换的函数外,我们还可以编写一个主函数来测试该函数的正确性。在主函数中,我们可以调用温度转换函数,并将用户输入的摄氏温度值作为参数传递给该函数。 在运行程序时,用户将被要求输入一个摄氏温度值。程序将自动将该温度转换为华氏温度和开氏温度,并将转换结果输出到屏幕上。 总而言之,XJTU嵌入式作业2要求我们通过C语言编写一个温度转换程序。该程序可以将摄氏温度转换为华氏温度和开氏温度,并将转换结果输出到屏幕上。该程序包括一个温度转换函数和一个主函数来测试该函数的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值