STM8L学习笔记 -- HALT模式
因为项目上需要用STM8L,从零接触这个片子,学习用遇到了很多问题,大部分都解决。现把学习的点滴做个记录,分享给大家,有问题也请大家指正。
该系列低功耗分五级:
● Wait mode
● Low power run mode
● Low power wait mode
● Active-halt mode
● Halt mode
我的产品,电池供电,大部分时间处于休眠,少数时间工作。因此经过权衡我选用片外32.768K作为主时钟,休眠方式采用halt,唤醒方式采用RTC的alarm和按键,使能了看门狗。
下面的是代码,有看门狗部分,HALT进入和唤醒(RTC和按键唤醒)。
1、如果不进入halt模式,可以看到单片机的LED在闪烁;
一旦进入halt模模式,LED停止工作,说明CPU停机模式。
2、定时3分钟,3分钟到,触发ALARM中断,LED开始继续闪烁。
3、按键按下,也会唤醒单片机LED闪烁。
4、如果不喂看门狗,可以发现模块一直在重启,说明看门狗是正常工作的。
分享代码如下:
main()
{
GPIO_Initialization(); //LED
//USART
GPIO_Init(GPIOC,GPIO_Pin_2,GPIO_Mode_In_PU_No_IT);
GPIO_Init(GPIOC,GPIO_Pin_3,GPIO_Mode_Out_PP_Low_Fast);
CLK_PeripheralClockConfig(CLK_Peripheral_USART1,ENABLE);
USART_DeInit(USART1);
USART_Init(USART1,9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,(USART_Mode_TypeDef)(USART_Mode_Rx|USART_Mode_Tx));
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
RTC_Config();
watchdog_init();
enableInterrupts();
Sent_String("start\r\n",strlen("start\r\n"));
eeprom_test();
Sent_String(GBuffer,strlen(GBuffer));
halt();
while (1)
{
IWDG_ReloadCounter();
Led_Ctrol();
}
}
void GPIO_Initialization(void)
{
/* Push-button initialization */
GPIO_Init(BUTTON_GPIO_PORT, FUNCTION_GPIO_PIN, GPIO_Mode_In_FL_IT);
/* Led ports initialization */
GPIO_Init(LED_GR_PORT, LED_GR_PIN, GPIO_Mode_Out_PP_Low_Fast);
GPIO_Init(LED_BL_PORT, LED_BL_PIN, GPIO_Mode_Out_PP_Low_Fast);
/* PC0 in output push-pull low because never used by the application */
//GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_PP_Low_Slow);
EXTI->CR1 = 0x00; /* PC1 (push-button) ext. interrupt to falling edge low level */
}
void Led_Ctrol(void)
{
GPIO_WriteBit(LED_GR_PORT, LED_GR_PIN, 1);///GPIO_ToggleBits(LED_GR_PORT, LED_GR_PIN);
// GPIO_WriteBit(LED_BL_PORT, LED_BL_PIN, 0);//GPIO_ToggleBits(LED_BL_PORT, LED_BL_PIN);
delay_ms(500);
GPIO_WriteBit(LED_GR_PORT, LED_GR_PIN, 0);///GPIO_ToggleBits(LED_GR_PORT, LED_GR_PIN);
// GPIO_WriteBit(LED_BL_PORT, LED_BL_PIN, 1);//GPIO_ToggleBits(LED_BL_PORT, LED_BL_PIN);
delay_ms(500);
}
void RTC_Config(void)
{
/* Enable RTC clock */
CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
/* Wait for LSE clock to be ready */
while (CLK_GetFlagStatus(CLK_FLAG_LSERDY) == RESET);
/* wait for 1 second for the LSE Stabilisation */
LSE_StabTime();
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
/* Configures the RTC wakeup timer_step = RTCCLK/16 = LSE/16 = 488.28125 us */
//RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);
RTC_InitStr.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStr.RTC_AsynchPrediv = 0x7F;
RTC_InitStr.RTC_SynchPrediv = 0x00FF;
RTC_Init(&RTC_InitStr);
RTC_TimeStructInit(&RTC_TimeStr);
RTC_TimeStr.RTC_Hours = 01;
RTC_TimeStr.RTC_Minutes = 00;
RTC_TimeStr.RTC_Seconds = 00;
RTC_SetTime(RTC_Format_BIN, &RTC_TimeStr);
/* Enable wake up unit Interrupt */
RTC_AlarmCmd(DISABLE);
RTC_AlarmStructInit(&RTC_AlarmStr);
RTC_AlarmStr.RTC_AlarmTime.RTC_Hours = 01;
RTC_AlarmStr.RTC_AlarmTime.RTC_Minutes = 03;
RTC_AlarmStr.RTC_AlarmTime.RTC_Seconds = 01;
RTC_AlarmStr.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
RTC_SetAlarm(RTC_Format_BIN, &RTC_AlarmStr);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(ENABLE);
RTC_ITConfig(RTC_IT_WUT, DISABLE);
}
#define RELOAD_VALUE 254
void watchdog_init(void)
{
IWDG_Enable(); //必须放前面,否则后面设时间不起作用
/* Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
/* Set IWDG timeout */
IWDG_SetPrescaler(IWDG_Prescaler_256);
IWDG_SetReload(RELOAD_VALUE);
/* Refresh IWDG */
IWDG_ReloadCounter();
}
void eeprom_test(void)
{
uint32_t add, startadd, stopadd = 0;
uint8_t newval = 0xAA;
uint8_t i = 0;
startadd = FLASH_DATA_EEPROM_START_PHYSICAL_ADDRESS + ((uint16_t)BLOCK_OPERATION * (uint16_t)FLASH_BLOCK_SIZE);
stopadd = startadd + (uint16_t)FLASH_BLOCK_SIZE;
/* Define flash programming Time*/
FLASH_SetProgrammingTime(FLASH_ProgramTime_Standard);
FLASH_Unlock(FLASH_MemType_Program);
/* Wait until Flash Program area unlocked flag is set*/
while (FLASH_GetFlagStatus(FLASH_FLAG_PUL) == RESET)
{}
/* Unlock flash data eeprom memory */
FLASH_Unlock(FLASH_MemType_Data);
/* Wait until Data EEPROM area unlocked flag is set*/
while (FLASH_GetFlagStatus(FLASH_FLAG_DUL) == RESET)
{}
for (i = 0; i < 10; i++)
{
FLASH_ProgramByte(startadd+i, i*10);
}
/* Wait until End of high voltage flag is set*/
while (FLASH_GetFlagStatus(FLASH_FLAG_HVOFF) == RESET)
{}
for (add = 0; add < 10; add++)
{
GBuffer = FLASH_ReadByte(startadd+add);
}
}
程序比较简单,经过实际测试,希望对大家有帮助,欢迎指正。
另外硬件使用的是stm8l discovery.
RE:STM8L学习笔记 -- HALT模式
支持:) 你这个是active-halt模式吧 同意楼上观点,如果是halt模式,外设都关完了。只有通过中断唤醒 Veiko 发表于 2015-5-14 22:48同意楼上观点,如果是halt模式,外设都关完了。只有通过中断唤醒
你好,进入halt模式要什么操作吗?我只用了一个halt()函数,
但是发现灯都还是亮的?这个正常吗?中间设置了halt之前关闭一个灯,唤醒再点亮。确实实现了,但是其他灯一直都亮着,无论进不进入halt中 谢谢分享 总结到位,学习啦! 帅鹰杨 发表于 2017-2-27 17:42
你好,进入halt模式要什么操作吗?我只用了一个halt()函数,
但是发现灯都还是亮的?这个正常吗?中间设 ...
进入halt是需要自己手动将需要关掉的都关掉的 进入halt模式只是单片机不工作了 我为什么进入HALT模式,液晶显示会暗掉。可不可以在HALT模式下液晶继续点亮啊,应该怎么做,大咖们能否帮忙一下 路过看看
页:
[1]
2