OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8050|回复: 3

FREERTOS 移植到STM32F030中 使用RTC报警唤醒后,任务进不去

[复制链接]

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2017-12-28
在线时间
3 小时
发表于 2018-5-31 20:11:19 | 显示全部楼层 |阅读模式
1金钱
FREERTOS 移植到STM32F030中  进入空闲任务低功耗WFI模式  使用RTC报警唤醒后,RTC外部中断可以进去,但是,任务一直呈现阻塞态 任务进不去


/**
  ******************************************************************************
  * @file    Project/STM32F0xx_StdPeriph_Templates/main.c
  * @Author  MCD Application Team
  * @version V1.5.0
  * @date    05-December-2014
  * @brief   Main program body
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_rtc.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx.h"
#include "myiic.h"
#include "bmi160.h"
#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"
#include "six_axis_sensor_app.h"
#include "led_app.h"
#include "adc.h"


#define LED_RCC_GPIO  RCC_AHBPeriph_GPIOC
#define LED_GREEN_GPIO  GPIOC
#define LED_GREEN_PIN   GPIO_Pin_13
#define LED_GREEN_ON   GPIO_ResetBits(LED_GREEN_GPIO,LED_GREEN_PIN)
#define LED_GREEN_OFF    GPIO_SetBits(LED_GREEN_GPIO,LED_GREEN_PIN)
void delay_ms(u16 nms);
void delay_us(u32 nus);
void delay_base_us(void);
void start_task(void *pvParameters);
void task1_task(void *pvParameters);
void task2_task(void *pvParameters);
static void RtcInit(void);
static void RTC_AlarmConfig(void);

static void SystemHumanDetectFunction(void);


//任务优先级
#define START_TASK_PRIO  1
//任务堆栈大小
#define START_STK_SIZE   128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_TASK_PRIO  2
//任务堆栈大小
#define TASK1_STK_SIZE   128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);
//任务优先级
#define TASK2_TASK_PRIO  3
//任务堆栈大小
#define TASK2_STK_SIZE   128  
//任务句柄 刚好
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);
//////////////////////////////////////////////
#define HUMAN_DETECT_TASK_PRIO  3
//任务堆栈大小
#define HUMAN_DETECT_STK_SIZE   128  
//任务句柄 刚好
TaskHandle_t HumanDetectHandler;
//任务函数
void HumanDetectTask(void *pvParameters);
//////////////////////光采样/////////////////
#define LIGHT_DETECT_TASK_PRIO  3
//任务堆栈大小
#define LIGHT_DETECT_STK_SIZE   128  
//任务句柄 刚好
TaskHandle_t LightDetectHandler;
//任务函数
void LightDetectTask(void *pvParameters);
///////////////////////////////////////////
u8 id;
u16 delay_time=0;
int main(void)
{
  SystemCoreClockUpdate();
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//DelayInit();
RtcInit();
RTC_AlarmConfig();
LEDGreenInit();
  //LedObjInit();
//Adc_Init();
  //HumanDetectTaskInit(10,(sHumanDetect*)&System.Module.HumanDetect);

  //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
  /*while(1)
{
  delay_time=Bmi160ReadTemperature(&Bmi160);
  I2CREAD_BMI160_gry(&Bmi160);
  I2CREAD_BMI160_acc(&Bmi160);
  I2CREAD_BMI160_step(&Bmi160);
  Bmi160GetPowerMode();
  if(Bmi160.acc_x>=50)
  {
   LED_GREEN_ON;
  }
  else
  {
   LED_GREEN_OFF;
  }
  delay_ms(50);
//  LED_GREEN_ON;
//  delay_ms(50);
//  LED_GREEN_OFF;
}
  */
     
}
static uint8_t EnHumanDetectFlag=0;
void HumanDetectTask(void *pvParameters)
{
while(1)
{
  if(EnHumanDetectFlag==1u)
  {
    HumanDetectMainTask((sHumanDetect*)&System.Module.HumanDetect);
    SystemHumanDetectFunction();
  }
  else
  {
   
  }
  vTaskDelay(System.Module.HumanDetect.TaskHandleTime);  
}
}
void LightDetectTask(void *pvParameters)
{
static uint16_t ad_value=0;
static uint16_t human_cnt=0;
while(1)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
{
    ad_value=Get_Adc_Average(LIGHT_ADC_CHANNEL,1);
  if(ad_value>3300u)//2.5v  0.91M和光敏分压
  {
   human_cnt++;
   if(human_cnt>=3u)
   {
    human_cnt=0;
    EnHumanDetectFlag=1;
   }
  }
  else if(ad_value<3500u)
  {
   //EnHumanDetectFlag=0;
   human_cnt=0;
  }
  vTaskDelay(100);  
}
}
//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,            
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    /*xTaskCreate((TaskFunction_t )HumanDetectTask,     
                (const char*    )"HumanDetectTask",   
                (uint16_t       )HUMAN_DETECT_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )HUMAN_DETECT_TASK_PRIO,
                (TaskHandle_t*  )&HumanDetectHandler);
   
  xTaskCreate((TaskFunction_t )LightDetectTask,     
                (const char*    )"LightDetectTask",   
                (uint16_t       )LIGHT_DETECT_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LIGHT_DETECT_TASK_PRIO,
                (TaskHandle_t*  )&LightDetectHandler);
//six_axis_sensor_task_creat(); */  
   
   
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}
//task1任务函数
static uint8_t TaskInCnt=0;
void task1_task(void *pvParameters)
{
while(1)
{
  /*delay_time=Bmi160ReadTemperature(&Bmi160);
  I2CREAD_BMI160_gry(&Bmi160);
  I2CREAD_BMI160_acc(&Bmi160);
  I2CREAD_BMI160_step(&Bmi160);
  Bmi160GetPowerMode();
  if(Bmi160.acc_x>=50)
  {
   LED_GREEN_ON;
  }*/
  /*else
  {
   LED_GREEN_OFF;
  }*/
  TaskInCnt++;
  if(TaskInCnt>=100)
  {
   TaskInCnt=0;
  }
  if(TaskInCnt>=50)
  {
   TaskInCnt=0;
   //LED_GREEN_ON;
  }
  else
  {
   //LED_GREEN_OFF;
  }
  vTaskDelay(100);                           //延时1s,也就是1000个时钟节拍
}
}
void RTC_IRQHandler(void)
{   
static unsigned char test=0;
if(test==0)
{
  test=1;
LED_GREEN_OFF;
}
else
{
  test=0;
  LED_GREEN_ON;
}
xTaskResumeFromISR(Task1Task_Handler);
/*如果函数xTaskResumeFromISR()返回值为pdTRUE,那么说明要恢复的这个
任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),所以在
退出中断的时候一定要进行上下文切换!*/

portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
if(RTC_GetITStatus(RTC_IT_ALRA)!= RESET)//闹钟中断
{
  RTC_ClearITPendingBit(RTC_IT_ALRA);  //清闹钟中断      
  }  
EXTI_ClearITPendingBit(EXTI_Line17);

}

void LEDGreenInit(void)
{
GPIO_InitTypeDef        GPIO_InitStructure;
  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(LED_RCC_GPIO, ENABLE);
  /* Configure PC10 and PC11 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = LED_GREEN_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(LED_GREEN_GPIO, &GPIO_InitStructure);
  LED_GREEN_OFF;
}
void LedGreenLow(void)
{
LED_GREEN_ON;
}
void LedGreenHigh(void)
{
LED_GREEN_OFF;
}


void SystemWfiPreProcessing(void)
{
  uint32_t tmpreg = 0;
  
  /* Select the regulator state in STOP mode ---------------------------------*/
  tmpreg = PWR->CR;
  /* Clear PDDS and LPDSR bits */
  tmpreg &= ((uint32_t)0xFFFFFFFC);
  
  /* Set LPDSR bit according to PWR_Regulator value */
  tmpreg |= PWR_Regulator_LowPower;
  
  /* Store the new value */
  PWR->CR = tmpreg;
  
  /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}  

void PreSleepProcessing(uint32_t ulExpectedIdleTime)//进入休眠
{
GPIO_InitTypeDef        GPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC  | RCC_AHBPeriph_GPIOF, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 |GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_11 |GPIO_Pin_12   |GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC,GPIO_Pin_14 | GPIO_Pin_15);
GPIO_SetBits(GPIOC,GPIO_Pin_13);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

GPIO_SetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_7);
GPIO_ResetBits(GPIOF,GPIO_Pin_0 | GPIO_Pin_1);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
SystemWfiPreProcessing();
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, DISABLE);
}

void PostSleepProcessing(uint32_t ulExpectedIdleTime)//退出休眠
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);
}
//////////////////////////////////////////
static void RtcInit(void)
{
RTC_TimeTypeDef RTC_TimeStructure;
RTC_InitTypeDef RTC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
/* Reset back up registers */
RCC_BackupResetCmd(ENABLE);
RCC_BackupResetCmd(DISABLE);
/* Enable the LSE */
RCC_LSEConfig(RCC_LSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Set RTC calendar clock to 1 HZ (1 second) */
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0xFF;
if (RTC_Init(&RTC_InitStructure) == ERROR)
{
  while(1);
}
/* Set the time to 01h 00mn 00s AM */
RTC_TimeStructure.RTC_H12     = RTC_H12_AM;
RTC_TimeStructure.RTC_Hours   = 0x00;
RTC_TimeStructure.RTC_Minutes = 0x00;
RTC_TimeStructure.RTC_Seconds = 0x00;
RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);
}
static void RTC_AlarmConfig(void)
{
RTC_TimeTypeDef  RTC_TimeStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* EXTI configuration */
EXTI_ClearITPendingBit(EXTI_Line17);//清除外部中断,RTC中断函数里面每次都要清除
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Alarm Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 0x0;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes =0x0;
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds =0x0;
RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_All;

RTC_SetAlarm(RTC_Format_BCD, RTC_Alarm_A, &RTC_AlarmStructure);
RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0x7f, RTC_AlarmSubSecondMask_SS14_7);

/* Enable the RTC Alarm A interrupt */
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
/* Enable the alarm */
RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
/* Clear the Alarm A Pending Bit */
RTC_ClearITPendingBit(RTC_IT_ALRA);
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-6-1 01:20:25 | 显示全部楼层
进入待机模式试试。
待机模式相当于重启,应该可以。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2017-12-28
在线时间
3 小时
 楼主| 发表于 2018-6-1 08:42:00 | 显示全部楼层
正点原子 发表于 2018-6-1 01:20
进入待机模式试试。
待机模式相当于重启,应该可以。

原子哥  想问下 STM32F030的FreeRtOs 通过移植F103的空闲任务进入IDLE的WFI模式下 有什么需要注意的吗?StandBy模式如果相当于重启的话  程序唤醒又从哪里开始执行?
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2017-12-28
在线时间
3 小时
 楼主| 发表于 2018-6-1 09:54:22 | 显示全部楼层
使用STANDBY模式    按照我写的程序  RTC是1s  唤醒一次,但是测试结果发现是140MS唤醒一次,我觉得程序不是被唤醒了而是GG了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表