久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8098|回復: 30
收起左側

怎么把STC89C52RC單片機程式改成STC8F2K08S2的,而且要有斷電記憶?

  [復制鏈接]
ID:468169 發表于 2019-1-15 00:32 來自觸屏版 | 顯示全部樓層 |閱讀模式
500黑幣
請幫忙把STC89C52RC52程式改成STC8F2K08S2程式,還有就是我下面的程式EEPROM斷電記憶部分沒辦法記憶,有地方寫的不對,請大神幫忙修改下……。
程式如下:
//頭函數
#include <reg52.h>
#include<intrins.h>       
#define uint unsigned int
#define uchar unsigned char
#define RdCommand 0x01
#define PrgCommand 0x02                //定義ISP的操作命令
#define EraseCommand 0x03
#define Error 1
#define OK 0
#define WaitTime 0x01   //定義單片機的等待時間
sfr ISP_DATA = 0xe2;     //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0XE5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
/*========================打開ISP,IAP功能=========================*/
void ISP_IAP_enable(void)
{
EA=0;                                           /*關中斷*/
ISP_CONTR=ISP_CONTR & 0x18;                   /*0001,1000*/
ISP_CONTR=ISP_CONTR | WaitTime;           /*寫入硬件延時*/
ISP_CONTR=ISP_CONTR | 0x80;         /*ISPEN=1*/

}
/*=============關閉ISP,IAP功能===================*/
void ISP_IAP_disable(void)
{
ISP_CONTR=ISP_CONTR & 0x7f;  /*ISPEN=0*/
ISP_TRIG=0x00;
EA=1;    /*開中斷*/
}
/*================公用的觸發代碼=========*/
void ISPgoon(void)
{
ISP_IAP_enable();  /*打開ISP,IAP功能*/
ISP_TRIG=0x46;
ISP_TRIG=0xb9;
_nop_();
}
/*============字節讀=============*/
unsigned char byte_read(unsigned int byte_addr)
{
   ISP_ADDRH=(unsigned char)(byte_addr>>8);  /*地址賦值*/
   ISP_ADDRL=(unsigned char)(byte_addr & 0x00ff);
   ISP_CMD=ISP_CMD & 0xf8;   /*清楚低3位*/
   ISP_CMD=ISP_CMD | RdCommand;   /*寫入讀指令*/
   ISPgoon();       /*觸發執行*/
   ISP_IAP_disable();  /*關閉ISP,IAP功能*/
   return(ISP_DATA);    /*返回讀到的數據*/
}
/*======================扇區擦除==================*/
void SectorErase(unsigned int sector_addr)
{
   unsigned int iSectorAddr;
   iSectorAddr=(sector_addr & 0xfe00);    /*區扇區地址*/
   ISP_ADDRH=(unsigned char )(iSectorAddr>>8);
   ISP_ADDRL=0x00;
   ISP_CMD=ISP_CMD&0xf8;   /*清空低3位*/
   ISP_CMD=ISP_CMD | EraseCommand;   /*擦除命令3*/
   ISPgoon();
   ISP_IAP_disable();       /*關閉ISP,IAP功能*/
}
/*===============字節寫===============*/
void byte_write(unsigned int byte_addr,unsigned char original_data)
{
   ISP_ADDRH=(unsigned char)(byte_addr>>8);   /*取地址*/
   ISP_ADDRL=(unsigned char)(byte_addr&0x00ff);
   ISP_CMD=ISP_CMD&0xf8;  /*清空低3位*/
   ISP_CMD=ISP_CMD|PrgCommand;   /*寫命令2*/
   ISP_DATA=original_data;  /*寫入數據準備*/
   ISPgoon();      /*觸發執行*/
   ISP_IAP_disable();    /*關閉IAP功能*/
}       
uchar scale1=10;                                   //定義占空比比例,初始是50%
uchar scale=30;                //定義占空比比例,初始是50%
uint Key_num,Key_num1,num2;

bit bdata flag_add_dec=0;        //長按時是加還是減取決于此變量
bit bdata flag_add_dec1=0;        //長按時是加還是減取決于此變量  

//管腳聲明
sbit LED = P1^0;        //燈光控制輸出 1
sbit K1= P3^6;          //觸摸輸入
sbit K2= P3^7;
sbit LED1 = P1^1;    //燈光控制輸出2
sbit led3 = P1^2;
/*****************延時函數:大約1ms************************/
void delay(uchar i)
{
  uchar j,k;
  for(j=i;j>0;j--)
    for(k=121;k>0;k--);
}

/*********定時器初始化函數**********/
void init()
{
        TMOD=0x11;           //工作方式 1 定時器0,1
        TH0=0xff;
        TL0=0xe7;                //T0賦初值25us
        TH1=0xff;
        TL1=0xe7;
        EA=1;                   //中斷總開關          
        ET0=1;                   //打開中斷允許開關
        ET1=1;
        TR0=1;                   //打開定時器開關
        TR1=1;
}



/****************主函數**********************/
void main()
{
    uint l;
    uchar num1;

        init();                  //調用初始化函數

         num1=byte_read(0x2003);  //程序開始時讀取EEPROM中數據
   if(num1>=20)             //防止首次上電時讀取出錯
   num1=0;
       
        while(1)                   //循環
        {       
                if(K1==0)        //有觸摸信號                                               
                {
                        delay(20);//延時,去抖,除掉干擾信號
                        if(K1==0)        //再次判斷有觸摸信號
                        {
                                while(!K1)//觸摸信號不消失就會在此循環中
                                {       
                                        Key_num++;                   //長按計時變量加
                                        if(Key_num>=100)   //檢測到是長按(如果沒加到100就退出則執行后面的if(Key_num!=0))
                                        {
                                                Key_num=0;           //清零,執行長按功能
                                                if(TR0==1)           //在燈開著時才可以調節亮度
                                                {         
                                                        while(!K1)                                    //觸摸信號一直在,進入循環,進行加減亮度
                                                        {                                                                         

                                                                if(flag_add_dec==0)                  //是加狀態
                                                                {        l--;
                                                                        scale++;
                                                                                          //燈光比例++
                                                                        if(scale>=61)          //達到最亮
                                                                        scale=61;                  //保持最亮
                                                                        LED1=~LED;

                                                          

                                                        }               
       
                                                               
                                                               
                                                                else
                                                                {
                                                                           l++;
                                                                        scale--;                   //燈光比例--
                                                                        if(scale<=2)           //達到最暗
                                                                {
                                                                        scale=2;                   //保持最暗
                                                               
                                                                }       
                                                                       
                                                                }


                                                           delay(30);
                                                        }
                                                         
                                                        flag_add_dec=!flag_add_dec;         //執行一次長按后,此變量取反(1變0,0變1)
                                                                 if(num2>=5)
                                                         {
                                                           num2=0;
                                                           num1++;
                                                           SectorErase(0x2000);  //擦除扇區
                                                           byte_write(0x2003,num1);  //重新寫入數據
                                                           if(num1==20)
                                                           {
                                                             num1=0;
                                                           }
                                                         }

                                                }
                                        }
                                        delay(2);                  //此延時是調節長按時間的
                                }
                                if(Key_num!=0)                  //如果不是長按按鍵
                                {
                                        Key_num=0;                  //清零
                                        TR0=~TR0;                  //定時器取反,就是開關定時器,從而開關燈
                                        if(TR0==0)                  //如果是關燈時,將LED輸出置高,關閉輸出
                                        LED=1;
                                        LED1=1;
                                }       
                        }
       

                }
       
        }
}

/******************定時器T0服務函數:脈沖發生函數*******************/
void time0() interrupt 1
{
        uchar n;
        TH0=0xff;
        TL0=0xe7;                //T0賦初值10us
        n++;                         //每25us  n++
        if(n<scale)                 //n<設置比例時,打開燈
        {          
                        LED=0;  LED1=~LED;
        }
        else if(n>=scale)//n大于等于設置比例時 關閉燈
        {         
                LED=1;    LED1=~LED;
        }
        if(n==60)                 //n==40  :25us*40=1ms   1kHZ
        {
                n=0;                 //n=0
        }
       
}

void time() interrupt 3
{
        TH1=0xff;
        TL1=0xe7;                //T0賦初值12.5us
        num2++;                         //每25us  n++
       
       
}

回復

使用道具 舉報

ID:123289 發表于 2019-1-15 07:53 | 顯示全部樓層
當你能搞清51原理后,這個不難,只要看一下:【STC89C52RC52】和【STC8F2K08S2】手冊,找一下它倆的區別,就OK了。如果你的51基礎不行,就麻煩了。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:468169 發表于 2019-1-15 09:55 來自觸屏版 | 顯示全部樓層
yzwzfyz 發表于 2019-1-15 07:53
當你能搞清51原理后,這個不難,只要看一下:【STC89C52RC52】和【STC8F2K08S2】手冊,找一下它倆的區別, ...

問題是,我現在用52RC的做斷電記憶它記憶不了,我都調試很久都沒調試出來,想不到好辦法了,因為剛接觸單片機不久,好多地方沒弄懂……。
回復

使用道具 舉報

ID:351872 發表于 2019-1-15 11:57 | 顯示全部樓層
#include "reg51.h"
#include "intrins.h"

//測試工作頻率為11.0592MHz

sfr     IAP_DATA    =   0xC2;
sfr     IAP_ADDRH   =   0xC3;
sfr     IAP_ADDRL   =   0xC4;
sfr     IAP_CMD     =   0xC5;
sfr     IAP_TRIG    =   0xC6;
sfr     IAP_CONTR   =   0xC7;

#define WT_30M          0x80
#define WT_24M          0x81
#define WT_20M          0x82
#define WT_12M          0x83
#define WT_6M           0x84
#define WT_3M           0x85
#define WT_2M           0x86
#define WT_1M           0x87

void IapIdle()
{
    IAP_CONTR = 0;                              //關閉IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除觸發寄存器
    IAP_ADDRH = 0x80;                           //將地址設置到非IAP區域
    IAP_ADDRL = 0;
}

char IapRead(int addr)
{
    char dat;

    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 1;                                //設置IAP讀命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //讀IAP數據
    IapIdle();                                  //關閉IAP功能

    return dat;
}

void IapProgram(int addr, char dat)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 2;                                //設置IAP寫命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_DATA = dat;                             //寫IAP數據
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    IapIdle();                                  //關閉IAP功能
}

void IapErase(int addr)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 3;                                //設置IAP擦除命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();                                    //
    IapIdle();                                  //關閉IAP功能
}

void main()
{
    IapErase(0x0400);
    P0 = IapRead(0x0400);                       //P0=0xff
    IapProgram(0x0400, 0x12);
    P1 = IapRead(0x0400);                       //P1=0x12

    while (1);
}

這是8F系列斷電記憶的例程  你可以學習下。

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:250700 發表于 2019-1-15 14:05 | 顯示全部樓層
STC系列單片機,斷電記憶原理,硬件需要有斷電檢測電路,STC89C52RC沒有自帶檢測電路可以利用外部中斷(在電源電壓低到一個閥值、并且要高于EEPROM可以寫入電壓),若產生中斷就 保存 所有需要保存的數據,在單片機上電時讀出 上次 保存的數據,STC8F2K08S2 自帶低電壓中斷功能 可以直接 在 低壓中斷 保存數據,若不考慮 EEPROM 擦寫壽命、可以在上電 讀出 數據后 擦除 EEPROM的使用扇區,也可以 在扇區中分塊使用、一個扇區 多次使用 提高擦寫壽命。

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:468169 發表于 2019-1-15 15:48 來自觸屏版 | 顯示全部樓層
GUELL 發表于 2019-1-15 14:05
STC系列單片機,斷電記憶原理,硬件需要有斷電檢測電路,STC89C52RC沒有自帶檢測電路可以利用外部中斷(在 ...

嗯,那有STC8F2K08S2的例程嗎,最好有EEPROM這方面的……。
回復

使用道具 舉報

ID:142059 發表于 2019-1-16 09:47 | 顯示全部樓層
nanyexin 發表于 2019-1-15 09:55
問題是,我現在用52RC的做斷電記憶它記憶不了,我都調試很久都沒調試出來,想不到好辦法了,因為剛接觸單 ...

那就是你的eeprom讀寫不成功,還想什么

評分

參與人數 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:468169 發表于 2019-1-16 16:01 來自觸屏版 | 顯示全部樓層
Angle145 發表于 2019-1-16 09:47
那就是你的eeprom讀寫不成功,還想什么

我也知道是讀寫不成功呀,所以我是想不出來哪里的問題呀,所以才請教大神們呀?
回復

使用道具 舉報

ID:468169 發表于 2019-1-23 11:52 來自觸屏版 | 顯示全部樓層
5100103 發表于 2019-1-15 11:57
#include "reg51.h"
#include "intrins.h"


你好。我已經把這個EEPROM例程放進我的程式中,斷電重啟還是沒有辦法記憶,我現在用的是STC8F2K08S2這款IC。
回復

使用道具 舉報

ID:213173 發表于 2019-1-23 16:53 | 顯示全部樓層
nanyexin 發表于 2019-1-23 11:52
你好。我已經把這個EEPROM例程放進我的程式中,斷電重啟還是沒有辦法記憶,我現在用的是STC8F2K08S2這款I ...

掉電記憶是需要外部硬件支持的,否則單片機沒有電源怎么工作?如下圖,C2值遠大于C1。把寫EEPROM的程序放在外部中斷里。一旦掉電進入外部中斷,由C2維持短暫工作。 無標題.jpg

回復

使用道具 舉報

ID:468169 發表于 2019-1-24 09:15 | 顯示全部樓層
wulin 發表于 2019-1-23 16:53
掉電記憶是需要外部硬件支持的,否則單片機沒有電源怎么工作?如下圖,C2值遠大于C1。把寫EEPROM的程序放 ...

不是可以用計時器萊做計數,每幾秒寫入一次嗎?我現在用的就是這個方法,沒幾秒寫進去一次,但是我按照你說的數據手冊中一樣的EEPROM例程來帶進去裏面一點反應都沒有,是不是不能按照數據手冊的測試例程來做,,,,
回復

使用道具 舉報

ID:213173 發表于 2019-1-24 09:58 | 顯示全部樓層
nanyexin 發表于 2019-1-24 09:15
不是可以用計時器萊做計數,每幾秒寫入一次嗎?我現在用的就是這個方法,沒幾秒寫進去一次,但是我按照你 ...

看來你的單片機可能已經玩壞了。EEPROM寫入次數不是無限的,數據手冊稱30萬次。如果5秒寫1次,工作十幾天就報廢了。正確做法是每次斷電寫1次。并且輪流使用不同扇區,可以用幾十年。
STC官方例程沒有問題,參照此例程編寫的應用程序用于產品達數千件,無一意外。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:158375 發表于 2019-1-24 10:42 | 顯示全部樓層
nanyexin 發表于 2019-1-16 16:01
我也知道是讀寫不成功呀,所以我是想不出來哪里的問題呀,所以才請教大神們呀?

火氣莫要太大!
看來你還是不知道為什么實現掉電記憶。
看12樓,他說的一點沒錯。
不然,你要使用鐵電......

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:468169 發表于 2019-1-24 13:18 | 顯示全部樓層
wulin 發表于 2019-1-24 09:58
看來你的單片機可能已經玩壞了。EEPROM寫入次數不是無限的,數據手冊稱30萬次。如果5秒寫1次,工作十幾天 ...

但是我看我公司這裡用的單片機用的也是掉電記憶,他們外圍電路并沒有加大電容,也是可以做斷電記憶,那他們用的是什麼方法呢?所以我猜想是在什麼特定時間寫入的,所以我才用幾秒寫入方法來《《《《

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:468169 發表于 2019-1-24 13:22 | 顯示全部樓層
笨笨兔 發表于 2019-1-24 10:42
火氣莫要太大!
看來你還是不知道為什么實現掉電記憶。
看12樓,他說的一點沒錯。

是呀,這是個好方法,但是我看見有很多斷電記憶的單片機并沒有電解電容,那他們爲什麼可以做掉電記憶,我公司就有兩款是這樣子的,單片機外圍電路就只有幾個電阻,一個觸摸腳,一個觸摸腳靈敏度的調節電容.......

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:213173 發表于 2019-1-24 14:24 | 顯示全部樓層
nanyexin 發表于 2019-1-24 13:18
但是我看我公司這裡用的單片機用的也是掉電記憶,他們外圍電路并沒有加大電容,也是可以做斷電記憶,那他 ...

我推薦這個方法只是諸多方法之一,不同的芯片可以設計對應的方法,只要在電源電壓沒有降低到無法寫EEPROM之前完成保存數據都是可行的。STC8F2K08S2的最低工作電壓2.0V。

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:472325 發表于 2019-1-24 16:44 | 顯示全部樓層
nanyexin 發表于 2019-1-15 09:55
問題是,我現在用52RC的做斷電記憶它記憶不了,我都調試很久都沒調試出來,想不到好辦法了,因為剛接觸單 ...

1.是寫不進還是讀不出?
2.用一個簡單的代碼,那怕就用控制P/I口燈來做試驗,只要能做到記憶,后面就只是多調試的問題了

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:155507 發表于 2019-1-24 22:17 | 顯示全部樓層
樓主,注意下載時,硬件選項中的“設置用戶EEPROM大小”要選擇你需要的EEPROM大小值,否則會訪問不成功的。
解決了是下載配置的問題,把地址改成0x0000就可以了!
回復

使用道具 舉報

ID:468169 發表于 2019-1-26 01:23 來自觸屏版 | 顯示全部樓層
wulin 發表于 2019-1-23 16:53
掉電記憶是需要外部硬件支持的,否則單片機沒有電源怎么工作?如下圖,C2值遠大于C1。把寫EEPROM的程序放 ...

如果用大電容那個外部中斷該怎的設置呢?我有寫了個普通的0和1LED燈它是可以記憶的,但是我換到單鍵做無極調光里面就記憶不了,想用大電容控制寫入,但是調試了挺久都不行……。
回復

使用道具 舉報

ID:213173 發表于 2019-1-26 10:32 | 顯示全部樓層
nanyexin 發表于 2019-1-26 01:23
如果用大電容那個外部中斷該怎的設置呢?我有寫了個普通的0和1LED燈它是可以記憶的,但是我換到單鍵做無 ...

硬件連接示意圖
無標題.jpg


//基于STC8F2K64S4,測試工作頻率為11.0592MHz
//此程序使用外部中斷1(INT1),也可以選擇:
//比較器中斷(CMP),低壓檢測中斷(LVD)
//注:此程序未經實物驗證,只是提供編程思路
#include <STC8.H>
//#include "reg51.h"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit key1=P3^4;       
sbit key2=P3^5;       
sbit LED=P1^7;
uchar num=0x00;
//        關閉IAP功能
void IapIdle()
{
    IAP_CONTR = 0;             //關閉IAP功能
    IAP_CMD = 0;               //清除命令寄存器
    IAP_TRIG = 0;              //清除觸發寄存器
    IAP_ADDRH = 0x80;          //將地址設置到非IAP區域
    IAP_ADDRL = 0;
}
//從ISP/IAP/EEPROM區域讀取一字節
uchar IapRead(uint addr)
{
    uchar dat;
    IAP_CONTR = 0x83;          //使能IAP
    IAP_CMD = 1;               //設置IAP讀命令
    IAP_ADDRL = addr;          //設置IAP低地址
    IAP_ADDRH = addr >> 8;     //設置IAP高地址
    IAP_TRIG = 0x5a;           //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;           //寫觸發命令(0xa5)
    _nop_();
    dat = IAP_DATA;            //讀IAP數據
    IapIdle();                 //關閉IAP功能
    return dat;
}
//寫一字節數據到ISP/IAP/EEPROM區域
void IapProgram(uint addr, uchar dat)
{
    IAP_CONTR = 0x83;          //使能IAP
    IAP_CMD = 2;               //設置IAP寫命令
    IAP_ADDRL = addr;          //設置IAP低地址
    IAP_ADDRH = addr >> 8;     //設置IAP高地址
    IAP_DATA = dat;            //寫IAP數據
    IAP_TRIG = 0x5a;           //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;           //寫觸發命令(0xa5)
    _nop_();
    IapIdle();                 //關閉IAP功能
}
//        ISP/IAP/EEPROM扇區擦除
void IapErase(uint addr)
{
    IAP_CONTR = 0x83;          //使能IAP
    IAP_CMD = 3;               //設置IAP擦除命令
    IAP_ADDRL = addr;          //設置IAP低地址
    IAP_ADDRH = addr >> 8;     //設置IAP高地址
    IAP_TRIG = 0x5a;           //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;           //寫觸發命令(0xa5)
    _nop_();
    IapIdle();                 //關閉IAP功能
}
//初始化PWM
void PWM_Init()
{
        CCON = 0;                   //初始化PCA控制寄存器
        CL = 0;                     //復位PCA寄存器
        CH = 0;
        CMOD = 0x02;                //設置PCA時鐘源,PWM頻率=11.0592MHZ/2/256=21.600KHZ
        PCA_PWM0 = 0x00;            //PCA模塊0工作于8位PWM
        CCAP0H = CCAP0L = 0x80;     //PWM0的占空比為50%
        CCAPM0 = 0x42;              //PCA模塊0為8位PWM模式
        CR = 1;                     //PCA定時器開始工作
}
void keyscan()
{
        static uint count1=0,count2=0;       
        if(!key1)//亮度增加
        {
                if(++count1>=2000)
                {                       
                        count1=0;
                        if(num>0x00)
                                num--;
                }
        }
        if(!key2)//亮度減弱
        {
                if(++count2>=2000)
                {                       
                        count2=0;
                        if(num<0xcc)//亮度下限
                                num++;
                }
        }
}

void main()
{
        P1M0 = 0x80;                        //P1.7推挽輸出
        P1M1 = 0x00;                        //P1.7推挽輸出
        P3M0 = 0x00;                        //P3.2高阻
        P3M1 = 0x04;                        //P3.2高阻
        PWM_Init();                                //初始化PWM
        IT0 = 1;            //設置INT0下降沿中斷
        EX0 = 1;            //使能INT0中斷
        EA = 1;
        num = IapRead(0x0400);
        if(num>0xcc)//占空比不大于80%
        num=0xcc;

        while (1)
        {
                keyscan(); //按鍵掃描
                CCAP0H=num;//P1.7 PWM輸出
        }
}
//中斷服務程序
void exint0() interrupt 0 //INT0中斷入口
{
    IapErase(0x0400);//扇區擦除
    IapProgram(0x0400,num);//保存num值
}


回復

使用道具 舉報

ID:468169 發表于 2019-1-26 17:30 | 顯示全部樓層
wulin 發表于 2019-1-26 10:32
硬件連接示意圖

已經調試了三個多小時了,沒有一點進展,請大師幫我看看哪里有問題?
#include <STC8F2K08S2.h>
#include<intrins.h>       
#include<math.h>                  //計算小數點的頭文件
#define uint unsigned int
#define uchar unsigned char

#define WT_30M          0x80
#define WT_24M          0x81
#define WT_20M          0x82
#define WT_12M          0x83
#define WT_6M           0x84
#define WT_3M           0x85
#define WT_2M           0x86
#define WT_1M           0x87
/********************************************************************
                            延時函數
*********************************************************************/
void delay(uchar dat)//延時程序
{
uchar m,n,s;
for(m=dat;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
void IapIdle()
{
    IAP_CONTR = 0;                              //關閉IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除觸發寄存器
    IAP_ADDRH = 0x80;                           //將地址設置到非IAP區域
    IAP_ADDRL = 0;
}

char IapRead(int addr)
{
    char dat;

    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 1;                                //設置IAP讀命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //讀IAP數據
    IapIdle();                                  //關閉IAP功能

    return dat;
}

void IapProgram(int addr, char dat)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 2;                                //設置IAP寫命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_DATA = dat;                             //寫IAP數據
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    IapIdle();                                  //關閉IAP功能
}

void IapErase(int addr)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 3;                                //設置IAP擦除命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();                                    //
    IapIdle();                                  //關閉IAP功能
}
uchar scale1=10;                                   //定義占空比比例,初始是50%
uchar scale=40;                //定義占空比比例,初始是50%
uchar num2;
uchar Key_num,Key_num1;
uchar n;

bit bdata flag_add_dec=0;        //長按時是加還是減取決于此變量
bit flag=0;        //長按時是加還是減取決于此變量  
bit write=0;
//管腳聲明
sbit LED = P1^0;        //燈光控制輸出 1
sbit K1= P3^3;          //觸摸輸入
sbit LED1 = P1^1;    //燈光控制輸出2




/*********定時器初始化函數**********/
void init()
{
            IT0=1;//跳變沿出發方式(下降沿)
        EX0=1;//打開INT0的中斷允許。       
        TMOD=0x11;           //工作方式 1 定時器0,1
        TH0=0xff;
        TL0=0xe7;                //T0賦初值25us
        TH1=0xff;
        TL1=0xe7;
        EA=1;                   //中斷總開關          
        ET0=1;                   //打開中斷允許開關
        ET1=1;
   TR0=1;//打開定時器開關
        TR1=1;
}



/****************主函數**********************/
void main()
{
  
          
   
        init();                  //調用初始化函數
        num2 = IapRead(0x0400);
        if(num2>81)
        {
           num2=scale;
        }

          
        while(1)                   //循環
        {         
       

                 
                if(K1==0)        //有觸摸信號                                               
                {
                  
                        delay(20);//延時,去抖,除掉干擾信號
                        if(K1==0)        //再次判斷有觸摸信號
                       
                        {       
                                 
                                while(!K1)//觸摸信號不消失就會在此循環中
                                {       
                                        Key_num++;                   //長按計時變量加
                                        if(Key_num>=100)   //檢測到是長按(如果沒加到100就退出則執行后面的if(Key_num!=0))
                                        {       
                                                Key_num=0;           //清零,執行長按功能
                                                   //在燈開著時才可以調節亮度
                                                         
                                                        while(!K1)                                    //觸摸信號一直在,進入循環,進行加減亮度
                                                        {                                                                         

                                                                if(flag_add_dec==0)                  //是加狀態

                                                                {       
                                                                  
                                                                       
                                                                  
                                                                        scale++;       
                                                                                                //燈光比例++

                                                                        if(scale>=81)          //達到最亮
                                                                        scale=81;                  //保持最亮
                                   
                                                                  
                                                        }       
                                                               
                                                                else
                                                                {
                                                                  
                                                               
                                                                        scale--;
                                                                           //燈光比例--
                                                                        if(scale<=2)           //達到最暗
                                                                {
                                                                        scale=2;                   //保持最暗
                                                                       
                                                                }       
                                                                       
                                                                }

                                               
                                                           delay(30);
                                                        }
                                                         
                                                        flag_add_dec=!flag_add_dec;         //執行一次長按后,此變量取反(1變0,0變1)
                                                       
                       
                                        }
                               
                                delay(2);                  //此延時是調節長按時間的
                                }
                               
                                if(Key_num!=0)                  //如果不是長按按鍵
                                {
                               
                                        Key_num=0;                  //清零
                                        TR0=~TR0;                  //定時器取反,就是開關定時器,從而開關燈
                                        if(TR0==0)                  //如果是關燈時,將LED輸出置高,關閉輸出
                                        LED=1;
                                        LED1=1;
                                }
                            
                        }
                  
               
                }

                num2=scale;
                }

                               
        }
   
          


/******************定時器T0服務函數:脈沖發生函數*******************/
void time0() interrupt 1
{
   
        TH0=0xff;
        TL0=0xe7;                //T0賦初值10us
        n++;                         //每25us  n++
       
        if(n<scale)                 //n<設置比例時,打開燈
        {          
                        LED=0;  LED1=~LED;
        }
        else if(n>=scale)//n大于等于設置比例時 關閉燈
        {         
                LED=1;    LED1=~LED;
        }
        if(n==80)                 //n==40  :25us*40=1ms   1kHZ
        {
                n=0;                 //n=0
        }

}

void time() interrupt 3
{
        TH1=0xff;
        TL1=0xe7;                //T0賦初值12.5us
                 //每25us  n++
       
       
}
/*外部中斷0----*/
void Int0()        interrupt 0                //外部中斷0的中斷函數
{

                                    IapErase(0x0400);  //擦除扇區
                    IapProgram(0x0400,num2);//寫入新的地址                           
                           
                       
                         
}

回復

使用道具 舉報

ID:468169 發表于 2019-1-26 19:58 來自觸屏版 | 顯示全部樓層
nanyexin 發表于 2019-1-26 17:30
已經調試了三個多小時了,沒有一點進展,請大師幫我看看哪里有問題?
#include
#include       

現在已經能記憶了,但是只能記憶最亮,不能隨意記憶,是不是哪里設置的不對,因為我的是無極調光,不能只記錄最亮的。
還有,怎么寫入和讀取多個數呢?
回復

使用道具 舉報

ID:213173 發表于 2019-1-26 21:27 | 顯示全部樓層
nanyexin 發表于 2019-1-26 17:30
已經調試了三個多小時了,沒有一點進展,請大師幫我看看哪里有問題?
#include
#include       

在沒有充分經驗的情況下不要試圖一下子就能把比較復雜的程序調試通。因該分塊調試,都調通后再合在一起統調比較容易發現問題。就你的程序而言,定時器明顯設置不合理,微秒級定時要用模式2,節省中斷重裝時間。而且你設置的是12T模式,T0中斷任務耗時30um,T1中斷任務耗時8um,CPU響應中斷、保存現場也需要時間,可是你設置25us要發生兩次中斷,也就是說前面中斷任務還沒有完成,下一次的中斷請求又到來,這叫CPU情何以堪?
回復

使用道具 舉報

ID:468169 發表于 2019-1-26 23:19 來自觸屏版 | 顯示全部樓層
wulin 發表于 2019-1-26 10:32
硬件連接示意圖



大師。我調試了很久,終于可以記憶它了,不過就是只能記憶0和1,就是燈亮或不亮。但是我的功能是無級調光,不能只記憶0和1,我要在哪里修改才可以調光亮度在那個級都可以記憶呀?
回復

使用道具 舉報

ID:468169 發表于 2019-1-27 16:36 來自觸屏版 | 顯示全部樓層
5100103 發表于 2019-1-15 11:57
#include "reg51.h"
#include "intrins.h"


請問STC8F EEPROM中怎么記憶多個字節,要怎地修改?
回復

使用道具 舉報

ID:213173 發表于 2019-1-28 13:52 | 顯示全部樓層
nanyexin 發表于 2019-1-26 23:19
大師。我調試了很久,終于可以記憶它了,不過就是只能記憶0和1,就是燈亮或不亮。但是我的功能是無級調光 ...

//不完全看明白你的意圖,把你的程序改成單鍵控制掉電記憶PWM調光燈
//去掉定時器PWM調光,用主循環完成PWM調光,去掉delay延時用計數法
//完成消抖、短按、長按、長按連+連-。程序按1T單片機編寫,經實際電路驗證無誤。
//操作平臺IAP15W4K58S4,因不涉及其它內部新增功能,程序與STC8F2K08S2通用。
//#include <STC8F2K08S2.h>
#include <STC8.H>
#include<intrins.h>        
//#include<math.h>            //計算小數點的頭文件
#define uint unsigned int
#define uchar unsigned char
#define WT_12M   0x83                        //CPU的等待時間
#define key_S 500                                        //宏定義短按(約20ms)
#define key_L 25000                                //宏定義長按(約1s)
#define key_M 24500                                //宏定義長按步進速度
//管腳聲明
sbit LED = P1^0;                       //開關指示
sbit K1= P3^3;          //觸摸輸入
sbit PWM = P1^1;                    //燈光控制輸出
//子程序聲明
void init();
void keyscan();
void IapIdle();
uchar IapRead(uint addr);
void IapProgram(uint addr, uchar dat);
void IapErase(uint addr);
//變量聲明
uchar scale;                        //占空變量
uchar num;                                //計數變量
uchar save;                                //保存的數據變量
bit flag=0;                                //長按標志
bit flag_add_dec=0;        //長按時加減標志
/****************主函數**********************/
void main()
{
        P0M0 = 0x00;//初始化端口弱上拉
        P0M1 = 0x00;
        P1M0 = 0x00;
        P1M1 = 0x00;
        P2M0 = 0x00;
        P2M1 = 0x00;
        P3M0 = 0x00;
        P3M1 = 0x00;
        P4M0 = 0x00;
        P4M1 = 0x00;
        P5M0 = 0x00;
        P5M1 = 0x00;
        P6M0 = 0x00;
        P6M1 = 0x00;
        P7M0 = 0x00;
        P7M1 = 0x00;

        init();      //調用初始化函數

        save=IapRead(0x0400);//讀取EEPROM保存的數據

        if(save==0xff)                //如果初次加電EEPROM沒有寫數據,默認寄存器0xff。
                save = 0x01;        //初始化占空變量與開關變量

        scale = save>>1;        //分解--占空變量
        LED = save & 0x01;//分解--開關變量

        while(1)          //循環
        {         
                keyscan();//按鍵掃描
                if(LED==0)//PWM控制
                {
                        if(++num==100)
                                num=0;
                        if(num<scale)
                                PWM=0;
                        else PWM=1;
                }
                save =(scale<<1)|LED;//占空變量與開關變量合并為1個字節
        }
}
void keyscan()                                                //按鍵掃描
{
        static uint count=0;                        //計數變量
        static uchar count1=0;                //1T單片機12倍計數變量
        if(!K1)   
        {  
                if(++count1>=12)
                {//如果使用12T單片機要屏蔽此段語句
                        count1=0;
                        count++;  
                }
                if(count>=key_L)                        //長按
                {
                        if(flag_add_dec==0)        //是加狀態
                        {        
                                if(scale<100)                //達到最亮       
                                        scale++;       //燈光比例++
                        }
                        else
                        {
                                if(scale>0)                        //達到最暗  
                                        scale--;       //燈光比例--            
                        }
                        count=key_M;                        //
                        flag=1;                                        //長按標志置1
                }
        }  
        else                                                         //按鍵松手
        {  
                if(flag==1)                //判斷長按松手
                {
                        flag=0;
                        flag_add_dec=~flag_add_dec;//長按加減標志取反
                        count=0;                                //count清0
                }
                else         if(count>key_S && count<key_L)//判斷短按松手
                {
                        LED=~LED;               
                        if(LED==1)
                                PWM=1;
                        count=0;                                //count清0
                }
        }   
}
/*********外部中斷0初始化函數**********/
void init()
{
        IT0=1;//跳變沿出發方式(下降沿)
        EX0=1;//打開INT0的中斷允許。        
        EA=1; //中斷總開關         
}
/**********外部中斷0************/
void Int0() interrupt 0 //外部中斷0的中斷函數
{
        IapErase(0x0400);  //擦除扇區
        IapProgram(0x0400, save); //保存占空變量與開關變量合并為1個字節的數據                       
}


void IapIdle()
{
    IAP_CONTR = 0;                              //關閉IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除觸發寄存器
    IAP_ADDRH = 0x80;                           //將地址設置到非IAP區域
    IAP_ADDRL = 0;
}

uchar IapRead(uint addr)
{
    uchar dat;

    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 1;                                //設置IAP讀命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //讀IAP數據
    IapIdle();                                  //關閉IAP功能

    return dat;
}

void IapProgram(uint addr, uchar dat)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 2;                                //設置IAP寫命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_DATA = dat;                             //寫IAP數據
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    IapIdle();                                  //關閉IAP功能
}

void IapErase(uint addr)
{
    IAP_CONTR = WT_12M;                         //使能IAP
    IAP_CMD = 3;                                //設置IAP擦除命令
    IAP_ADDRL = addr;                           //設置IAP低地址
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();                                    //
    IapIdle();                                  //關閉IAP功能
}
回復

使用道具 舉報

ID:250700 發表于 2019-1-28 15:14 | 顯示全部樓層
nanyexin 發表于 2019-1-15 15:48
嗯,那有STC8F2K08S2的例程嗎,最好有EEPROM這方面的……。

;;;這是STC15W系列的 匯編語言編寫的 停電保存數據,上電恢復數據 部分的程序
;;;在 STC12C系列 上有使用過,
;;; STC8F2K08S2 可以對比一下幾個相關寄存器地址是否一致,一致可以直接使用
;;;用C語言的沒有        
        ; / *** *** *** *** *** *** /   CPU         STC15W404AS
         ; / *** *** *** *** *** *** /                 12.000MHz

         WDT_CONTR  EQU  0C1H          ; 看門狗
         ISP_DATA   EQU  0C2H          ; EEPROM 數據寄存器
         ISP_ADDRH  EQU  0C3H          ; 地址寄存器H
         ISP_ADDRL  EQU  0C4H          ; 地址寄存器L
         ISP_CMD    EQU  0C5H          ; 命令寄存器
         ISP_TRIG   EQU  0C6H          ; 觸發寄存器
         ISP_CONTR  EQU  0C7H          ; ( 等待時間 <  6M   4 )
         ISPRH      EQU   78H          ; ( 等待時間 < 12M   3 )
         ISPRL      EQU   79H          ; ( 等待時間 < 20M   2 )  
         ISPWH      EQU   7AH          ; ( 等待時間 < 12M   3 )
         ISPWL      EQU   7BH          ; ( 等待時間 < 20M   2 )  

         ; / *** *** *** *** *** *** /   通用數據存儲器    RAM  256 字節
         ; / *** *** *** *** *** *** /   定義內部RAM L     EEPROM    5K

         RIV_R0  EQU     1CH
         RIV_R1  EQU     1DH
         
         PTJSA0  EQU     50H           ; 停電保存數據
         PTJSA1  EQU     51H           ; 可以根據需要字節
         ; -------------------------------

                  
         ; / *** *** *** *** *** *** /
         ;   ISP - 78H 79H 7AH 7BH
         
         PJSQS0  EQU     7EH      
         PJSQS1  EQU     7FH


         ; / *** *** *** *** *** *** /   通用      標志位
         ; / *** *** *** *** *** *** /   20H --- 2FH

         PLVD_BZ BIT     26H           ; 停電處理標志
         PLVD_B2 BIT     27H
         
         ; / *** *** *** *** *** *** /   程序入口
         ; / *** *** *** *** *** *** /

         ORG     0000H            
L0000:   LJMP    MIN000                ; 初始化 主程序 START


         ORG     0033H            
L0033:   LJMP    LVD000                ; LVD  低電壓 ( LVDF )
         ; RETI
        
         ; / *** *** *** *** *** *** /   ELVDI (低電壓) 中斷
         ; / *** *** *** *** *** *** /   
         ; 5V-3.7V   5.50V - 3.30V         4.06V - 1.32V

LVD000:  PUSH    PSW                   ; 電流檢測
         PUSH    ACC
         SETB    RS0                   ; 1 區  R1 R3
         CLR     RS1
         ANL     PCON, #11011111B      ; 清 LVDF 位
         MOV     A, PCON
         JNB     ACC.5, LVD008         ; LVDF
         CLR     EA            
         CLR     TR1
         SETB    PLVD_BZ           
         JNB     PLVD_B2, LVD008
         CLR     PLVD_B2
LVD003:  MOV     A, PJSQS0             ; 數據
         MOV     B, #08H
         MUL     AB
         MOV     ISPWL, A              ; 0000H - 01FFH
         MOV     ISPWH, B
         MOV     R1, #PTJSA0           ; 斷電保存數據寫入
         MOV     R3, #08H
LVD006:  MOV     A, @R1
         LCALL   ISP010                ; 字節寫
         INC     ISPWL
         INC     R1
         DJNZ    R3, LVD006
         INC     PJSQS0
LVD007:  ANL     PCON, #11011111B      ;  清 LVDF 位
         MOV     A, PCON
         JB      ACC.5, LVD007              
LVD008:  CLR     PLVD_BZ         
         SETB    EA
         POP     ACC
         POP     PSW
         RETI
         
         ; / *** *** *** *** *** *** /   初始化 主程序A
         ; / *** *** *** *** *** *** /

MIN000:  MOV     SP, #0B0H             ; 初始化 主程序 SP = B0H - FFH  

         MOV     IE, #11000000B        ; IE.6 ( EPCA_LVD 中斷 )         

         
MIN002:  LCALL   MIM000                ; 初始化


MIN010:  NOP                           ; 主程序
         NOP
         MOV     WDT_CONTR, #3EH       ; 看門狗 初始化 12M ( 1.0485 S )
         NOP                           ; 喂狗 同
         NOP
         ; 主控程序在這里加入
         
MIN050:  JMP     MIN010
         RET
         

         ; / *** *** *** *** *** *** /   讀寫 STC15W404AS  EEPROM  
         ; / *** *** *** *** *** *** /   1 字節讀

ISP000:  MOV     ISP_CONTR, #83H       ; 打開 IAP 功能 設置等待時間
         MOV     ISP_CMD, #01H         ; 送字節讀命令
         MOV     ISP_ADDRH, ISPRH      ; 送地址高字節
         MOV     ISP_ADDRL, ISPRL      ; 送地址低字節
         CLR     EA                    ; 關中斷
         MOV     ISP_TRIG, #5AH        ; 起動 ISP/IAP 觸發寄存器
         MOV     ISP_TRIG, #0A5H
         NOP
         MOV     A, ISP_DATA           ; 將讀出的數據送往Acc
         JB      PLVD_BZ, $+5
         SETB    EA
         LCALL   ISP030                ; 關閉 IAP 功能
         RET

         ; / *** *** *** *** *** *** /   1 字節編程

ISP010:  MOV     ISP_CONTR, #83H       ; 打開 IAP 功能 設置等待時間
         MOV     ISP_CMD, #02H         ; 送字節編程命令
         MOV     ISP_ADDRH, ISPWH      ; 送地址高字節
         MOV     ISP_ADDRL, ISPWL      ; 送地址低字節
         MOV     ISP_DATA, A           ; 數據進ISP_DATA
         CLR     EA                    ; 關中斷
         MOV     ISP_TRIG, #5AH        ; 起動 ISP/IAP 觸發寄存器
         MOV     ISP_TRIG, #0A5H
         NOP
         JB      PLVD_BZ, $+5
         SETB    EA
         LCALL   ISP030                ; 關閉 IAP 功能
         RET

         ; / *** *** *** *** *** *** /   擦除扇區

ISP020:  MOV     ISP_CONTR, #83H       ; 打開 IAP 功能 設置等待時間
         MOV     ISP_CMD, #03H         ; 送擦除扇區命令
         MOV     ISP_ADDRH, ISPWH      ; 送地址高字節
         MOV     ISP_ADDRL, ISPWL      ; 送地址低字節
         CLR     EA                    ; 關中斷
         MOV     ISP_TRIG, #5AH        ; 起動 ISP/IAP 觸發寄存器
         MOV     ISP_TRIG, #0A5H
         NOP
         JB      PLVD_BZ, $+5
         SETB    EA
         LCALL   ISP030                ; 關閉 IAP 功能
         RET

         ; / *** *** *** *** *** *** /   關閉 IAP 功能

ISP030:  MOV     ISP_CONTR, #00H
         MOV     ISP_CMD, #00H
         MOV     ISP_TRIG, #00H
         MOV     ISP_ADDRH, #0FFH      ; 指向非EEPROM區
         MOV     ISP_ADDRL, #0FFH
         RET
         

         RET

         ; / *** *** *** *** *** *** /   初始化   STC15W404AS
         ; / *** *** *** *** *** *** /   讀回DAT         ***
      
MIM000:  MOV     R4, #20               ; 50000 uS * 20
MIM001:  NOP
         NOP
         MOV     WDT_CONTR, #3CH       ; 看門狗 初始化 12M ( 1.0485 S )
         NOP     
         NOP                           ; 喂狗 同
         DJNZ    R4, MIM001     
         CLR     PLVD_BZ               ;
         CLR     PLVD_B2
         MOV     RIV_R1, #50           ; 30 S
         LCALL   MIM050                ; 機器編號
         NOP
MIM010:  MOV     PJSQS0, #40H          ; 讀回     編碼
MIM013:  DEC     PJSQS0                ; 0000H - 01FFH
         MOV     A, PJSQS0
         CJNE    A, #0FFH, MIM015
         RET
MIM015:  MOV     B, #08H               ; 計算地址
         MUL     AB
         MOV     ISPRL, A              ; 0000H - 01FFH
         MOV     ISPRH, B
         LCALL   ISP000                ; 字節讀
         CJNE    A, #0FFH, MIM016
         JMP     MIM013
MIM016:  MOV     R0, #PTJSA0     
         MOV     R3, #08H
MIM018:  LCALL   ISP000                ; 字節讀
         MOV     @R0, A                ; 寫 RAM
         INC     ISPRL
         INC     R0
         DJNZ    R3, MIM018
         INC     PJSQS0

MIM050:  RET

         ; / *** *** *** *** *** *** /   結束

         END
回復

使用道具 舉報

ID:468169 發表于 2019-1-31 22:19 來自觸屏版 | 顯示全部樓層
wulin 發表于 2019-1-28 13:52
//不完全看明白你的意圖,把你的程序改成單鍵控制掉電記憶PWM調光燈
//去掉定時器PWM調光,用主循環完成 ...

STC8F2K08S2不是沒有PWM(PCA)寄存器嗎?
Screenshot_20190131_222213_com.UCMobile.jpg
回復

使用道具 舉報

ID:213173 發表于 2019-2-1 07:33 | 顯示全部樓層
nanyexin 發表于 2019-1-31 22:19
STC8F2K08S2不是沒有PWM(PCA)寄存器嗎?

STC8F2K08S2是沒有硬件PWM(PCA)寄存器,在這個程序中PWM調光是在主循環中由軟件處理。
回復

使用道具 舉報

ID:468169 發表于 2020-9-13 11:52 來自觸屏版 | 顯示全部樓層
wulin 發表于 2019-1-23 16:53
掉電記憶是需要外部硬件支持的,否則單片機沒有電源怎么工作?如下圖,C2值遠大于C1。把寫EEPROM的程序放 ...

大師,現在我要把這個程式改為兩路iO口輸出,具體工作為:上電一路IO口輸出高電平另一個不輸出,,斷電再上電輸出另一路高電平,怎么實現?
回復

使用道具 舉報

ID:140489 發表于 2020-9-29 11:08 | 顯示全部樓層
給你一段我的代碼,調光完成,松手后存儲pwm值
/*----------------------------
感應掃描
----------------------------*/
void keyscan()
{
        if(PHO==0)        //沒有感應 要及時清零一些標志
        {

                ucKeyLock1=0;   //感應自鎖標志清零
                uiKeyTimeCnt1=0;//感應去抖動延時計數器清零,此行非常巧妙,是我實戰中摸索出來的。
                if(flag2)                //長按松手后,存儲pwm值
                {
                        IapEraseSector(0x0001); // 清除EEPROM
                        IapProgramByte(0x0001, pwm_val); // 將pwm值據寫入EEPROM
                        flag2 = 0;                           //pwm值寫入EEPROM后,存儲標志清零
                }

        }
        else if(ucKeyLock1==0)//有感應,且是第一次感應
        {       
                IR = 1;                          //關閉紅外發射
                ++uiKeyTimeCnt1;  //延時計數器
                if(uiKeyTimeCnt1>const_key_time1)//短按
                {
                        uiKeyTimeCnt1=0;
                        ucKeyLock1=1; //自鎖按鍵置位,避免一直觸發
                        flag1 = !flag1;
                }               
        }
        else if(uiKeyTimeCnt1<const_key_time2)//長按
        {
                ++uiKeyTimeCnt1;  //延時計數器
                if(uiKeyTimeCnt1==const_key_time2)
                {
                        uiKeyTimeCnt1=198;//此處調節調光速度,值越大,調光越快
                        flag2=1;                  //存儲標志置1
                        if(flag == 1)
                        {
                               
                                if(pwm_val < 255)
                               
                                {
                                  pwm_val++;        //亮度變暗
                               
                                  if(pwm_val==255)//此處賦值255可以調滅
                                  {
                                                  delay(100);
                                                  flag = 0;
                                  }
                                }
                        }
                       
                        if( flag ==0 )
                        {
                                if(pwm_val > 0)
                                {
                                  pwm_val--;        //亮度變亮
                               
                                  if(pwm_val==0)//
                                  {
                                                delay(100);
                                                flag = 1;
                                  }
                                }
                        }
                }               
        }                                               
}
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天操夜夜操 | 亚洲色图综合 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 三级成人片 | 天天躁日日躁狠狠躁白人 | 亚洲精品专区 | 777zyz色资源站在线观看 | 国产精品成人一区二区三区 | 一区二区在线 | 99re国产视频 | 一区二区三区在线电影 | 亚洲精品中文在线 | 国产99久久久国产精品 | 黄色91在线 | 亚洲精品一区二区在线观看 | 久久久网| 久久精品中文字幕 | 久色视频在线观看 | 国产精品123区 | 男女羞羞视频在线免费观看 | 国产97碰免费视频 | 国产一区91精品张津瑜 | 国产精品成人免费 | 国产成人久久精品一区二区三区 | 欧美一级欧美一级在线播放 | 亚洲精品久久久久中文字幕欢迎你 | 黑人巨大精品欧美一区二区免费 | 日韩精品一区二区三区中文字幕 | 国产91综合 | 国产免费观看视频 | 国产精品一二三区 | 一区二区三区中文字幕 | 777777777亚洲妇女| 一区二区三区不卡视频 | 一级毛片免费视频观看 | 精品一区二区在线观看 | 最新中文字幕一区 | 爱爱免费视频网站 | 精品欧美乱码久久久久久 | 中文字幕在线视频观看 | 久久久区 |