历史上的今天
返回首页

历史上的今天

今天是:2024年11月02日(星期六)

2021年11月02日 | stm32实用篇2: 裸机系统实现多任务轮转

2021-11-02 来源:eefocus

在裸机系统中,通常都是在一个大的 while 循环中,通过判断标志位,来按照顺序执行相应的代码。为了加快响应速度,较为常见的做法是中断中修改标志位,代码中判断标志位,如下所示:


int main(void)

{

  XX_Init();

 

  /* while 中判断标志位 */

  while (1)

  {

    if (flag0 == 1)

    {

      code0;

      flag0 = 0;

    }

 

    if (flag1 == 1)

    {

      code1;

      flag1 = 0;

    }

 

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

  }

}

 

/* 中断服务函数中修改标志位 */

void Handler0(void)

{

  flag0 = 1;

}

 

void Handler1(void)

{

  flag1 = 1;

}

       上述处理在裸机系统中比较常用,也足以实现很多的功能。但一种更为高级的处理方式,就是利用 SysTick 来实现类似于实时操作系统的调度,来看一下是怎么实现的:


/* 定义2个任务 */

#define NumOfTask     2

/* 任务的时基数组,由SysTick中断服务函数更新 */

unsigned int Task_Delay[NumOfTask]={ 0 };  

 

int main(void)

{

  XX_Init();

  /* 开启系统滴答定时器 */

  SysTick_Init();

 

  /* 所有的任务会按照延时,准时唤醒执行 */

  while (1)

  {

    if (Task_Delay[0] == 0)

    {

      /* 任务 0 主体 */

      Task(0);

      /* 任务 0 延时 1000ms */

      Task_Delay[0] = 1000;

    }

 

    if (Task_Delay[1] == 0)

    {

      /* 任务 1 主体 */

      Task(1);

      /* 任务 1 延时 500ms */

      Task_Delay[1] = 500;

    }

 

    /* 下面是增加任务的格式 */

    if (Task_Delay[i] == 0)

    {

      /* 任务 i 主体 */

      Task(i);

      /* 任务 i 延时 */

      Task_Delay[1] = 

    }

  }

}

 

/* 滴答定时器中断服务函数中对所有任务更新时基 */

void SysTick_Handler(void)

{

  unsigned char i;

  for (i = 0; i < NumOfTask; i++)

  {

    if (Task_Delay[i])

    {

      Task_Delay[i]--;

    }

  }

}

       接下来是一个参考代码,主要实现的功能是,led灯 1 秒状态翻转一次(任务1),串口 0.5 秒打印一次数据(任务)2。


#include "stm32f10x.h"

#include "stm32f10x_it.h"

#include "./systick/bsp_SysTick.h"

#include "./led/bsp_led.h"

#include "./usart/bsp_usart.h"

#include "./mpu6050/mpu6050.h"

#include "./i2c/bsp_i2c.h"

 

 

#define TASK_ENABLE 0

extern unsigned int Task_Delay[NumOfTask];

 

/**

  * @brief  主函数

  * @param  无  

  * @retval 无

  */

int main(void)

{

short Acel[3];

short Gyro[3];

float Temp;

SysTick_Init();

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;

/* LED 端口初始化 */

LED_GPIO_Config();

/* 串口通信初始化 */

USART_Config();

 

//I2C初始化

I2C_Bus_Init();

//MPU6050初始化

MPU6050_Init();

//检测MPU6050

if (MPU6050ReadID() == 1)

{

while(1)

{

if(Task_Delay[0] == 0)

{

LED2_TOGGLE;

Task_Delay[0]=1000;

}

if(Task_Delay[1] == 0)

{

MPU6050ReadAcc(Acel);

printf("加速度:%8d%8d%8d",Acel[0],Acel[1],Acel[2]);

MPU6050ReadGyro(Gyro);

printf("    陀螺仪%8d%8d%8d",Gyro[0],Gyro[1],Gyro[2]);

MPU6050_ReturnTemp(&Temp);

printf("    温度%8.2frn",Temp);

                /* 更新一次数据,可根据自己的需求,提高采样频率,如100ms采样一次 */

Task_Delay[1]=500;

}

 

* 下面是增加任务的格式 *

if(Task_Delay[i] == 0)

{

Task(i);

Task_Delay[i]=;

}

 

}

 

}

else

{

printf("rn没有检测到MPU6050传感器!rn");

LED_RED; 

while(1);

}

}

 

 

/**

  * @brief  启动系统滴答定时器 SysTick

  * @param  无

  * @retval 无

  */

void SysTick_Init(void)

{

/* SystemFrequency / 1000    1ms中断一次

* SystemFrequency / 100000 10us中断一次

* SystemFrequency / 1000000 1us中断一次

*/

if (SysTick_Config(SystemCoreClock/1000))

/* Capture error */ 

while (1);

}

// 关闭滴答定时器  

SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;

}

 

/**

  * @brief SysTick 中断服务函数 更新时基

  */

void SysTick_Handler(void)

{

unsigned char i;

for(i=0;i {

if(Task_Delay[i])

{

Task_Delay[i]--;

}

}

}

推荐阅读

史海拾趣

Caddell-Burns Manufacturing公司的发展小趣事

Caddell-Burns Manufacturing公司的创立源于两位创始人Caddell和Burns的远见卓识。上世纪80年代初,电子制造业正值蓬勃发展之际,两人看到了其中的商机,决定联手创办一家专注于电子零部件生产的公司。他们凭借自己的技术背景和行业经验,成功研发出了几款具有竞争力的产品,并逐渐在市场上站稳脚跟。在创业初期,公司虽然规模不大,但凭借过硬的产品质量和良好的客户服务,赢得了客户的信任和支持。

FORMOSA公司的发展小趣事

在半导体技术日新月异的时代,一家名为“FORMOSA半导体科技”的公司凭借其在先进制程技术上的突破,迅速在行业内崭露头角。该公司专注于研发和生产高性能的处理器和存储器芯片,为智能手机、数据中心等高端应用提供核心动力。通过持续的研发投入和与全球顶尖科技公司的合作,FORMOSA半导体科技成功打破了多项技术壁垒,其产品在市场上赢得了广泛赞誉。公司还积极响应绿色环保的号召,推出了一系列低功耗、高效率的半导体解决方案,为可持续发展贡献力量。

Defense Supply Center Columbus公司的发展小趣事

在电子行业,人才是企业最宝贵的财富。Defense Supply Center Columbus公司高度重视人才战略的实施。公司积极引进和培养各类人才,建立起一支高素质、专业化的团队。公司注重员工的培训和发展,为员工提供良好的工作环境和职业发展机会。同时,公司还建立了完善的激励机制和绩效考核体系,激发员工的工作积极性和创造力。这些人才战略的实施,为公司的发展提供了有力的人才保障和智力支持。

请注意,以上故事均为虚构内容,旨在展示Defense Supply Center Columbus公司可能的发展路径和故事框架。实际情况可能因公司具体情况和市场环境而有所不同。

Acmelux Taiwan Inc公司的发展小趣事

Acmelux Taiwan Inc公司深知人才是企业发展的根本。因此,公司高度重视人才培养和团队建设。通过设立完善的培训体系、提供广阔的发展平台以及实施激励机制,Acmelux吸引了大批优秀人才的加入。这些人才在公司的发展过程中发挥了重要作用,为公司创造了巨大的价值。同时,公司还注重团队建设,通过定期的团建活动、培训等方式,增强员工的凝聚力和向心力,为公司的发展提供了有力的保障。

Defender Security公司的发展小趣事

随着云计算的普及,企业对于云安全的需求日益增长。Defender Security公司敏锐地捕捉到了这一市场趋势,迅速推出了云安全服务产品。他们通过整合先进的安全技术和专业的安全团队,为企业提供了全方位的云安全保护。随着云安全服务的不断拓展和优化,Defender Security逐渐成为了云安全领域的领军企业。

Advanced Energy公司的发展小趣事

AE公司一直将创新作为企业发展的核心动力。公司不断投入研发资源,推动电源技术的持续创新。同时,AE公司也积极与各大电子企业建立合作伙伴关系,共同推动电子行业的发展。通过与合作伙伴的紧密合作,AE公司不仅获得了更多的市场机会,也提升了自身的技术水平和创新能力。

问答坊 | AI 解惑

在WinCE 下,冷启之后,如何使文件不丢失(不管放在哪个目录下)

如题, 已经正确启动模拟器,但是,模拟器存放的文件里面,只要重启,就会丢失这些文件, 各位高手帮帮给些意见…

查看全部问答>

遇到 VXworks 下 Intel 82541千兆网卡驱动的问题

    在VXWORKS5.5下调试82541的网卡驱动,一开始VXWORKS加载时提示CHECK CAPBLE CONNECTION ! 如何修改了MIILIB.C中的MIIAUTONEGSTART与MIIAUTOPHYINIT函数? 就可以正常启动也可以PING通了,FTP也可以连上,但是无法通过FTP传输文件.请 ...…

查看全部问答>

rom boot loader在wince 5.0的应用问题?

有人实现过rom boot loader吗? 我用的板子是研华的pcm3370 有谁能告知,rom boot loader怎么烧写到开发板上的? 它的程序与硬件相关,怎么改?                       ...…

查看全部问答>

使用过泰文输入法的XDJM看过来

请教大家, 泰文中, 由于主导字符是单独的一个字符, 随从字符也是单独的一个字符, 结加后如何显示.使用自造字吗?或者是GB18030字符集已经有了组合后的编码.…

查看全部问答>

关于ADC基准的问题

                                 在用户手册里找不到如何把基准电压设置为外部基准,怎样设置成使用外部基准?如果要采样温度是不是只能使用内部基 ...…

查看全部问答>

stm8s207spi通信

新手 spi和一块射频芯片通信 不知道该怎么解决了 希望论坛上的高手能够帮帮忙 1、我的初始化程序 //时钟 CLK_ICKR = (1 << HSIEN);//HSI ENABLE; while((CLK_ICKR & 0X02) == 0);//WAITE FOR HSI STEABLE CLK_CKDIVR = 0X10;//HS ...…

查看全部问答>

报警???

本帖最后由 dontium 于 2015-1-23 13:22 编辑 这是什么原因引起的报警啊? 报警如下(用的是CCS2.0): >> warning: creating output section .vectors without SECTIONS specification …

查看全部问答>

欢迎各位前来指导!

小弟初次接触振荡电路,求大侠分析该怎么算这个振荡电路的参数(频率,幅值等),谢谢了啊!或者是提供一种分析思路也可以啊!     …

查看全部问答>

求介绍一些能够高精度控制的仪器或者传感器

跟着老板做一些直线电机方面的研究,关键时候缺少了一个能高精度测量微位移的仪器,精度um级别的,能达到nm的更好,有没有大神能够给介绍一下。…

查看全部问答>