void Standby_Init() { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);//使能 GPIOA 和复用功能时钟 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; //PA.0 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 IO //使用外部中断方式 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //中断线 0 连接 GPIOA.0 EXTI_InitStructure.EXTI_Line = EXTI_Line0; //设置按键所有的外部线路 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模 //式:EXTI 线路为中断请求 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // 初始化外部中断 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级 2 级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级 2 级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化 NVIC Sys_Enter_Standby(); }
//中断,检测到PA0脚的一个上升沿. //中断线0线上的中断检测 void EXTI0_IRQHandler(void) { EXTI->PR=1<<0; //清除LINE10上的中断标志位 if(Check_WKUP())//关机? { Sys_Enter_Standby(); } }
void EXTI0_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位 if(Check_WKUP())//关机? { Sys_Enter_Standby(); } }
/* *@功能:在空闲状态的几个任务 *1.检测是否有按键按下 *2.检测是否读到RFID *3.检测是否接受到串口传来的指令 *4.检测是否有USB连接到计算机上 *5.检测锂电池电压是否低电 共5个任务按各自的时间轴转动,基本上无冲突 */ void ST_Idle(void) { uint16_t ss_num=0; uint16_t power_num=0; uint16_t usb_bit; uint8_t key_r=KEYNO; uint8_t usb_r=0; uint8_t bt_r=0; uint8_t time_num=0; uint8_t p_c=0; uint8_t ss_flag=0; ResetKey(); //KeyNum是一个全局变量 //Init_KeyNumuber(); //Key_Num =KEYINIT //根据flsah中的信息,更改主菜单中的信息 SPI_FLASH_Read(HsMenu[1].Name,GROUP_INFORMATION,10); SPI_FLASH_Read(HsMenu[2].Name,KEY_INFORMATION,8); // //for debug // SPI_FLASH_Read(item,GROUP_INFORMATION,10); // UART1nSendChar(1,item,10); // delay_ms(1000); // //for dedug // SPI_FLASH_Read(item,KEY_INFORMATION,8); // UART1nSendChar(1,item,8); // delay_ms(1000); //for dedug // UART1nSendChar(1,HsMenu[1].Name,10); // delay_ms(1000); // UART1nSendChar(1,HsMenu[2].Name,8); // delay_ms(1000); OLED_Clear(); ShowMenuNoInverse(HsMenu); Main_Oled_Power(); Main_Oled_Time(); //Choose_MenuOp1(); //主界面显示 while(1) { // if(g_State!=ST_IDLE) // return; if(time_num==20) { Main_Oled_Time(); time_num=0; } ++time_num; delay_ms(50); //按键按下检测,如果有按键就按下就进入菜单操作 key_r =GetKey(); //判断是否有按键操作 if(ss_flag==0&&key_r==KEYNO) //超时关屏 { ss_num++; if(ss_num>=choosetime*6)//按下超过10秒钟 300/50=6 { OLED_Display_Off(); ss_flag=1; ss_num=0; } } if(ss_flag==1&&(key_r ==KEYCLEAR||key_r ==KEYSURE||key_r ==KEYDOWN||key_r == KEYUP)) { OLED_Display_On(); ss_flag=0; ResetKey(); key_r=KEYNO; } if(key_r !=KEYNO&&key_r !=KEYINIT) { //ResetKey(); //读完按键值后,将按键值复位 g_State =ST_LCDMENU; return; //按任意按键进入可选择菜单 } // //RFID检测 // nChar =Read_RfidData(2,Rfid_Buff,0xff); //非常重要的一点,是理解Trismit()的关键 // if(nChar >=3) // { // g_State =ST_KEY;return; //检测ID信息数据,如果读到了rfid数据,则将g_State置为st_key // } //检测上位机连接下位机命令,从菜单界面进入USB通信中 usb_r =UART1ReadFrm(1,g_Buff,MAX_BUFF); //USB串口1,g_Buff是一个全局变量;#define MAX_BUFF 520 if(usb_r==7&&g_Buff[0]==0xaa&&g_Buff[1]==0x75&&g_Buff[2]==0x0d&&g_Buff[3]==0x02&&g_Buff[4]==0x00&&g_Buff[5]==0x01&&g_Buff[6]==0xD1)//如果返回0x00就发下一条授权 { usb_bit=(USB_CHEAK&(GPIO_Pin_1))>>1; if(usb_bit==1) //USB插上 { bluetooth_uart_switch=0; pc_to_slave(); //上位机连接下位机的处理 g_State =ST_USB; //进入USB通信 return; } } bt_r =UART3ReadFrm(3,g_Buff,MAX_BUFF); //蓝牙串口2,g_Buff是一个全局变量;#define MAX_BUFF 520 if(bt_r==7&&g_Buff[0]==0xaa&&g_Buff[1]==0x75&&g_Buff[2]==0x0d&&g_Buff[3]==0x02&&g_Buff[4]==0x00&&g_Buff[5]==0x01&&g_Buff[6]==0xD1)//如果返回0x00就发下一条授权 { bluetooth_uart_switch=1; pc_to_slave(); //上位机连接下位机的处理;使用接受到的g_Buff // m_UB3; // m_UB3.RBuff; g_State =ST_USB; //进入USB通信 return; } usb_bit=(USB_CHEAK&(GPIO_Pin_1))>>1; if(usb_bit==1) //USB已经插上,即从蓝牙切换到USB bluetooth_uart_switch=0; //电池电量检测 power_num++; if( power_num==0x15) //0x15*20时Power_Cheak()才会返回有效值 { power_num =0; IWDG_Feed(); Main_Oled_Power(); //更新电池电量 p_c=Power_Cheak(); //此函数运行20次才返回有效值 if(p_c==4) //检测电池电压,如果电池电压过低,则进入关机模式,并进行提示 { // Main_Oled_Time(); // Main_Oled_Power(); OLED_Show_LowBattry(); //延时1s后关机 g_WaitTimeOut = 0; SetTimer(TIMER_TIMEOUT,100,Do_TimeOut,THREE_MIN); while( g_WaitTimeOut == 0 ) { IWDG_Feed(); } KillTimer(TIMER_TIMEOUT); Sys_Enter_Standby(); } } }