本帖最后由 wakojosin 于 2015-6-3 16:28 编辑
现在对这个问题做一个小结吧,希望对遇到类似问题的朋友有点参考价值。如有什么不对或是不全的地方,希望大神能够指出,在此谢谢啦。
1.关于无法进入停机模式,单独运行却可以:目前的解决方法是当通过仿真器下载完程序之后,拔掉仿真器后运行就OK了,具体为什么会造成单独运行停机模式是可以的,加入其他程序就不行的原因还未知,但是这也算一个解决方法吧。
2.关于PA0的WKUP功能,从手册上看,WKUP功能是在待机模式下使用的,在停机模式下,现在的测试结果是无效,同时使能唤醒Pin功能之后对PA0的中断有影响,这个也就是造成了在进入停机模式之前,PA0的中断函数是能够进入的,但是进入停机模式之后却没有任何反应,因为在进入停机模式之前开启了WKUP功能。
3.关于USART2对PA0的影响,首先PA0的复用功能有USART_CTS,这是硬件流控制使用的,我在配置串口的时候未使用该功能,在程序测试中,USART2暂时还没有出现对唤醒功能有影响,或是PA0的设置对串口有影响的情况。
我在使用PA0中是将PA0配置成普通中断使用来唤醒停机模式的,为什么选PA0也是为了之后在待机模式上作兼容的考虑。仅供各位参考哈。
==============分=============割=============线===================
程序独立运行的时候没有问题,但是加入了串口,定时器等等,就出现问题了;其中定时器是开中断的,但是在进入停止模式之前停止了,并且做了定时器中断标志位的清除,如下:
TIM_Cmd(TIM2, DISABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_WakeUpPinCmd(ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式
SYSCLKConfig();
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
程序运行之后直接跳过了停机模式,不知道为什么,看了和试了好多例子都不行,希望大神出来指点一下吧
今天用同样的程序竟然可以进停止模式了!!原因未知好郁闷。
使用PA0的WKUP功能需要作引脚映射吗?
main.c
- #include "main.h"
- #include "stdio.h"
- void NVIC_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /* 1 bit for pre-emption priority, 3 bits for subpriority */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- /* Configure and enable SPI_MASTER interrupt -------------------------------
- NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);*/
- /* Configure and enable TIM interrupt -------------------------------*/
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- /* Configure and enable USART interrupt -------------------------------*/
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void WKUP_IOInit(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- EXTI_InitTypeDef EXTI_InitStructure;
-
- /* Enable GPIO clock */
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
-
- /* Configure EXTI0 line */
- EXTI_InitStructure.EXTI_Line = EXTI_Line0;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /* Connect EXTI0 Line to PA.00 pin */
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
- }
- void SYSCLKReConfig(void)
- {
- ErrorStatus HSEStartUpStatus;
- /* Enable HSE */
- RCC_HSEConfig(RCC_HSE_ON);
- /* Wait till HSE is ready */
- HSEStartUpStatus = RCC_WaitForHSEStartUp();
- if(HSEStartUpStatus == SUCCESS)
- {
- /* Enable PLL */
- RCC_PLLCmd(ENABLE);
- /* Wait till PLL is ready */
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
- {
- }
- /* Select PLL as system clock source */
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
- /* Wait till PLL is used as system clock source */
- while(RCC_GetSYSCLKSource() != 0x08)
- {
- }
- }
- }
- void Board_Init(void)
- {
- NVIC_Configuration();
- My_COM2_Init(9600);
- My_COM1_Init(2400);
-
- //My_ADC1_Init();//需要更换IO
- My_Delay_Init();
- TIM2_Init();
- LCD_Init();
- WKUP_IOInit();
-
- OLED_B_Init();
- delayMs(500);
- LLW_D_LoadData();
- delayMs(500);
- WIFI_Init();
- }
- uint8_t wifi_sed_s=0;
- int main(void)
- {
- char lcdstr[20];
- uint16_t gp2y10_data;
- uint8_t keyvalue;
-
- Board_Init();
- LCD_Fill(0x00);
-
- while(1)
- {
- LCD_P12x24Str(0,2,"T: H: %");
- LCD_P12x24Str(0,5,"PM2.5:");
- while(1)
- {
- gp2y10_data=10;
- while(gp2y10_data)
- {
- keyvalue=OLEDGUI_B_Read();
- if(keyvalue==0XFF)
- {
- delayMs(100);
- }
- else
- {
- break;
- }
- gp2y10_data--;
- }
- if(keyvalue==0XFF)
- {
- if(DHT11_ReadData())
- {
- sprintf(lcdstr,"T:%2d H:%2d%%",DHT11_Data[2],((DHT11_Data[0]&0XF0)>>4)*16+(DHT11_Data[0]&0X0F));
- sprintf(LLW_D_TVALUE,"%2d",DHT11_Data[2]);
- sprintf(LLW_D_HVALUE,"%2d",DHT11_Data[0]);
- LCD_P12x24Str(0,2,lcdstr);
- }
- /*if((gp2y10_data=GP2Y10_ReadData())!=0XFFFF)
- {
- sprintf(LLW_D_PVALUE,"%3d",gp2y10_data);
- LCD_P12x24Str(72,5,LLW_D_PVALUE);
- }*/
- if(wifi_sed_s)
- {
- wifi_sed_s=0;
- WIFI_D_Send();
- }
- }
- else
- {
- break;
- }
- WIFI_EN(0);
- LCD_Fill(0x00);
- TIM_Cmd(TIM2, DISABLE);
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- delayMs(10);
- /* Enable PWR and BKP clock */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
- PWR_WakeUpPinCmd(ENABLE);
- PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式
- SYSCLKReConfig();
- /* TIM2 enable counter */
- TIM_Cmd(TIM2, ENABLE);
- WIFI_EN(1);
- delayMs(20);
- }
- //进入设置
- MenuGeneralSet();
- }
- }
复制代码
|
这个WKUP唤醒是在待机模式,手册上没有对停机模式有这个描述,是写了中断唤醒。现在的状态是,拔掉仿真器的线,全部OK,再次插上线之后也是正常进入停止模式,还有唤醒。所以这个又有还多需要学习研究的了。通过断开仿真器线后正常运行程序也解释了,昨天为什么不能进入待机模式和程序不能正常跑,而今天再次运行就可以了,可能是仿真器的状态影响着单片机的程序执行,所以出现了这种效果,详情还得好好学习学习才知道了。
PA0是特殊的外部中断引脚,功能就是用来唤醒待机或者停止模式的单片机,之前拿这个脚来做普通上下拉引脚,结果死活不成功,吃亏了后来才知道,然而我的问题很奇怪,我可以进入停止模式,也可以通过外部中断唤醒进入主函数,但是重复一些次数之后就会出现程序只能运行到进入停止模式的函数体之后剩余的部分,函数体结束之后不能进入主函数,只能断电重新开启才能再次正常工作,但是多重复几次之后又会出现上面的问题,,,,就很奇怪
嗯嗯是的,用的stlink
可以的呀,在调试模式里面的低功耗模式调试支持有写可以的,只要配置一下就可以了,如果不配置,仿真会断开,而且在单独运行停止模式的时候也没有什么问题呢,就是加入了其他东西之后就不正常了。试了一下,不仿真,通过串口打印信息,也是没有达到进入低功耗的效果
main.c已经贴出来了,现在的问题是无法唤醒,用的PA0,有问题不明白,PA0中断唤醒跟其他外部中断唤醒有什么区别吗
我这边测试PA0配置可以产生中断。楼主在运行模式下,PA0是否可以产生中断?
独立运行是可以的,也是用串口2,串口1应该对PA0没有影响吧。目前中断是在while之外是可以进入的,但是进入之后也不好把握这个是否能够进入中断,因为很快就断开仿真了。没法看,在进入停止模式之前能不能进入中断函数,我再试试。关于PA0 它的复用功能有一个是WKUP,这个是指唤醒的IO吗?只是在待机模式跟其他IO有区别是吧,我从手册上理解是这样的,因为STOP模式所有EXTI都可以唤醒,但觉也就没啥区别了吧
是的是的,谢谢版主大人的指导