嵌入式应用之-初始化部分

举报
内核笔记 发表于 2021/06/08 23:39:20 2021/06/08
【摘要】 main 是我们的一个入口函数,那么再开始运行任务之前我们应该做些什么? main 1、 问题:stm32 睡眠模式默认debug端口不打开,设置DBGMCU_STANDBY可以打开。 问题:在调试模式下,内核被调试器停止时,相关外设是否同时停止. 比如定时器输出,如果是连接了电机什么的时候,调试到某个地方断点了,默认定时器会继续跑,这时电机电流可能会失...

main 是我们的一个入口函数,那么再开始运行任务之前我们应该做些什么?

main

1、

问题:stm32 睡眠模式默认debug端口不打开,设置DBGMCU_STANDBY可以打开。

问题:在调试模式下,内核被调试器停止时,相关外设是否同时停止. 比如定时器输出,如果是连接了电机什么的时候,调试到某个地方断点了,默认定时器会继续跑,这时电机电流可能会失控烧电路,设置了对应的位后,定时器会停止,输出会固定在CCMR设置的电平. 对于串行通信,内核停止并且设置了对应的位,数据就有可能发了一半停下来,等内核跑了再继续发,这样数据时序就不对了,但这种情况对于分析内核与数据间的时序是有帮助的.

因此我们可以在程序开始时设置DBGMCU.

 DBGMCU_Config(DBGMCU_STANDBY,ENABLE);

  
 
  • 1

stm32f10x_dbgmcu.c 库函数:

void DBGMCU_Config(u32 DBGMCU_Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE)
  {
DBGMCU->CR |= DBGMCU_Periph;
  }
  else
  {
DBGMCU->CR &= ~DBGMCU_Periph;
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2、
/=========关闭JTAG-DP,启用SW-DP,SWJ_CFG[2:0]=010===========/

#if(SYSTEM_RUN_IN_DEBUG==GAL_YES)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
#else
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
#endif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3、PWR包括功耗管理和低功耗模式选择。(电源管理也是必不可少的)

void WKUP_Init(FunctionalState nEn)
{ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0); GPIO_Init(GPIOA, &GPIO_InitStructure); PWR_ClearFlag(PWR_FLAG_WU); PWR_WakeUpPinCmd(nEn);
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4、看门狗是防止程序跑飞

void ClearWatchDog(void)
{
#if(SYSTEM_RUN_IN_DEBUG==GAL_NO)
IWDG_ReloadCounter();
#endif
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5、低功耗处理I/O口

void InitialIOInLowCost(void)
{
//以下代码是控制低功耗的关键。
//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SRAM, DISABLE);
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FLITF, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, DISABLE); //S1:关闭除RCC_APB1Periph_PWR外的全部时钟;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, ENABLE);

 //---- 把GPIO_Init 的结果直接运行,降低运行时间-------

GPIOA->CRL=0X44444444;
GPIOA->CRH=0X44444444;

GPIOB->CRL=0X44444444;
GPIOB->CRH=0X44444444;

GPIOC->CRL=0X44444444;
GPIOC->CRH=0X44444444;

GPIOD->CRL=0X44444444;
GPIOD->CRH=0X44444444;

GPIOE->CRL=0X44444444;
GPIOE->CRH=0X44444444;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);/* 唤醒按键和电源检测输入口时钟使能 */

uInitIRWakeupStatus();  /* 红外唤醒初始化 */

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

}

5、初始化应该是个连续的过程应该这里有相关数据的初始化,但不能保证初始化过程中不会掉电,因此我们这里还要增加掉电复位等处理。

首先看看我们的运行模式有哪些:

#define AC_POWER_ON 0
#define AC_POWER_OFF 1


#define SYSTEM_RESET 1
#define POWER_ON 0
#define WAIT_MODE 2
#define STOP_MODE 3
#define IDLE_MODE 4
#define POWER_OFF 5
#define SYSTEM_GETRTC   6

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

检测函数:

unsigned char GetACPowerStatus(void)  //交流电检测
{
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
//--AA是否是市电上电判断管脚AA-- GPIO_InitStructure.GPIO_Pin = (IN_PECHK_PIN );
  GPIO_Init(IN_PECHK_PORT, &GPIO_InitStructure); if(IfPowerDown())
  {
  return (AC_POWER_OFF);
  }
  else
  {
  return (AC_POWER_ON);
  }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

#

/掉电检测
uchar IfPowerDown(void)
{ uchar ucTem,ucData; ucTem=8; ucData=0; while(ucTem) { ucData+=GetPowerSupplyStatus(); ucTem--; } if(ucData<4) { return 1; } return 0;
//  if(1==GetPowerSupplyStatus())
//  {
// return 0;
//  }
//  return 1;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

#

#define GetPowerSupplyStatus() (GPIO_ReadInputDataBit(IN_PECHK_PORT,IN_PECHK_PIN))

  
 
  • 1

判断后初始化函数:

uchar RunCPUToDifferentPowerMode(uchar Mode)

uchar RunCPUToDifferentPowerMode(uchar Mode)
{
  //ulong ulTempTest;
#if(CONFIG_METER_PREPAY_MODE != CONFIG_METER_PREPAY_MODE_DISABLE) uchar ucTempStatus;
#endif
uchar ucTemp1;
uchar Staks;

InitWatchDog();
ClearWatchDog(); switch(Mode) { case SYSTEM_RESET: ; case POWER_ON: ; case POWER_OFF: ; default: ; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

#

InitializeVariable

uchar InitializeVariable(uchar Mode)
{
  ulong ulTempTest, ulTime;
  uchar ucTempStatus;
  uint ucRemteTimesCount;
#if(HAVING_PROGRAMKEY== GAL_YES)
  uint uiTempProgramTime;
#endif
 // uchar ucSystemRestOk;
 //STR_CALENDAR FMtime;
  uchar Staks,uchannel;
  //gucSystemRestOk=0; switch(Mode) { case SYSTEM_RESET:  ///停电唤醒初始化 ; case POWER_ON: ; case POWER_OFF: ; default : ; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

文章来源: xuesong.blog.csdn.net,作者:内核笔记,版权归原作者所有,如需转载,请联系作者。

原文链接:xuesong.blog.csdn.net/article/details/78143707

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。