当前位置:首页 > 单片机 > 单片机
[导读]似乎软件架构,只有纯上位机软件才有,其实,嵌入式软件也有架构可言,只有好的架构,才能结构清晰,方便开发和让系统稳定的工作。在有嵌入式操作系统的情况下,可以利用多任务和信号量,事件等设计嵌入式软件。但是在没有操作系统的裸机中,更需要有好的架构。例如利用事件和状态机模拟实现多任务,或者利用定时器和消息队列,信号量等模拟实现多任务,有了多任务就能灵活的设计软件架构。

 似乎软件架构,只有纯上位机软件才有,其实,嵌入式软件也有架构可言,只有好的架构,才能结构清晰,方便开发和让系统稳定的工作。在有嵌入式操作系统的情况下,可以利用多任务和信号量,事件等设计嵌入式软件。但是在没有操作系统的裸机中,更需要有好的架构。例如利用事件和状态机模拟实现多任务,或者利用定时器和消息队列,信号量等模拟实现多任务,有了多任务就能灵活的设计软件架构。

一种简单的信号量实现:

[cpp] view plain copy



void%20%20sem_init(%20volatile%20U08%20*Sem%20)

{

(*Sem)=0;

}

void%20sem_post(%20volatile%20U08%20*Sem%20)

{

if(%200%20==%20(*Sem)%20)

(*Sem)++;

}

U08%20sem_wait(%20volatile%20U08%20*Sem%20)

{

if(0%20==%20*Sem)

return%201;

(*Sem)--;

return%200;

}

在一个大的while(1)大循环中,利用信号量实现各个函数(任务)的同步。

[cpp]%20view%20plain%20copy


void%20%20Task_SysTime(%20void%20)

{

static%20int%20TaskInitFlg%20=%200;

U32%20Timer1sCount%20=%200;%20//时钟计数器个数

U32%20disstat%20=%200;

static%20int%20tmrid0%20=%200,%20tmrid1%20=%200,%20tmrid2%20=%200,%20tmrid3%20=%200;

if(%200%20==%20TaskInitFlg%20)

{

OSTimeDlyHMSM(%200,%200,%200,%2050%20//主要等待任务删除后才创建卡任务

tmrid0%20=%20TimerSet(20);%20//定时器0(毫秒定时器)用于键盘、寻卡、定时器中断服务程序,20ms

tmrid1%20=%20TimerSet(1000);//定时器1(毫秒定时器)用于背显、GPS、定时连接检测、空闲显示

tmrid2%20=%20TimerSet(500);%20//定时器2(毫秒定时器)用于信号显示,500ms

tmrid3%20=%20TimerSet(500);%20//定时器3(毫秒定时器)用于电池显示,500ms

sem_init(%20&gSem_EVT_CARDFLG_OK%20);%20//初始化为没有卡

APP_DisIdle(%202%20);%20//显示一次时间

APP_DisVoice();

TaskInitFlg%20=%201;%20//任务初始化完成

}

else

{

HW_IWDG_ReloadCounter();%20//清看门狗

if(%200%20==%20TimerCheck(tmrid0)%20)

{

tmrid0%20=%20TimerSet(20);%20//定时器0重新定时,%2020ms

Timer_ScanKeyboard();%20//20MS键盘扫描

Timer_FindCard();%20//20MS寻卡处理

TIM20MS_IRQHandler();%20//20MS定时器中断服务程序

}

}

}

void%20Task_Tick(%20void%20)

{

Task_SysError();

Task_CardProc();

Task_SysTime();

Task_MenuProc();

Task_MtnLink();

Task_CommProc();

}

int%20main(%20void%20)

{

Sys_Init();%20//系统初始化

while(%201%20)

{

Task_Tick();%20//任务轮询

if(%200%20==%20sem_wait(%20&gSem_EVT_QUIT_APP%20)%20)

break;%20//应用退出

}

}

以上为借助信号量和定时器实现的一种简单的模拟多任务,其实也算不上是多任务,因为如果一个函数执行时间很长,如何打断它?

以下为借住定时器和任务队列实现的一种模拟多任务:

[cpp]%20view%20plain%20copy


#include%20

#include%20"timTask.h"

#include%20"disp.h"

/*=====================================================

=%20变量定义

=====================================================*/

//任务队列

typedef%20struct{

char%20flagState;%20//运行方式%200:%20无任务

//%201:%20运行

char%20flagRun;%20//完成状态%200:%20正在计数

//%201:%20计数完成

char%20flagType;%20//处理方式%200:%20主任务处理

//%201:%20中断处理

ulong%20cntRun;%20//运行计数器

ulong%20numCircle;%20//循环计数器

void%20(*pTaskFunc)(void);%20//任务

}TypeTimTask;

TypeTimTask%20timTaskTab[TIM_TASK_NUMBER];

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20TimTaskInit(void)

{

int%20i;

for%20(i=0;%20i

{

timTaskTab[i].pTaskFunc%20=%200;

timTaskTab[i].cntRun%20=%200;

timTaskTab[i].numCircle%20=%200;

timTaskTab[i].flagRun%20=%200;

timTaskTab[i].flagState%20=%200;

}

SPT_register_call_back(TimTaskUpdate);

SPT_set(TIM_TASK_PERIOD%20*64%20/%201000);

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

short%20TimTaskAdd(ulong%20fsttim,%20ulong%20cirtim,%20void%20(*pTaskFunc)(void),%20uchar%20%20type)

{

int%20i;

int%20pos%20=%20-1;

//查找位置

for%20(i=0;%20i

{

if%20(timTaskTab[i].pTaskFunc%20==%20pTaskFunc)

{

pos%20=%20i;

break;

}

if%20((pos%20==%20-1)%20&&%20(timTaskTab[i].flagState%20==%200))

{

pos%20=%20i;

}

}

//任务已满

if%20(pos%20==%20-1)

{

return%20-1;

}

//

timTaskTab[pos].pTaskFunc%20=%20pTaskFunc;

timTaskTab[pos].cntRun%20=%20fsttim%20/%20TIM_TASK_PERIOD;

timTaskTab[pos].numCircle%20=%20cirtim%20/%20TIM_TASK_PERIOD;

timTaskTab[pos].flagRun%20=%200;

timTaskTab[pos].flagType%20=%20type;

timTaskTab[pos].flagState%20=%201;

return%200;

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20TimTaskDel(void%20(*pTaskFunc)(void))

{

int%20i;

for%20(i=0;%20i

{

if%20(timTaskTab[i].pTaskFunc%20==%20pTaskFunc)

{

timTaskTab[i].flagState%20=%200;

timTaskTab[i].flagRun%20=%200;

return;

}

}

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20TimTaskUpdate(void)

{

int%20i;

SPT_set(TIM_TASK_PERIOD%20*64%20/%201000);

for%20(i=0;%20i

{

if%20(timTaskTab[i].flagState%20!=%200)

{

if%20(timTaskTab[i].cntRun%20!=%200)

{

timTaskTab[i].cntRun--;

}

else

{

//判断处理位置

if%20(timTaskTab[i].flagType%20!=%200)

(*timTaskTab[i].pTaskFunc)();

else

timTaskTab[i].flagRun%20=%201;

//判断重载

if%20(timTaskTab[i].numCircle)

timTaskTab[i].cntRun%20=%20timTaskTab[i].numCircle;

else

timTaskTab[i].flagState%20=%200;

}

}

}

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20TimTaskProc(void)

{

int%20i;

for%20(i=0;%20i

{

if%20(timTaskTab[i].flagRun%20!=%200)

{

timTaskTab[i].flagRun%20=%200;

(*timTaskTab[i].pTaskFunc)();

}

}

}

更为巧妙的是,可以借住函数指针实现一种灵活的菜单和按键实时处理结构。类似于windows下win32的消息驱动机制,

通过中断等方式把实时事件封装成消息。以下为定义界面刷新显示和响应按键处理的结构:

[cpp]%20view%20plain%20copy%20%20


#ifndef%20__PAGE_H_

#define%20__PAGE_H_

#include%20"heads.h"

/*=====================================================

=

=====================================================*/

typedef%20struct{

void%20(*%20OnPaint)(void);

void%20(*%20OnKey)(short);

}TypePage;

/*=====================================================

=

=====================================================*/

void%20WndPageSet(const%20TypePage%20*pg,%20int%20type%20=%200);

TypePage%20*%20WndGetPage(void);

void%20WndPageEsc(void);

void%20WndOnKey(short%20key);

void%20WndOnPaint(void);

void%20WndMenuInit(const%20char%20*pmn,%20char%20mline);

void%20WndMenuSelet(int%20m);

char%20WndMenuGetSelet(void);

long%20WndGetPaseword(int%20x,%20int%20y,%20char%20*psw,%20int%20len,%20long%20qevent);

[cpp]%20%20view%20plain%20copy%20%20


#include%20"pageWnd.h"

/*=====================================================

=

=====================================================*/

char%20flagPaint%20=%200;

void%20(*%20pOnPaint)(void)%20=%200;

void%20(*%20pOnKey)(short)%20=%200;

const%20char%20*pMenuStr;

uchar%20menuSelect%20=%200;

uchar%20menuLine%20=%200;

uchar%20menuTop;

TypePage%20*pageCurrent;

TypePage%20*pageTreeTab[10];

uchar%20pageIndex%20=%200;

/*=====================================================

=

=====================================================*/

void%20WndDrawMenu(void);

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndPageSet(const%20TypePage%20*pg,%20int%20type)

{

if%20(pg%20==%20&pageMain)%20//防止出错

{

pageIndex%20=%200;

}

else%20if%20(type%20==%200)

{

pageTreeTab[pageIndex++]%20=%20pageCurrent;

}

pageCurrent%20=%20(TypePage%20*)pg;

pOnPaint%20=%20pg->OnPaint;

pOnKey%20=%20pg->OnKey;

flagPaint%20=%201;

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

TypePage%20*%20WndGetPage(void)

{

return%20pageCurrent;

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndPageEsc(void)

{

TypePage%20*pg;

if%20(pageIndex%20!=%200)

{

pageIndex--;

pg%20=%20pageTreeTab[pageIndex];

}

else

{

pg%20=%20(TypePage%20*)&pageMain;

}

pageCurrent%20=%20pg;

pOnPaint%20=%20pg->OnPaint;

pOnKey%20=%20pg->OnKey;

flagPaint%20=%201;

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndOnPaint(void)

{

if%20(flagPaint%20!=%200)

{

flagPaint%20=%200;

(*pOnPaint)();

}

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndOnKey(short%20key)

{

if%20(pOnKey%20!=%200)

{

(*pOnKey)(key);

}

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndMenuInit(const%20char%20*pmn,%20char%20mline)

{

menuSelect%20=%200;

pMenuStr%20=%20pmn;

menuLine%20=%20mline;

menuTop%20=%200;

WndDrawMenu();

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndMenuSelet(int%20m)

{

//光标滑动

if%20(m%20>%200)%20//下移

{

menuSelect++;

if%20(menuSelect%20==%20menuLine)

menuSelect%20=%200;

if%20(menuSelect%20>%20menuTop%20+%204)

{

if%20(menuLine%20<%20menuTop%20+%204)

menuTop%20=%20menuLine%20-%204;

else

menuTop%20=%20menuSelect%20-%204;

}

}

else%20if%20(m%20<%200)%20//上移

{

if%20(menuSelect%20==%200)

menuSelect%20=%20menuLine%20-%201;

else

menuSelect--;

}

//图框移动

if%20(menuSelect%20<%20menuTop)%20//上移

{

menuTop%20=%20menuSelect;

}

else%20if%20(menuSelect%20>=%20menuTop%20+%204)%20//下移

{

menuTop%20=%20menuSelect%20-%203;

}

WndDrawMenu();

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

char%20WndMenuGetSelet(void)

{

return%20menuSelect%20+%201;

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndDrawMenu(void)

{

int%20i;

char%20buf[17];

const%20char%20*pmn%20=%20pMenuStr%20+%20menuTop%20*%2016;

DispClr();

for%20(i=0;%20i<4;%20i++)

{

if%20(menuTop%20+%20i%20==%20menuLine)

break;

memcpy(buf,%20pmn,%2016);

buf[16]%20=%20'\0';

if%20(menuSelect%20==%20menuTop%20+%20i)

DispSetStyle(DISP_POSITION%20|%20DISP_REVERSE%20|%20DISP_7x9);

else

DispSetStyle(DISP_POSITION%20|%20DISP_NORMAL%20|%20DISP_7x9);

DispString(0,%20i%20*%202,%20buf);

pmn%20+=%2016;

}

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

long%20WndGetPaseword(int%20x,%20int%20y,%20char%20*psw,%20int%20len,%20long%20qevent)

{

int%20pin%20=%200;

long%20keyevt;

char%20key;

char%20buf[20];

memset(buf,%20'_',%20len);

buf[len]%20=%20'\0';

PSW_INPUT_LOOP:

DispString(x,%20y,%20buf);

keyevt%20=%20delay_and_wait_key(0,%20EXIT_KEY_ALL,%200);

if%20(keyevt%20==%20qevent)

{

psw[0]%20=%20'\0';

return%20keyevt;

}

switch%20(keyevt)

{

case%20EXIT_KEY_0:

key%20=%20'0';

break;

case%20EXIT_KEY_1:

key%20=%20'1';

break;

case%20EXIT_KEY_2:

key%20=%20'2';

break;

case%20EXIT_KEY_3:

key%20=%20'3';

break;

case%20EXIT_KEY_4:

key%20=%20'4';

break;

case%20EXIT_KEY_5:

key%20=%20'5';

break;

case%20EXIT_KEY_6:

key%20=%20'6';

break;

case%20EXIT_KEY_7:

key%20=%20'7';

break;

case%20EXIT_KEY_8:

key%20=%20'8';

break;

case%20EXIT_KEY_9:

key%20=%20'9';

break;

case%20EXIT_KEY_COMM:

if%20(pin%20!=%200)

{

buf[--pin]%20=%20'_';

}

goto%20PSW_INPUT_LOOP;

break;

case%20EXIT_KEY_ENTER:

psw[pin]%20=%200;

return%200;

default:

goto%20PSW_INPUT_LOOP;

}

if%20(pin%20!=%20len)

{

psw[pin]%20=%20key;

buf[pin]%20=%20'*';

pin++;

}

goto%20PSW_INPUT_LOOP;

}

在软件设计时,如果添加界面和对应的按键处理,很灵活,只需要新添加一个文件就可以了,文件的内容,只需要实现OnPain和对应的OnKey

[cpp]%20%20view%20plain%20copy%20%20


#include%20"PageMenu.h"

/*=====================================================

=

=====================================================*/

const%20char%20mainMenuTab[]%20=%20/*

1234567890123456*/"\

1.%20现场采集%20\

2.%20数据上传%20\

3.%20存储状态查询%20\

4.%20时间设置%20\

5.%20对比度设置%20\

6.%20恢复出厂设置%20\

7.%20关于%20";

/*=====================================================

=

=====================================================*/

void%20PageMenuOnPain(void);

void%20WndMenuOnKey(short%20key);

const%20TypePage%20pageMenu%20=%20{PageMenuOnPain,%20WndMenuOnKey};

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20PageMenuOnPain(void)

{

WndMenuInit(mainMenuTab,%207);

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20WndMenuOnKey(short%20key)

{

int%20res;

switch%20(key)

{

case%20KEY_F1:

case%20KEY_ENTER:

res%20=%20WndMenuGetSelet();

switch%20(res)

{

case%201:

WndPageSet(&pageSimp);

break;

case%202:

WndPageSet(&pagePclink);

break;

case%203:

WndPageSet(&pageInquire);

break;

case%204:

WndPageSet(&pageRtc);

break;

case%205:

WndPageSet(&pageGray);

break;

case%206:

SPageInit();

WndPageSet(&pageMenu,%201);

break;

case%207:

WndPageSet(&pageAbout);

break;

}

break;

case%20KEY_F2:

case%20KEY_F3:

WndPageSet(&pageMain);

break;

case%20KEY_1:

WndPageSet(&pageSimp);

break;

case%20KEY_2:

WndPageSet(&pagePclink);

break;

case%20KEY_3:

WndPageSet(&pageInquire);

break;

case%20KEY_4:

WndPageSet(&pageRtc);

break;

case%20KEY_5:

WndPageSet(&pageGray);

break;

case%20KEY_6:

SPageInit();

WndPageSet(&pageMenu,%201);

break;

case%20KEY_7:

WndPageSet(&pageAbout);

break;

case%20KEY_UP:

WndMenuSelet(-1);

break;

case%20KEY_DOWN:

WndMenuSelet(1);

break;

case%20KEY_POWER:

WndPageSet(&pagePower);

break;

}

}

pageMain,pageAbout,pageRtc,pagePclink等文件,他们的结构很类似。都是实现了OnPaint和OnKey函数。

如:pagePclink.c文件内容:

实现了PagePclinkOnPaint和PagePclinOnKey函数.

CommPclink函数是自己想要实现的功能,可以自己定义。

[cpp]%20view%20plain%20copy%20%20


#include%20"pagePclink.h"

/*=====================================================

=

=====================================================*/

void%20PagePclinkOnPaint(void);

void%20PagePclinOnKey(short%20key);

const%20TypePage%20pagePclink%20=%20{PagePclinkOnPaint,%20PagePclinOnKey};

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20PagePclinkOnPaint(void)

{

DispClr();

DispSetStyle(DISP_CENTER%20|%20DISP_REVERSE%20|%20DISP_7x9);

DispString(0,%200,%20"%20数据上传%20");

DispSetStyle(DISP_POSITION|DISP_NORMAL|DISP_7x9);

DispString(0,%206,%20"[连接]%20[返回]");

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20PagePclinOnKey(short%20key)

{

switch%20(key)

{

case%20KEY_F1:

CommPclink();

break;

case%20KEY_F3:

WndPageEsc();

break;

}

}

[cpp]%20view%20plain%20copy%20%20


#ifndef%20__PAGE_POWER_H_

#define%20__PAGE_POWER_H_

#include%20"pageWnd.h"

/*=====================================================

=

=====================================================*/

extern%20const%20TypePage%20pagePower;

#endif

#include%20"PagePower.h"

#include%20"disp.h"

/*=====================================================

=

=====================================================*/

void%20PagePowerOnPaint(void);

void%20PagePowerOnKey(short%20key);

const%20TypePage%20pagePower%20=%20{PagePowerOnPaint,%20PagePowerOnKey};

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20PagePowerOnPaint(void)

{

DispClr();

DispSetStyle(DISP_CENTER%20|%20DISP_REVERSE%20|%20DISP_7x9);

DispString(0,%200,%20"%20电源管理%20");

DispSetStyle(DISP_POSITION|DISP_NORMAL|DISP_7x9);

DispString(0,%202,%20"%20[Enter]%20关机%20");

DispString(0,%204,%20"%20[F3%20]%20返回%20");

}

/*************************************************************************

*%20函数原型:

*%20功能描述:

*%20入口参数:

*%20出口参数:

*%20返%20回%20值:

*************************************************************************/

void%20PagePowerOnKey(short%20key)

{

switch%20(key)

{

case%20KEY_ENTER:

case%20KEY_POWER:

Halt_EH0218(4);

SysInit();

break;

case%20KEY_F3:

WndPageEsc();

break;

}

}

这样的一种结构,很灵活,在主函数中只需要这样调用:

[cpp]%20view%20plain%20copy%20%20


int main(void)

{

short key;

typ_msg_word smw;

SysInit();

for ( ; ; )

{

/*

界面刷新

*/

WndOnPaint();

/*

消息处理

*/

smw.s_word = sys_msg(SM_STAY_AWAKE); //用SM_GOTO_SLEEP串口就不能用

//按键处理

if (smw.bits.key_available)

{

LcdOffDelay(LCD_OFF_DELAY);

key = KEY_read();

if (key != -1)

{

WndOnKey(key);

}

}

//插入充电电源

if (smw.bits.charger_on)

{

LcdOffDelay(LCD_OFF_DELAY);

}

//断开充电电源

if (smw.bits.charger_off)

{

LcdOffDelay(LCD_OFF_DELAY);

RefreshBattery();

}

//串口

if (smw.bits.comm_data)

{

CommReceive();

}

//实时任务

if (smw.bits.time_out)

{

TimTaskProc();

}

}

}

 

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

在现代电子技术的快速发展中,单片机以其高度的集成性、稳定性和可靠性,在工业自动化、智能家居、医疗设备、航空航天等诸多领域得到了广泛应用。S32单片机,作为其中的佼佼者,其引脚功能丰富多样,是实现与外部设备通信、控制、数据...

关键字: s32单片机引脚 单片机

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备
关闭
关闭