STM32入门学习笔记之uCOS-II系统移植4

电子说

1.2w人已加入

描述

首先要做根据UCOSII中定义的OS_TICKS_PER_SEC来计算出SysTick的装载值reload,开启SysTick中断,将reload值写进SysTick的LOAD寄存器中,最后开启SysTick,开启SysTick后还要编写其中断服务函数。

③微秒级别延时函数

void delay_us( u16 nus )
{
#if SYSTEM_SUPPORT_OS
  u32 ticks, told, tnow, tcnt=0 ;
  u32 reload = SysTick->LOAD ;                  //LOAD的值
  ticks = nus*fac_us ;                                        //需要的节拍数
  OSSchedLock() ;                        //禁止调度,防止打断us延时
  told = SysTick->VAL ;                                        //刚进入时的计数器值
  while( 1 )
  {
    tnow = SysTick->VAL ;
    if( tnow!=told )
    {
      //这里注意一下SYSTICK是一个递减的计数器
      if( tnowelse
        tcnt += reload-tnow+told ;
      told = tnow ;
      //时间超过/等于要延迟的时间,则退出
      if( tcnt>=ticks )
        break ;
    }
  }
  OSSchedUnlock() ;                        //UCOSII的方式,恢复调度
#else
  u32 temp ;
  SysTick->LOAD = nus*fac_us ;                  //时间加载
  SysTick->VAL = 0x00 ;                      //清空计数器
  SysTick->CTRL = 0x01 ;                    //开始倒数
  do
  {
    temp = SysTick->CTRL ;
  }while( ( temp&0x01 )&&!( temp&( 1<<16 ) ) ) ;          //等待时间到达
  SysTick->CTRL = 0x00 ;                    //关闭计数器
  SysTick->VAL = 0x00 ;                      //清空计数器
#endif
}

④毫秒级别延时函数

void delay_ms( u16 nms )
{
#if SYSTEM_SUPPORT_OS
  //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
  if( ( delay_osrunning==1 )&&( delay_osintnesting==0 ) )
  {
    //延时的时间大于OS的最少时间周期
    if( nms>=fac_ms )
      OSTimeDly( nms/fac_ms ) ;                //UCOSII延时
    nms %= fac_ms ;                      //延时太短,采用普通方式延时
  }
  delay_us( ( u32 )( nms*1000 ) ) ;                  //普通方式延时
#else
  u32 temp ;
  SysTick->LOAD = ( u32 )nms*fac_ms ;              //时间加载(SysTick->LOAD为24bit)
  SysTick->VAL = 0x00 ;                      //清空计数器
  SysTick->CTRL = 0x01 ;                    //开始倒数
  do
  {
    temp = SysTick->CTRL ;
  }while( ( temp&0x01 )&&!( temp&( 1<<16 ) ) ) ;          //等待时间到达
  SysTick->CTRL = 0x00 ;                    //关闭计数器
  SysTick->VAL = 0x00 ;                      //清空计数器
#endif
}

(5)usart1.c文件修改

①添加头文件定义

#if SYSTEM_SUPPORT_OS

#include "includes.h"

#endif

②修改串口中断服务函数

void USART1_IRQHandler()
{
#if SYSTEM_SUPPORT_OS
  OSIntEnter() ;
#endif
  //接收到数据
  if( USART1->SR&( 1<<5 ) )
  {
    if( USART1->DR=='\\n' )
    {
      USART1_Data.Len = USART1_Rx_Count ;
      USART1_Rx_Count = 0 ;
      USART1_Data.State = 1 ;
    }
    USART1_Data.Buffer[ USART1_Rx_Count ] = USART1->DR ;
    USART1_Rx_Count ++ ;
  }
#if SYSTEM_SUPPORT_OS
  OSIntExit() ;
#endif
}

23.3 实验例程

例程:利用移植完成的ucos-ii系统新建两个任务,并且在两个任务中打印自定义的任务名称。

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "includes.h"
/****************************************************
Name    :Task01
Function  :任务1
Paramater  :None
Return    :None
****************************************************/
#define TASK01_PRIO  7                                          //设置任务优先级
#define TASK01_SIZE  64                                          //设置任务堆栈大小
OS_STK TASK01_STK[ TASK01_SIZE ] ;                                    //任务堆栈
void Task01( void *pdata )
{
  while( 1 )
  {
    printf( "Task1 Run\\r\\n" ) ;
    delay_ms( 1000 ) ;
  }
}
/****************************************************
Name    :Task02
Function  :任务2
Paramater  :None
Return    :None
****************************************************/
#define TASK02_PRIO  6                                          //设置任务优先级
#define TASK02_SIZE  64                                          //设置任务堆栈大小
OS_STK TASK02_STK[ TASK02_SIZE ] ;                                    //任务堆栈
void Task02( void *pdata )
{
  while( 1 )
  {
    printf( "Task2 Run\\r\\n" ) ;
    delay_ms( 2000 ) ;
  }
}
/****************************************************
Name    :Start
Function  :开始任务
Paramater  :None
Return    :None
****************************************************/
#define START_PRIO  10                                          //开始任务的优先级设置为最低
#define START_SIZE  64                                          //设置任务堆栈大小
OS_STK START_STK[ START_SIZE ] ;                                    //任务堆栈
void Start( void *pdata )
{
    OS_CPU_SR cpu_sr=0 ;
  pdata = pdata ;
    OS_ENTER_CRITICAL() ;                                        //进入临界区(无法被中断打断)
   OSTaskCreate( Task01, ( void * )0, ( OS_STK* )&TASK01_STK[ TASK01_SIZE-1 ], TASK01_PRIO ) ;
   OSTaskCreate( Task02, ( void * )0, ( OS_STK* )&TASK02_STK[ TASK02_SIZE-1 ], TASK02_PRIO ) ;
  OSTaskSuspend( START_PRIO ) ;                                    //挂起起始任务
  OS_EXIT_CRITICAL() ;                                        //退出临界区(可以被中断打断)
}
/****************************************************
Name    :Main
Function  :主函数
Paramater  :None
Return    :None
****************************************************/
int main()
{
   STM32_Clock_Init( 9 ) ;                                        //系统时钟设置
  SysTick_Init( 72 ) ;                                        //延时初始化
  USART1_Init( 72, 115200 ) ;                                      //串口初始化为115200
  OSInit() ;
   OSTaskCreate( Start, ( void * )0, ( OS_STK * )&START_STK[ START_SIZE-1 ], START_PRIO ) ;      //创建起始任务
  OSStart() ;
   while( 1 ) ;
}

将程序下载进单片机,打开串口助手可以看到以下的效果。

uCOS-Ⅱ

通过时间可以看出,Task2的任务2s打印一次数据,Task1的任务1s打印一次数据,和我们程序所写一致,所以说明UCOS-II系统移植成功。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分