矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
楼主: jxjie1314

求助;51单片机独立按键长按加减键四位数码管就显示0000

[复制链接]
     
 楼主| 发表于 2019-8-27 11:14:06 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2019-8-27 11:30:18 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-27 11:39 编辑
jxjie1314 发表于 2019-8-27 11:14
发射部分临时搭了一电路,用单片机可以控制,程序用你原来写的,后来修改的也试了没有问题,没有存储功能 ...


http://www.crystalradio.cn/forum ... &extra=page%3D1
这有存储的程序,直接复制上去就能用了。。要是89C52得改两个字节
把IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
改成
IAP_TRIG = 0x46;               
IAP_TRIG = 0xb9;              
不是的话就不用改了。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-27 12:23:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-27 18:17:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2019-8-27 20:44:13 | 显示全部楼层
jxjie1314 发表于 2019-8-27 18:17
我还是搞不定,还得麻烦你,

这有存储的程序,直接复制上去就能用了。。要是89C52得改两个字节

你只复制EEPROM的程序粘贴到你的程序啊,你直接把我的下载进去当然不行了。。。
好吧,我明早帮你复制到你的程序里,要稍微改改的。哎。。。。。。。。
回复 支持 反对

使用道具 举报

     
发表于 2019-8-27 20:49:45 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-27 20:51 编辑
jxjie1314 发表于 2019-8-27 18:17
我还是搞不定,还得麻烦你,

这有存储的程序,直接复制上去就能用了。。要是89C52得改两个字节


啊,这么明显,怎么会看不到呢?我这不同的分开了的,方便移植,明天帮你揉合到你的程序中去。。。
QQ浏览器截图20190827204813.png
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-27 21:09:28 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2019-8-27 22:53:35 | 显示全部楼层
jxjie1314 发表于 2019-8-27 21:09
我下载你的程序解压后全部打不开,看不到你图片里这些代码,我先把你图片里的抄到我的程序里试试,如果可 ...

不会吧,怎么会打不开,能打开的啊。。我下载下来都能打开。。。
别根据图片写,截图只是一部分,还有一大截没截上啊。
回复 支持 反对

使用道具 举报

     
发表于 2019-8-27 22:59:19 | 显示全部楼层
也好,你先自己试试,这样才能学到东西,都帮你写好了,光下载进去学不到东西,唯一的好处就是有个参考,实在不行我明天帮你弄。。
回复 支持 反对

使用道具 举报

     
发表于 2019-8-28 08:23:12 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-28 08:27 编辑

#include "reg52.h"
#include "intrins.h"

typedef unsigned char u8;
typedef unsigned int u16;

sfr IAP_DATA    =   0xE2;           //Flash data register
sfr IAP_ADDRH   =   0xE3;           //Flash address HIGH
sfr IAP_ADDRL   =   0xE4;           //Flash address LOW
sfr IAP_CMD     =   0xE5;           //Flash command register
sfr IAP_TRIG    =   0xE6;           //Flash command trigger
sfr IAP_CONTR   =   0xE7;           //Flash control register

#define ENABLE_IAP 0x82                   //if SYSCLK<20MHz

#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令

#define cunchudizhi 0                                //频率存放地址
#define cunchubiaozhi 0xcb

#define p2 P2                                                   //把大写改成小写,打字累
#define p1 P1                                                   //按Caps Lock键也是要花力气的

sbit      jia      =P2^3;                  //频率增加键
sbit      jian    =P2^2;                  //频率递减键

u16 pinlv;                                                        //频率,请看拼音
bit jishi;                                                        //延时用

char chufa;                                                          //按键触发值
int zijia;                                                         //消抖计时
bit zisuo;                                                          //按键自锁,短按避免重复触发
bit changanbiaozhi;                                        //长按标志

sbit      key_LTS_KZ     =P2^1;     //立体声控制键
sbit      LTS_LED        =P3^3;     //立体声显示//INT1
sbit      CE             =P3^4;     //锁存信号//CE
sbit      CLK            =P3^5;     //时钟信号//CLK
sbit      DA             =P3^6;     //数据信号//DA                          

bit        modo;                                     //立体声数据寄存器

#define duanan 10                                        //100毫秒为短按
#define changan 100                                           //1秒以上为长按
#define lianxuchufa 5                                //连续触发时间为50毫秒一次

unsigned char code shuju[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

void yanshi(int a)
{
        while(a)
        {
                if(jishi)
                {
                        jishi=0;
                        a--;
                }                                               
        }
}

void nop(void)
{
        _nop_();
        _nop_();       
}

void IapIdle()                                                   //关闭IAP
{
        IAP_CONTR=0;                                         //关闭IAP功能
        IAP_CMD  =0;                                         //清除命令寄存器
        IAP_TRIG =0;                                         //清除触发寄存器
        IAP_ADDRH=0X80;                                         //将地址设置到非IAP区域
        IAP_ADDRL=0;
}

u8 durom(u16 addr)                                           //从ISP/IAP/EEPROM区域读取一个字节
{
        u8 dat;                                                         //数据缓冲区
        IAP_CONTR=ENABLE_IAP;                        //使能IAP           同时设置等待时间
        IAP_CMD=CMD_READ;                                //设置IAP命令
        IAP_ADDRL=addr;                                         //设置IAP低地址
        IAP_ADDRH=addr>>8;                                //设置IAP高地址
        IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
    IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
        _nop_();                                                //等待ISP/IAP/EEPROM操作完成
        dat=IAP_DATA;                                        //读ISP/IAP/EEPROM数据
        IapIdle();                                                //关闭IAP功能        
        return dat;                                                 //返回
}  

void xierom(u16 addr,u8 dat)                //写一个字节数据到ISP/IAP/EEPROM区域
{
        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 = 0x46;                //Send trigger command1 (0x46)
    IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
        _nop_();                                                //等待ISP/IAP/EEPROM操作完成
        IapIdle();                                                //关闭IAP功能  
}                  

void cachu(u16 addr)                                   //扇区擦除
{
        IAP_CONTR=ENABLE_IAP;                        //使能IAP         同时设置等待时间
        IAP_CMD=CMD_ERASE;                            //设置IAP命令
        IAP_ADDRL=addr;                                         //设置IAP低地址
        IAP_ADDRH=addr>>8;                                //设置IAP高地址
        IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
    IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
        _nop_();                                                //等待ISP/IAP/EEPROM操作完成
        IapIdle();                                                //关闭IAP功能
}

void xianshi(void)
{
        p2&=0x0f;                                                  //先关位选
        if(pinlv/1000)                                        //如果频率超过100兆赫兹就显示
        {       
                p1=shuju[pinlv/1000%10];        
                p2|=0x10;                         
        }
        yanshi(10);
        p2&=0x0f;
        p1=shuju[pinlv/100%10];
        p2|=0x20;       
        yanshi(10);
        p2&=0x0f;
        p1=shuju[pinlv/10%10]-0x80;
        p2|=0x40;
        yanshi(10);
        p2&=0x0f;
        p1=shuju[pinlv%10];
        p2|=0x80;
        yanshi(10);
}

void anjian(void)
{
        if(jia&&jian&&key_LTS_KZ)                  //如果没按键按下
        {
                zijia=0;                                           //清除自加计时
                zisuo=0;                                          //置零按键自锁
                changanbiaozhi=0;                         //清除长按标志
        }
        else if(zisuo==0)                                  //如果有按键按下
        {
                zijia++;                                          //消抖计时自加
                if(zijia>duanan)                           //如果加到设定时间
                {
                        zijia=0;                                 //置零自加计时
                        if(!jia)
                        chufa=1;                                //触发1号键
                        if(!jian)
                        chufa=2;                                //触发2号键
                        if(!key_LTS_KZ)
                        chufa=3;                                //触发立体声按键
                        zisuo=1;                                   //按键自锁
                }
        }
        else
        {
                zijia++;                                        //消抖计时自加
                if(changanbiaozhi)                            //如果连续触发为1
                {                                         
                        if(zijia>lianxuchufa)         //如果消抖时间达到连续触发时间
                        {
                                zijia=0;
                                if(!jia)
                                chufa=1;                        //触发1号键
                                if(!jian)
                                chufa=2;                        //触发2号键
                        }
                }
                else
                {                                                                                                             
                        if(zijia>changan)                 //如果自加超过设定的长按时间
                        zijia=0,
                        changanbiaozhi=1;                 //开启长按标志
                }
        }
}

///*************************写数据函数*********************************
//将数据送入BH1415中
//*********************************************************************
void send_16data(u16 Data,u8 MODO)
{
        u8 i;
        CLK=0;
        CE=0;
        CE=1;                                                          //连续保存高电平,可输入数据
        for(i=11;i>0;i--)
        {
                DA=Data & 0x01;                                //传输BH1415F2个字节频率控制11位D0-D10频率数据
                Data>>=1;
                nop();
                CLK=1;
                nop();
                CLK=0;
        }
        DA=MODO;
        nop();
        CLK=1;                                                   //MONO
        nop();
        CLK=0;
        nop();
        DA=0;
        nop();                                               
        CLK=1;   
        nop();
        CLK=0;
        nop();
        DA=0;
        nop();
        CLK=1;  
        nop();
        CLK=0;   
        nop();
        DA=1;
        nop();
        CLK=1;   
        nop();
        CLK=0;
        nop();
        DA=0;
        nop();
        CLK=1;   
        nop();
        CLK=0;
        CE=0;                                               //输入数据结束
}

void baocunpinlv(void)                                //保存频率值,下次开机自动进入保存值
{
        cachu(cunchudizhi);                                                                                               
        xierom(cunchudizhi,cunchubiaozhi);                                                        
        xierom(cunchudizhi+1,pinlv>>8);
        xierom(cunchudizhi+2,pinlv);
}

void chushihuapinlv(void)                        //初始化频率
{                                                                        //如果EEPROM存储地址读数不为存储标志,代表没保存
        if(durom(cunchudizhi)!=cunchubiaozhi)       
        {
                pinlv=9790;                                        //那么频率为97.9MHZ
                baocunpinlv();                                //保存频率至EEPROM
        }
        else
        pinlv=(u16)durom(cunchudizhi+1)<<8|durom(cunchudizhi+2);
}

void main(void)
{
        TMOD=0x01;  
        TH0=0xfc;
        TL0=0x18;                                                                                                   
        TR0=1;
        ET0=1;
        EA=1;
        chushihuapinlv();
        send_16data(pinlv,modo);
        while(1)
        {
                if(chufa==1)
                {
                        chufa=0;
                        pinlv++;
                        if(pinlv>1080)
                        pinlv=875;
                        baocunpinlv();
                        send_16data(pinlv,modo);
                }
                else if(chufa==2)
                {
                        chufa=0;
                        pinlv--;
                        if(pinlv<875)
                        pinlv=1080;
                        baocunpinlv();
                        send_16data(pinlv,modo);
                }
                else if(chufa==3)
                {
                        chufa=0;
                        modo=~modo;
                        LTS_LED=~modo;  //打开关闭立体声
                        send_16data(pinlv,modo);       
                }
                xianshi();
        }
}

void dingshiqi(void) interrupt 1
{
        static char a;
        TH0=0xfc;
        TL0=0x18;
        jishi=1;
        a++;
        if(a>10)
        a=0,
        anjian();
}

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-28 10:32:22 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-28 10:34:56 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2019-8-28 10:40:23 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-28 10:49 编辑
jxjie1314 发表于 2019-8-28 10:34
我的解压工具有问题,后来重新下载过一个解压工具就可以解压


pinlv=9790;                                        //那么频率为97.9MHZ
这一句有问题。改成979.我是直接复制的我的。
但是我的108.0是10800。你的是1080.
也可以随便等于1个,就算不改也没事,只要按过按键之后,这一句也没什么用了。。。
我用97.9M是因为我的电路从理论上来看,这个频率应该是发射功率最大的。。。所以用97.9。。实际上可以随便定义。。。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2019-8-28 17:44:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
发表于 2019-8-28 19:15:24 | 显示全部楼层
本帖最后由 isoimg2130 于 2019-8-28 19:19 编辑

如果是STC89C52那么现在的程序是可以的。如果AT89C52不是,那不行。如果是其他STC也不行。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-5-6 11:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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