首页>>科技 >>内容

想从事嵌入式软件开发考研选什么专业,嵌入式软件开发是什么意思

发布时间:2023-10-17 16:28:08编辑:温柔的背包来源:

想从事嵌入式软件开发考研选什么专业,嵌入式软件开发是什么意思

很多朋友对想从事嵌入式软件开发考研选什么专业,嵌入式软件开发是什么意思不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

1.问题描述

使用定时器过程中最苦恼的就是定义flag和holdtime会导致中断函数中的标志位飞得到处都是,程序中随处可见时间变量。我想移植,但又不敢随便删除。程序处于高度耦合状态,a.c、a.h失去了意义。

2.如何解决这个问题

引入注册机制。为了方便说明注册机制,我们举个例子:在使用手机拍照功能时,有一个操作:发送拍摄的照片。用程序来实现这个过程,最容易想到的方法如下:

在相机的发送模块中添加以下代码:

if(选择发送){if(选择微信发送){获取发件人;选择发件人;} elseif(选择qq发送){获取发件人;选择发件人;} elseif(选择微博发送){获取发件人;选择发件人;}.此处省略10,000 行。}

这是最容易想到的实现方法。就像上面定时器的实现方法一样,无论你想在哪里使用它,只要定义一系列变量即可。回到相机的例子,假设有一天出现了一款比微信更流行的聊天软件。用户安装它并想要发送图片。这个时候他该怎么办呢?当然,你只能添加else if (在上面相机的send 模块中)。 )及其实现,这意味着每次更新需要使用图片功能的软件时,都必须修改摄像头模块。是不是感觉和我们的定时器很相似呢?

注册的本质:各个模块解耦。程序注重高内聚、低耦合。我目前对这句话的理解是:高内聚:各个功能模块(c文件、h文件)内部不与其他模块互相调用。例如,障碍函数中不应该有状态变量,更不用说运行此操作时您应该具有零地标恢复。它只做一件事,处理IO端口信息并生成相应的障碍物状态。低耦合:障碍物函数与其他模块的耦合只是生成的障碍物状态。让我们更深入地了解注册机制。

什么是注册:我目前的理解是,相机想要发送图片,面临着多种发送方法,而每种发送方法肯定会调用不同的函数。反过来想,我有很多使用相机模块的应用程序(比较这里的计时器)。在这种情况下,相机模块定义了一个注册函数,供其他模块调用,告诉相机允许相应的发送方法。

#definenum_max20//最大设备数typedefstruct{ u8 num; //当前注册设备数量u8list_name[num_max];//用于保存注册设备列表void (*click[num_max]) (u8*temp); //存放不同模块(微信qq)发送函数地址}Equiment;EquimentCOM;/****************************注册函数**** **** **************************************/voidPhoto_Register(void(*a)(u8*temp ),u8list)//提供给外部的接口{if(COM.numnum.max){COM.click[COM.num]=a;//保存函数地址COM.List_name[COM.num]=list;//将设备名称保存到列表中COM .num++;}else{/****超出最大设备数量并报错******/}}voidClick ( u8temp)//最终实现图片发送只需调用该函数即可{ u8 i, NUM; for (i=0;i=COM.num;i++){printf("打印列表,显示注册设备")} NUM=Get(选择发送方式); if(!NUM)COM .click[NUM](temp);}/************************以上是在相机中实现的**** ********** **********************/

如果想在微信中使用,在安装过程中,如果提示打开相机权限,则需要调用上面的注册函数。将微信自带的发送功能地址传递给相机。摄像头每次发送时,只需判断注册了哪些设备,并选择相应的方法即可。这样,无论出现多少个新的应用程序想要使用摄像头,都只需要注册一次。摄像头与微信、QQ、微博等模块完美解耦!同样,定时器的解耦也可以这样处理。

定时器应用注册机制

首先,为了解耦,必须去掉随机定义的标志和时间变量,并且只允许有一个时间变量。因此,定义一个没有任何条件限制的32位时间变量,并让它不断地自行添加。

参考Arduino中的定时处理方法:定义一个函数获取当前时间,保存当前时间,运行一段时间,再次查询当前时间,差两次得到运行时间。从上面不难看出,关键点是:获取当前时间的函数、当前时间的存储、差后的时间。操作方法如下:

时间.h

#include'stm32f10x.h'#ifndef__TIME_H#define__TIME_H#defineTimerID_max20//注册设备最大数量#defineRunOutOf_time(ID,ms)(systime.now-systime.last[ID-1]ms)typedefstruct{u8ID;//设备IDu32now ; //当前时间u32last[TimerID_max];//存储捕获的时间void(*timer_init)(u16countdata,u16freqData);//指向初始化函数u8(*get_id)(void);//指向获取ID function void( *refresh)(u8ID);//指向更新时间函数}SYSTIME;externSYSTIMEsystime;#endif

时间.c

#include'time.h'/*********提供给外部API************************/voidTimer_Init(u16CountData,u16FreqData );unsignedcharsystime_get (void);voidRefresh(u8ID);/******************************************** *** ********/SYSTIMEsystime=定义SYSTIME类型变量并初始化函数指针{.get_id=systime_get,refresh=刷新,timer_init=Timer_Init};/************ ******* ***************************************///功能name: Timer_init//描述:初始化定时器//输入:中断时间相关//输出:null/**************************** ******** ******************/voidTimer_Init(u16CountData,u16FreqData){RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);NVIC_InitTypeDefNVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitStructure。 NVIC_IRQChannel=TI M4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStructure.NVIC_IRQChannelSubPriority=4;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(NVIC_InitStructure);TIM_TimeBaseInitTypeDefTIM_TimeBaseStru cture;TIM_DeInit(TIM4);TIM_TimeBaseStructure.TIM_Prescaler=FreqData;TI M_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseStructure。 TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInit(TIM4,TIM_TimeBaseStructure);TIM_ClearFlag(TIM4,TIM_FLAG_Update);TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);TIM_Cmd(TIM4,ENABLE);}/**************** ********** **********************************///函数名:systime_get//说明:获取当前时间并生成注册//输入:null//输出:null/******************************** ********** **********/unsignedcharsystime_get(){if(systime.ID

在.c和.h中实现上述之后,面向外部的函数就只剩下三个了。

/************提供给外部API************************/voidTimer_Init(u16CountData,u16FreqData);unsignedcharsystime_get(void );voidRefresh(u8ID );/************************************************ ***** /

如何使用定时器

1.2./************任务1实现运行等闪烁,频率1s************/voidtask1(){staticu8Task1_ID;if (!Task1_ID )Task1_ID=systime.get_id();if(RunOutOf_time(Task1_ID,1000))RUN_LED()=1;elseif(RunOutOf_time(Task1_ID,2000))RUN_LED()=0;elseif(RunOutOf_time(Task1_ID,3000) )RUN_LED( )=1;elseif(RunOutOf_time(Task1_ID,4000))RUN_LED()=0;elseif(RunOutOf_time(Task1_ID,5000)RUN_LED()=1;elsesystime.refresh(Task1_ID);}/***** *** *************任务2实现运行等闪烁,频率100ms************************ /voidtask2(){staticu8Task1_ID;if (!Task1_ID)Task1_ID=systime.get_id();if(RunOutOf_time(Task1_ID,100))RUN_LED()=1;elseif(RunOutOf_time(Task1_ID,200))RUN_LED()=0; elseif(RunOutOf_time(Task1_ID,300))RUN_LED()=1;elseif(RunOutOf_time(Task1_ID,400))RUN_LED()=0;elseif(RunOutOf_time(Task1_ID,500))RUN_LED()=1;elsesystime.refresh(Task1_ID) );}/**** *************main函数实现任务1运行10s,任务2运行10s**************** *****/intmain(void){staticu8main_ID;System_Init() ;while(1){if(!main_ID)main_ID=systime.get_id();if(RunOutOf_time(main_ID,10000))task1();elseif( RunOutOf_time(main_ID,20000))task2();elsesystime.refresh(main_ID );}}

上面,如果有一个函数想要使用定时器,只需要根据需要设置一个ID存储变量来存储注册时分配的ID,然后就可以调用定时器了。它可以很容易地移植到任何平台上,只需要修改硬件。初始化。

该程序无法实现基于时间的任务执行。例如,某个任务需要每100ms执行一次,并且只能在一个时间段内执行。原因是程序的主循环需要时间,导致轮询时无法准确捕获100ms的时刻。为了达到这个效果,需要对其进行改进或者以完全不同的方式编写。比如捕获放在中断中,主循环查询100ms。使能位。

评论柳青

以上知识分享希望能够帮助到大家!