找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6054|回复: 10
收起左侧

AT89C2051单片机单键控制掉电并锁定四路音频切换电路和程序

[复制链接]
ID:213173 发表于 2017-6-25 08:59 | 显示全部楼层
1.采用内含EEPROM的单片机,把操作数据保存,下次开机读取保存的操作数据控制相应电路,如STC15F104等
2.AT89C2051+外接EEPROM,把操作数据保存,下次开机读取保存的操作数据控制相应电路,如AT24CXX系列
3.使用充电电池,只单独给4017保持供电,4017静态电流不到1mA,4个晶体管换为MOS管,以降低4017电耗
回复

使用道具 举报

ID:213173 发表于 2017-7-1 09:58 | 显示全部楼层
jimi123 发表于 2017-6-30 15:13
我想用STC15F104,能否给具体的电路和程序

给你写了程序和电路图: 图片.png

#include "STC15W104.H"                                 //单片机头文件
//#include "STC15F104.H"                                 //单片机头文件
#include <intrins.h>                                //库头文件
#define uint unsigned int                         //宏定义数据类型uint
#define uchar unsigned char                 //宏定义数据类型uchar
/**宏定义ISP的操作命令****/
#define CMD_IDLE    0               //空闲模式
#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令
#define ENABLE_IAP  0x82            //CPU的等待时间
#define IAP_ADDRESS 0x0400                        //测试地址
/********端口定义*********/
sbit OUT1=P3^0;                                                //输出端口定义
sbit OUT2=P3^1;
sbit OUT3=P3^2;
sbit OUT4=P3^3;
sbit CN  =P3^4;                                                //备用端口定义
sbit key =P3^5;                                                //按键端口定义       
/*******变量声明**********/
uchar ch;                                                        //中间变量
uint  tim;                                                        //键值变量
bit   flag=0;                                                //操作标志
/******子程序声明*********/
void keyscan();                                                //按键识别子程序声明
void key_service();                                 //按键服务程序声明
void Preservation();                                //写入状态数据
/****EEPROM操作程序声明****/
void IapIdle();                                                //关闭IAP/EEPROM
uchar IapReadByte(uint addr);                //读取EEPROM数据
void IapProgramByte(uint addr, uchar dat);//写入EEPROM数据
void IapEraseSector(uint addr);                //擦除EEPROM数据

/*******主函数*************/
void main()                                               
{
        P3M1 = 0x00;                                         //设置P3.0~P3.3推挽模式:0000 0000
        P3M0 = 0x0f;                                         //设置P3.0~P3.3推挽模式:0000 1111
        tim=IapReadByte(IAP_ADDRESS);        //程序开始时读取EEPROM中数据               
        if((tim<1)||(tim>4))                        //判断读取的键值数据是否有效
        {
                tim=0;                                                //键值数据无效即清0
        }
        while(1)
        {
                keyscan();                                        //按键识别程序
                key_service();                                //按键服务程序
                Preservation();                                //保存键值程序
                P1=ch;                                                //输出状态
        }
}
/*********按键识别子程序**********/
void keyscan()
{
        static bit key_sign=0;                //按键自锁标志
        static uchar count=0;                //消抖计数变量                       
        if(key==0)                                        //检测按键如果为0
        {
                count++;                                //消抖计数
                if(count>=100)                        //100次检测按键如果为0
                {                       
                        count=100;                        //防止溢出
                        if(key_sign==0)                //按键自锁标志为0
                        {
                                key_sign=1;                //按键自锁标志置1
                                flag=1;                        //操作标志置1
                                tim++;                        //状态变量自+1               
                                if(tim>4)                //如果tim>4
                                  tim=0;                //tim>4清0
                        }
                }
        }
        else
        {
                key_sign=0;                                //按键自锁标志清0
                count=0;                                //消抖计数清0
        }
}
/*********按键服务程序**********/
void key_service()
{
        switch(tim)
        {
                case 0: ch=0xf0;                 //备用端输出高电平
                break;

                case 1: ch=0xe1;                //第1通道输出高电平
                break;

                case 2: ch=0xe2;                //第2通道输出高电平
                break;

                case 3: ch=0xe4;                //第3通道输出高电平
                break;

                case 4: ch=0xe8;                //第4通道输出高电平
                break;
        }
}
/*********保存键值数据程序**********/
void Preservation()
{
        if(flag==1)                                                //如果操作标志为1
        {
                flag=0;                                                //操作标志清0
                IapEraseSector(IAP_ADDRESS);//擦除EEPROM数据
                IapProgramByte(IAP_ADDRESS,tim);//写入EEPROM数据
        }
}
/**********关闭IAP功能************/
void IapIdle()
{
    IAP_CONTR = 0;                  //关闭IAP功能
    IAP_CMD = 0;                    //清除命令寄存器
    IAP_TRIG = 0;                   //清除触发寄存器
    IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}
/***从ISP/IAP/EEPROM区域读取一字节***/
uchar IapReadByte(uint addr)
{
    uchar dat;                      //数据缓冲区
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
    IapIdle();                      //关闭IAP功能
    return dat;                     //返回数据
}
/***写一字节数据到ISP/IAP/EEPROM区域***/
void IapProgramByte(uint addr, uchar dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();                      //关闭IAP功能
}
/***ISP/IAP/EEPROM扇区擦除****/
void IapEraseSector(uint addr)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_ERASE;            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();                      //关闭IAP功能
}

4路记忆控制器.zip (57.33 KB, 下载次数: 64)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表