2.尝试新建ucos任务(LED闪烁)

本文详细介绍了如何使用STM32微控制器和uC/OS-II实时操作系统实现LED灯的定时闪烁功能。通过修改C文件、添加配置和集成外部库,成功在开发板上调试通过,展示了微控制器与实时操作系统的有效结合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

app.c文件修改为如下


#include <includes.h>

static void App_TaskStart(void *);
static void App_TaskCreate(void);
static  void Task_Led1(void* p_arg);
static  void Task_Led2(void* p_arg);

static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];

static  OS_STK Task_Led1Stk[Task_Led1_STK_SIZE];
static  OS_STK Task_Led2Stk[Task_Led2_STK_SIZE];

#define LED_LED1_ON()   GPIO_SetBits(GPIOB, GPIO_Pin_5 );  	       //LED1  ÁÁ
#define LED_LED1_OFF()  GPIO_ResetBits(GPIOB, GPIO_Pin_5 ); 	   //LED1  Ãð

#define LED_LED2_ON()   GPIO_SetBits(GPIOD, GPIO_Pin_6 );  	       //LED2  ÁÁ
#define LED_LED2_OFF()  GPIO_ResetBits(GPIOD, GPIO_Pin_6 ); 	   //LED2  Ãð

INT32U milsec1,milsec2;

int main(){
	CPU_IntDis();

	OSInit();
	BSP_Init();
	
	milsec1=100;
	milsec2=200;
	
	OSTaskCreate((void(*)(void *))App_TaskStart,
							(void *)0,
							(OS_STK *)&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],
							(INT8U)APP_TASK_START_PRIO);
	OSTimeSet(0);
	OSStart();
	return 0;
}

static void App_TaskStart(void * p_arg){
	(void)p_arg;
	OS_CPU_SysTickInit();
	App_TaskCreate();
	while(1){
		OSTimeDlyHMSM(0,0,1,0);
	}
}

static void App_TaskCreate(void){
	OSTaskCreateExt(Task_Led1,(void *)0,(OS_STK *)&Task_Led1Stk[Task_Led1_STK_SIZE-1],
		Task_Led1_PRIO,Task_Led1_PRIO,(OS_STK *)&Task_Led1Stk[0],
		Task_Led1_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
	OSTaskCreateExt(Task_Led2,(void *)0,(OS_STK *)&Task_Led2Stk[Task_Led2_STK_SIZE-1],
		Task_Led2_PRIO,Task_Led2_PRIO,(OS_STK *)&Task_Led2Stk[0],
		Task_Led2_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
}

static  void Task_Led1(void* p_arg)
{
   (void) p_arg;	    
   while (1)
   {
      LED_LED1_ON();
      OSTimeDlyHMSM(0, 0, 0, milsec1);
      
      LED_LED1_OFF();
      OSTimeDlyHMSM(0, 0, 0, milsec1);	
   }
}

static  void Task_Led2(void* p_arg)
{
	(void) p_arg;	    
	while(1)
	{
      LED_LED2_ON();
      OSTimeDlyHMSM(0, 0, 0, milsec2);
      
      LED_LED2_OFF();
      OSTimeDlyHMSM(0, 0, 0, milsec2);	
   }
}



BSP.c文件增加如下方法:

void RCC_Configuration(void)
{	
  SystemInit(); 
}

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB , ENABLE); 
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				                 //LED1
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);					 
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3;		 			//LED2, LED3
  GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void BSP_Init(void)
{
  /* System Clocks Configuration --72M*/
  RCC_Configuration();   

  GPIO_Configuration(); 
}


另需要在app_cfg.h文件中添加:

#define  APP_TASK_START_PRIO                               3
#define  Task_Led1_PRIO                                    7
#define  Task_Led2_PRIO                                    8

#define  APP_TASK_START_STK_SIZE                       128
#define  Task_Led1_STK_SIZE                         	 128
#define  Task_Led2_STK_SIZE                         	 128


此时编译会发现,LED灯不闪烁,需要做如下修改:


1.startup_stm32f10x_hd.s文件中,处理PendSV_Handler名称与os_cpu_a.asm文件中OS_CPU_PendSVHandler名称不匹配,需要把PendSV_Handler全部替换为OS_CPU_PendSVHandler

2.复制Keil安装目录C:\Keil_v5\ARM\Pack\Keil\STM32F1xx_DFP\1.0.5\Device\StdPeriph_Driver\templates下的stm32f10x_it.c和stm32f10x_it.h文件到APP目录下,去掉其只读属性,并添加到工程中,然后添加头文件:

#include <includes.h>


再修改SysTick_Handler函数如下:

void SysTick_Handler(void)
{
	OS_CPU_SR  cpu_sr;

	OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/
	OSIntNesting++;	   //OSSemPost(NMEA_MBOX); 
	OS_EXIT_CRITICAL();	  //恢复全局中断标志

	OSTimeTick();     /* Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到*/

	OSIntExit();  //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换    
}

本工程在奋斗V5开发板上调试通过


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值