完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
以下是功能实现其中的DMA中断服务函数,你先自己参考参考吧,我最近忙
void DMA1_Channel1_IRQHandler(void) { float Voltage = 0; //电压变量 float Thermistor = 0; //热敏电阻阻值变量 int Temp = 0; //热敏电阻测出的温度变量 if(DMA_GetITStatus(DMA1_IT_TC1)) { //电压采样处理 Voltage = g_ADCConvertedValue[2]*3.3/4096; #if DEBUG /*if(++g_Printf_Count > 300) { g_Printf_Count = 0; printf("Voltage = %fn", Voltage); }*/ #endif Voltage *= VOLTAGE_FACTOR; Voltage += 0.35; if(Voltage < voltage_sill) //电压值低于阀值 { if(++g_VoltageLow_Count > 10 ) { g_VoltageLow_Count = 0; g_VoltageLow_Flag = 1; //设置电压过低的标志 g_VoltageLow_Flag_backup = 1; //设置电压过低标志的备份 } g_VoltRecovery_Count = 0; } else if(Voltage > voltage_sill + 0.5) { if(g_VoltageLow_Flag_backup) //电压过低标志的备份置1表示电压曾经过低,现在表示电压恢复 { if(++g_VoltRecovery_Count > 10 ) { g_VoltRecovery_Count = 0; g_VoltageLow_Flag_backup = 0; g_VoltageLow_Flag = 2; } } else { g_VoltRecovery_Count = 0; } g_VoltageLow_Count = 0; } else { g_VoltRecovery_Count = 0; g_VoltageLow_Count = 0; } //热敏电阻采样处理,根据计算公式可得Rt = R1*U0/(2*U1-U0), //或者Rt = R1*U0/(Vcc-U0) if(2*g_ADCConvertedValue[1] > g_ADCConvertedValue[0]) { Thermistor = (float)(10.0*g_ADCConvertedValue[0]/(2*g_ADCConvertedValue[1]-g_ADCConvertedValue[0])); Temp = ThermalLookUp(Thermistor); //从热敏电阻阻值查表得到相应温度 if(Temp < HEAT_TEMPERATURE2) //低于二级温度阀值 { if(++g_ThermalCount > 200) //当时间超过2秒时,应该设置加热标志 { g_ThermalCount = 0; g_ThermalHeat_Flag = 2; } } else if(Temp < HEAT_TEMPERATURE1) { if(++g_ThermalCount > 200) { g_ThermalCount = 0; g_ThermalHeat_Flag = 1; } } else { g_ThermalCount = 0; g_ThermalHeat_Flag = 0; } #if DEBUG //if(++g_Printf_Count > 200) //{ // g_Printf_Count = 0; // printf("Vol0 = %f,Vol1 = %fn",g_ADCConvertedValue[0]*3.3/4096,g_ADCConvertedValue[1]*3.3/4096); // printf("Thermistor = %fn", Thermistor); // printf("Temperature = %dn", Temp); //} #endif } else { g_ThermalCount = 0; g_ThermalHeat_Flag = 0; } DMA_ClearITPendingBit(DMA1_IT_GL1); } } |
|
|
|
davidliu9518 发表于 2019-2-27 08:49 我先看看,又不明白的再请教你,谢谢你了! |
|
|
|
davidliu9518 发表于 2019-2-27 08:49 你的这个里面没有写怎么进入睡眠,还有进入之后怎么唤醒?在DMA中断中检测电压低于阈值多长时间置标志位,高于设定阈值请标志位,但始终没有写怎么进入睡眠。 |
|
|
|
这里只是中断服务函数,中断服务函数里面,仅仅读取电压(DMA会循环把ADC寄存器的数据扫到内存变量里),处理几个全局的标志而已,主程序里面会对这些标志进行判断,然后才进行相应的处理(比如休眠等等);至于多长时间置标志位,这个你可以自行设定,计时我是用的定时器累加实现计时的。差不多低于阀值300ms就会置标志位,然后主程序在循环中发现该标志位,就会进入休眠。至于怎么唤醒,这个也是主程序里实现的。在休眠之前会配置好几个外部中断,只要触发,就会唤醒。
|
|
|
|
davidliu9518 发表于 2019-2-27 09:28 谢谢你的回复,我明白你的意思,但是我现在的问题是调用进入睡眠的库函数就是进不到睡眠,请问你的主程序中进入睡眠是怎么进去的吗?我的进入睡眠的代码如下: RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_DeInit(); PWR_BackupAccessCmd(DISABLE); SCB->SCR &= 0xFFFFFFF0; // SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,DISABLE); NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,DISABLE); PWR_EnterSleepMode(PWR_SLEEPEntry_WFE); // __WFE; 不知道那里出问题了,就是进不了睡眠。求帮忙指点,谢谢! |
|
|
|
stop_mode:
#if DEBUG printf("S Mn"); #endif RTC_Configuration(); //PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问 //RTC_ITConfig(RTC_IT_ALR, ENABLE); //RTC_WaitForLastTask(); //RTC_ClearFlag(RTC_FLAG_SEC); //while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET); //RCC_ClearFlag(); //set the all GPIO as general GPIO 、remap IRDA in EXIT0 and disable TIM4 interrupt lowLevelGPIOCfg(); ADC_Cmd(ADC1, DISABLE); DMA_Cmd(DMA1_Channel1, DISABLE); WireControl_EXTI_Enable(); GPIO_ResetBits(Led_Power, Led_Power_Pin); //GPIO_SetBits(Led_Power, Led_Power_Pin); BKP_WriteBackupRegister(BKP_DR3, 0xFFFF); //设置为睡眠状态 #if DEBUG GPIO_SetBits(GPS_ON,GPS_ON_Pin); #endif //Enter a stop mode //Request to enter STOP mode with regulator in low power mode, wake by any exit interrupt IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetReload(0xffe); IWDG_ReloadCounter(); GPIO_SetBits(LED_SD1_G, LED_SD1_G_Pin); GPIO_SetBits(LED_SD2_G, LED_SD2_G_Pin); GPIO_SetBits(LED_CAM1, LED_CAM1_Pin); GPIO_SetBits(LED_CAM2, LED_CAM2_Pin); mcu_iwdg_flag = 1; delay_ms(RESET_INTERVAL); EXTI_ClearITPendingBit(ACC_EXTI_Line | EXTI_Line0 | EXTI_Line17 | EXTI_Line11); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); GPIO_ResetBits(LED_SD1_G, LED_SD1_G_Pin); GPIO_ResetBits(LED_SD2_G, LED_SD2_G_Pin); GPIO_ResetBits(LED_CAM1, LED_CAM1_Pin); 这个是我进入睡眠的代码, PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); 这里是进入睡眠的地方,睡眠需要注意的是,睡眠前清理一下中断悬挂 EXTI_ClearITPendingBit(ACC_EXTI_Line | EXTI_Li..... ,配置好外部中断。 如果睡眠之前有独立看门狗的话,需要另外的处理。 |
|
|
|
睡眠之前有一些其他的操作,主要是关闭一些外设,这个是出于睡眠功耗的考虑。你根据你的外设情况自己定。
|
|
|
|
其实建议你单独,做一个小程序,仅仅做一个进入休眠的小程序,自己测试一下。排除其他因素的干扰,你看能不能行。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2046 浏览 0 评论
STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
1212 浏览 0 评论
2803 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2574 浏览 3 评论
5254 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-12 18:30 , Processed in 0.531866 second(s), Total 55, Slave 50 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号