2.3.1
https://www.st.com/zh/embedded-software/stsw-stm8069.html
IAR Assembler for STMicroelectronics STM8 3.11.1
https://oshwhub.com/perseverance51/stm8s207rbt6-kai-fa-ban
AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。
在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM3的输入捕捉1来测定。
/**
* @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
* @note It is recommended to use a timer clock frequency of at least 10MHz in order
* to obtain a better in the LSI frequency measurement.
* @param None
* @retval None
*/
uint32_t LSIMeasurment( void )
{
uint32_t lsi_freq_hz = 0x0;
uint32_t fmaster = 0x0;
uint16_t ICValue1 = 0x0;
uint16_t ICValue2 = 0x0;
/* Get master frequency */
fmaster = CLK_GetClockFreq();
/* Enable the LSI measurement: LSI clock connected to timer Input Capture 1 */
AWU->CSR |= AWU_CSR_MSR;
#if defined (STM8S903) || defined (STM8S103) || defined (STM8S003) || defined (STM8S001)
/* Measure the LSI frequency with TIMER Input Capture 1 */
/* Capture only every 8 events!!! */
/* Enable capture of TI1 */
TIM1_ICInit( TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0 );
/* Enable TIM1 */
TIM1_Cmd( ENABLE );
/* wait a capture on cc1 */
while( ( TIM1->SR1 & TIM1_FLAG_CC1 ) != TIM1_FLAG_CC1 );
/* Get CCR1 value*/
ICValue1 = TIM1_GetCapture1();
TIM1_ClearFlag( TIM1_FLAG_CC1 );
/* wait a capture on cc1 */
while( ( TIM1->SR1 & TIM1_FLAG_CC1 ) != TIM1_FLAG_CC1 );
/* Get CCR1 value*/
ICValue2 = TIM1_GetCapture1();
TIM1_ClearFlag( TIM1_FLAG_CC1 );
/* Disable IC1 input capture */
TIM1->CCER1 &= ( uint8_t )( ~TIM1_CCER1_CC1E );
/* Disable timer2 */
TIM1_Cmd( DISABLE );
#else
/* Measure the LSI frequency with TIMER Input Capture 1 */
/* Capture only every 8 events!!! */
/* Enable capture of TI1 */
TIM3_ICInit( TIM3_CHANNEL_1, TIM3_ICPOLARITY_RISING, TIM3_ICSELECTION_DIRECTTI, TIM3_ICPSC_DIV8, 0 );
/* Enable TIM3 */
TIM3_Cmd( ENABLE );
/* wait a capture on cc1 */
while ( ( TIM3->SR1 & TIM3_FLAG_CC1 ) != TIM3_FLAG_CC1 );
/* Get CCR1 value*/
ICValue1 = TIM3_GetCapture1();
TIM3_ClearFlag( TIM3_FLAG_CC1 );
/* wait a capture on cc1 */
while ( ( TIM3->SR1 & TIM3_FLAG_CC1 ) != TIM3_FLAG_CC1 );
/* Get CCR1 value*/
ICValue2 = TIM3_GetCapture1();
TIM3_ClearFlag( TIM3_FLAG_CC1 );
/* Disable IC1 input capture */
TIM3->CCER1 &= ( uint8_t )( ~TIM3_CCER1_CC1E );
/* Disable timer3 */
TIM3_Cmd( DISABLE );
#endif /* (STM8S903) || (STM8S103) || (STM8S003) || (STM8S001) */
/* Compute LSI clock frequency */
lsi_freq_hz = ( 8 * fmaster ) / ( ICValue2 - ICValue1 );
/* Disable the LSI measurement: LSI clock disconnected from timer Input Capture 1 */
AWU->CSR &= ( uint8_t )( ~AWU_CSR_MSR );
return ( lsi_freq_hz );
}
printf
输出函数,串口输出的信息会不完整,其中带一些乱码字符。这一点特别需要特别注意,AWU唤醒后对于其他外设功能最好再进行初始化一次,以免意外发生。typedef enum
{
AWU_TIMEBASE_NO_IT = (uint8_t)0, /*!< No AWU interrupt selected */
AWU_TIMEBASE_250US = (uint8_t)1, /*!< AWU Timebase equals 0.25 ms */
AWU_TIMEBASE_500US = (uint8_t)2, /*!< AWU Timebase equals 0.5 ms */
AWU_TIMEBASE_1MS = (uint8_t)3, /*!< AWU Timebase equals 1 ms */
AWU_TIMEBASE_2MS = (uint8_t)4, /*!< AWU Timebase equals 2 ms */
AWU_TIMEBASE_4MS = (uint8_t)5, /*!< AWU Timebase equals 4 ms */
AWU_TIMEBASE_8MS = (uint8_t)6, /*!< AWU Timebase equals 8 ms */
AWU_TIMEBASE_16MS = (uint8_t)7, /*!< AWU Timebase equals 16 ms */
AWU_TIMEBASE_32MS = (uint8_t)8, /*!< AWU Timebase equals 32 ms */
AWU_TIMEBASE_64MS = (uint8_t)9, /*!< AWU Timebase equals 64 ms */
AWU_TIMEBASE_128MS = (uint8_t)10, /*!< AWU Timebase equals 128 ms */
AWU_TIMEBASE_256MS = (uint8_t)11, /*!< AWU Timebase equals 256 ms */
AWU_TIMEBASE_512MS = (uint8_t)12, /*!< AWU Timebase equals 512 ms */
AWU_TIMEBASE_1S = (uint8_t)13, /*!< AWU Timebase equals 1 s */
AWU_TIMEBASE_2S = (uint8_t)14, /*!< AWU Timebase equals 2 s */
AWU_TIMEBASE_12S = (uint8_t)15, /*!< AWU Timebase equals 12 s */
AWU_TIMEBASE_30S = (uint8_t)16 /*!< AWU Timebase equals 30 s */
} AWU_Timebase_TypeDef;
/*******************************************************************************
**函数名称:void MyAWU_Init()
**功能描述:初始化AWU模块
**入口参数:无
**输出:无
*******************************************************************************/
void MyAWU_Init(void)
{
AWU_Init(AWU_TIMEBASE_2S); //配置自动呼醒为1秒时间呼醒CPU
AWU_Cmd(ENABLE); //使能自动呼醒功能
}
/**************************************************************************************
实验现象: 每间隔1秒自动唤醒CPU,同时使用LED1指示灯亮灭来指示唤醒状态。
接线说明: 1,STM8S单片机-->LED
PC7-->LED1
PC6-->LED2
注意事项:1、点击“Download active application”按钮,程序下载完成后,即可运行程序。
***************************************************************************************/
#include "stm8s.h" /* 添加库函数头文件 */
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "awu.h"
#include "stdio.h"
/*******************************************************************************
**函数名称:void ClockSwitch_HSE()
**功能描述:将系统时钟切换到外部高速晶振时钟
**入口参数:无
**输出:无
*******************************************************************************/
void ClockSwitch_HSE( void )
{
//启用外部高速晶振,外部晶振1-24MHz
CLK_HSECmd( ENABLE ); //使能HSE起振
while( CLK_GetFlagStatus( CLK_FLAG_HSERDY ) == RESET ); //等待HSE准备就绪
CLK_ClockSwitchCmd( ENABLE ); //使能时钟切换
CLK_ClockSwitchConfig( CLK_SWITCHMODE_AUTO, //
CLK_SOURCE_HSE, //选择外部外部晶振(24M晶振)作为系统时钟源
DISABLE, //不开启时钟切换中断
CLK_CURRENTCLOCKSTATE_ENABLE //振荡器使能
);
while( CLK_GetFlagStatus( CLK_FLAG_SWBSY ) != RESET );
CLK_SYSCLKConfig( CLK_PRESCALER_CPUDIV1 ); //如果切换成功,则设置CPU时钟为1分频,让外部晶振作为系统时钟
CLK_ClockSwitchCmd( DISABLE ); //关闭切换
CLK_HSICmd( DISABLE ); //关闭内部高速HSI
}
INTERRUPT_HANDLER(AWU_IRQHandler, 1)
{
LED1_TOGGLE;
USART1_Init( 9600 ); //唤醒后,需要重新初始化一次USART1,否则,串口话打印乱码
printf("Hello World! \r\n");
LED2_TOGGLE;
AWU_GetFlagStatus(); //通过读其状态,清除标志位
}
/* 主函数 */
int main( void )
{
disableInterrupts(); //关闭系统中断
//内部时钟为1分频 = 16Mhz
CLK_SYSCLKConfig( CLK_PRESCALER_HSIDIV1 );
// ClockSwitch_HSE(); //调用时钟切换函数 设置外部晶振(24MHz)为系统时钟
USART1_Init( 9600 ); //初始化USART1 , 并设置波特率为9600
printf("Hello World! \r\n");
LED_Init();
MyAWU_Init();
enableInterrupts(); //使能系统中断
while( 1 )
{
halt(); //进入活跃停机模式,等待AWU自动呼醒
}
}
//是一个宏定义;在固件库中,它的作用就是检测传递给函数的参数是否是有效的参数
void assert_failed( u8* file, u32 line )
{
while ( 1 )
{
}
}
链接: https://pan.baidu.com/s/1EfAirobJeSyADKLKQ5Lj1w
提取码: 6jxt