单键开关电路已经广泛应用于PDA、手机和电子词典等数码产品中,其实现方式多种多样。一般可采用RS触发器、计数器以及采用555集成电路等等。在单片机的一些实际应用中,以上的实现方式会增加整个电路的复杂度,不能达到简洁、实用的效果。本文将介绍一种可以在单片机应用中实现的,简易、稳定的轻触式单键开关电路。
MCU用的是AVR 的ATMEGA16L,电源芯片用的是LM2576-3.3,是低电平开启的,有些电源芯片用的是高电平开启。图中有标注。
这个是不能复位的版本。一复位就会关机。就是只有上电复位。
说明一下第一个电路工作原理:
S2按下后,D3,Q1,Q3导通,输出低电平给LM2576的判断控制端。稳压芯片工作,为单片机供电。单片机马上将相应的I/O引脚置为输出高,这时Q1和Q2及Q3都导通,整个电路进入工作状态。而后单片机再将这个I/O引脚设置为输入,由于开启AVR单片机IO的内置上拉电阻,Q1和Q2和Q3一直导通。单片机一直扫描相应I/O输入状态,如果S2没有按下去,则这个I/O将始终为高。当S2再次按下去时,D4导通,单片机检测到这个I/O引脚输入为低,此时作些延时,看延时合不合预先设定的值,达到则将单片机的这个I/O设置成输出为低的状态。Q2截止,如果按键抬起,Q1也会截止,稳压芯片将不会为单片机提供电压,整个电路处于关断状态。
注意,C10是必不可少的,不然由于单单片机的复位操作会使系统断电。
进入正常工作后,就将正常工作的代码写入EEPROM。关机时将正常关机的代码也写入EEPROM。这样,还可以检测是不是正常关机。
最后,奉上这些boot代码:
//*****************************GCC for the new lab board ******************************
//****************************** code 02 ***********************************************
#include
#include
#include
#include
#define POWER PB0
#define LED PD7
#define ON 0x0f
#define OFF 0xf0
//******************************向UART 写一字节**************************************
int usart_putchar(char c)
{
if(c==
)
usart_putchar( );
loop_until_bit_is_set(UCSRA,UDRE);
UDR=c;
return 0;
}
//*******************************从UART 读一字节*************************************
int usart_getchar(void)
{
loop_until_bit_is_set(UCSRA,RXC);
return UDR;
}
//************************************初始化i/o**************************************
void Initialuart(void)
{
//UART 初始化
UCSRB=_BV(RXEN)|_BV(TXEN);/*(1< UBRRL=25; //9600 baud 6MHz:38 4MHz:25
//i/o 流UART 连接
fdevopen(usart_putchar,usart_getchar,0);
}
//*********************************to start the power,hehe***************************
void Powerpost(void)
{
unsigned long i="0";
unsigned char val;
DDRB&=~_BV(POWER);
PORTB|=_BV(POWER);
eeprom_busy_wait();
val=eeprom_read_byte(0); //从EEPROM 0 地址处读取一字节赋给RAM 变量val
if(val==OFF)
{
//if(PIND&_BV(K4)) _delay_ms(500);if(PIND&_BV(K4))
while(!(PINB&_BV(POWER))) {i++;if(i>300000) break;}
if(i>=300000)
{
DDRB|=_BV(POWER);
PORTB|=_BV(POWER);
eeprom_busy_wait(); //等待EEPROM 读写就绪
eeprom_write_byte(0,ON); //将0xbb 写入到EEPORM 0 地址处
DDRD|=_BV(LED);
PORTD|=_BV(LED);
}
else
{
eeprom_busy_wait(); //等待EEPROM 读写就绪
eeprom_write_byte(0,OFF); //将0xbb 写入到EEPORM 0 地址处
DDRB|=_BV(POWER);
PORTB&=~_BV(POWER);
DDRD|=_BV(LED);
PORTD&=~_BV(LED);
}
}
else
{
DDRD|=_BV(LED);
PORTD|=_BV(LED);
DDRB|=_BV(POWER);
PORTB|=_BV(POWER);
eeprom_busy_wait(); //等待EEPROM 读写就绪
eeprom_write_byte(0,ON); //将0xbb 写入到EEPORM 0 地址处
}
}
//************************************Shut Down *************************************
void ShutDown(void)
{
unsigned long i="0";
while(!(PINB&_BV(POWER))) {i++;if(i>200000) break;}
if(i>=200000)
{
eeprom_busy_wait(); //等待EEPROM 读写就绪
eeprom_write_byte(0,OFF); //将OFF 写入到EEPORM 0 地址处
PORTD&=~_BV(LED);
DDRB|=_BV(POWER);
PORTB&=~_BV(POWER);
}
}
//************************************the entrey*************************************
int main()
{
Powerpost();
Initialuart();
printf("hello,你好吗?嘿嘿!!
");
// PORTB=0x00;
while(1)
{
ShutDown();
}
}
祝大家成功!!!
文章评论(0条评论)
登录后参与讨论