標題: STC15F104W單片機下載后運行和仿真完全不一樣? [打印本頁]

作者: kevind    時間: 2020-4-17 00:21
標題: STC15F104W單片機下載后運行和仿真完全不一樣?
以下程序在Proteus里仿真正常,延時時間(不需要十分精準)和切換顯示都可以達到預定效果,但是把程序下載到STC15F104W后就完全不是Proteus里的仿真效果了,不知道哪里的問題。
下載程序的時候發(fā)現(xiàn)程序基本下載不進去,P3.0只接一個按鍵,P3.1空的,下載的時候始終顯示檢測單片機,后來發(fā)現(xiàn)要把P3.4和P3.5的限流電阻拆掉才可以順利下載程序。懵逼了……

單片機源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit key =P3^0;                //開始結(jié)束按鍵
sbit LED1=P3^2;         //開始綠燈
sbit LED2=P3^3;         //停止紅燈
sbit relay =P3^4;      //開始繼電器
sbit relay1=P3^5;        //結(jié)束繼電器

uint count;//計時存儲器

void DelayMS(uint x)
{
        uchar i;
        while(x--);
        {
                for(i=0;i<120;i++);
        }
}

void init()
{

        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;

        ET0 =1;
        TR0 =0;
        EA =1;
}

void main()
{
        relay1=1;
        relay=1;
        LED1=1;
        LED2=0;
        init();

        while (1)
        {
            if (key==0)//按鍵按下
            {

                     TR0 =1;//啟動定時器

            }

        }
}

void timer0()interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;

        count++;

        if (count ==1 && LED2==0)//到達設(shè)定時間
                {
                    relay =~relay;
                    DelayMS(50000);
                    relay =~relay;
                                       
                }

                if (count ==1 && LED1==0)
                {
                    relay1 =~relay1;
                    DelayMS(50000);
                    relay1 =~relay1;
                                       
                }
                        
                if (count <=450 && LED1==0)
                {
                        LED1=~LED1;
                        DelayMS(3000);
                            LED1=~LED1;
                        }
                else
                         {
                               LED2=~LED2;
                        DelayMS(3000);
                            LED2=~LED2;
                }

        if (count >=450)
                {
                            LED1=~LED1;
                            LED2=~LED2;
                            count =0;
                            TR0 =0;
                     }
}




作者: wulin    時間: 2020-4-17 08:08
STC15F104W是1T單片機,樓主的程序是按12T單片機編寫,仿真不能真實反映實際應(yīng)用。樓主的在定時中斷中使用阻滯型延時,且延時時間遠遠大于中斷周期,根本不可能正常運行。根據(jù)樓主以前的帖子解釋是用于驅(qū)動磁保持繼電器,給你按STC15F104W配置寄存器改寫程序,未經(jīng)實物驗證,但邏輯關(guān)系給你理順了并有詳細注釋。樓主自行按實際需求調(diào)整時間參數(shù)。程序的驅(qū)動輸出按低電平有效,如使用高電平有效則啟用端口配置推挽模式。 示例程序.zip (13.77 KB, 下載次數(shù): 30)


作者: csmyldl    時間: 2020-4-17 08:22
該單片機要選擇1T或12T模式,況且仿真速度是由設(shè)置的晶振頻率決定
作者: kevind    時間: 2020-4-17 09:59
wulin 發(fā)表于 2020-4-17 08:08
STC15F104W是1T單片機,樓主的程序是按12T單片機編寫,仿真不能真實反映實際應(yīng)用。樓主的在定時中斷中使用 ...

感謝大佬的指點,謝謝!
試運行看看結(jié)果再反饋。
作者: kevind    時間: 2020-4-19 19:01
本帖最后由 kevind 于 2020-4-20 14:37 編輯

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char

sfr AUXR=0x8E;                   //輔助寄存器
sbit key=P3^0;          //開始結(jié)束按鍵
sbit LED1=P3^2;         //開始綠燈
sbit LED2=P3^3;         //停止紅燈
sbit relay=P3^4;      //開始繼電器
sbit relay1=P3^5;        //結(jié)束繼電器

uint count;//計時計數(shù)變量

void delay(uint ms)           //延時函數(shù)
{        
        int i;                                       
        while(ms--)                             
        {
                for(i=0;i<1150;i++);
        }
}

void Timer0Init(void)        //50毫秒@11.0592MHz
{
        AUXR &= 0x7F;        //定時器時鐘12T模式
        TMOD &= 0xF0;        //設(shè)置定時器16位自動重裝模式
        TL0 = 0x00;                //設(shè)置定時初值
        TH0 = 0x4C;                //設(shè)置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 0;                //定時器0關(guān)閉
        ET0 =1;
        EA =1;
}

void main()    //主函數(shù)
{
        Timer0Init();
        LED1=1;
          LED2=0;
        relay1=1;
        relay=1;
               
        while (1)
        {
                if(key==0 && TR0==0)//按鍵與定時器互鎖
                {
                        TR0=1;//啟動定時器        
                }
               
        }
}

void Timer0(void) interrupt 1
{
      //TL0 = 0x00;                //設(shè)置定時初值
             //TH0 = 0x4C;                //設(shè)置定時初值

        count++;

         if (count ==1 && LED2==0)//到達設(shè)定時間
                {
            relay =~relay;
                        delay(500);
                        relay =~relay;
                                       
                }
               
            if (count ==1 && LED1==0)
                {
            relay1 =~relay1;
                        delay(500);
                        relay1 =~relay1;
                                       
                }
                        
                if (count <=600 && LED1==1)                    
                       {
                LED2=~LED2;
                        delay(10);
                    LED2=~LED2;
                        }
                if (count <=100 && LED1==0)
                         {
                       LED1=~LED1;
                        delay(20);
                    LED1=~LED1;
                }

        if (count >=600)
                {
            count=0;
                    TR0=0;
                        LED1=~LED1;
                        LED2=~LED2;                    
                        }
}

-------------------------------------------------------------------------------------------------------
程序改成以上基本功能出來了,存在以下問題:
KEY第一次觸發(fā),delay延時1秒,LED2閃爍大延時后LED1常亮,LED2滅。KEY第二次觸發(fā)后,delay1延時1秒,應(yīng)該LED1閃爍大延時后LED2常亮,LED1滅,以此循環(huán)。但是KEY第二次觸發(fā)后,delay2延時1秒,LED2閃爍,大延時后LED1常亮,LED2滅,以此循環(huán)……
作者: kevind    時間: 2020-4-19 19:05
csmyldl 發(fā)表于 2020-4-17 08:22
該單片機要選擇1T或12T模式,況且仿真速度是由設(shè)置的晶振頻率決定

11.0592M
后面改成了12T模式。

上真機運行還是有問題……
作者: kevind    時間: 2020-4-21 19:12
wulin 發(fā)表于 2020-4-17 08:08
STC15F104W是1T單片機,樓主的程序是按12T單片機編寫,仿真不能真實反映實際應(yīng)用。樓主的在定時中斷中使用 ...

定時器中斷里不要有延時。如此情況需要在指定的時間內(nèi)循環(huán)讓指示燈閃爍有什么推薦的方法嗎?
當前程序跑的還順利,基本滿足要求,不知道有沒有什么不良影響?能否長時間運行使用呢?
望大佬指點,感謝。
作者: wulin    時間: 2020-4-22 07:38
kevind 發(fā)表于 2020-4-21 19:12
定時器中斷里不要有延時。如此情況需要在指定的時間內(nèi)循環(huán)讓指示燈閃爍有什么推薦的方法嗎?
當前程序跑 ...

大于中斷周期的延時函數(shù)放在定時器中斷中會破壞定時準確度。LED閃爍功能要放在主函數(shù)中運行。中斷中只要輸出閃爍標志即可。
作者: kevind    時間: 2020-4-28 12:11
wulin 發(fā)表于 2020-4-22 07:38
大于中斷周期的延時函數(shù)放在定時器中斷中會破壞定時準確度。LED閃爍功能要放在主函數(shù)中運行。中斷中只要 ...

大佬能否給一個標志位的例程做參考?感激不盡~~
作者: wulin    時間: 2020-4-28 20:48
kevind 發(fā)表于 2020-4-28 12:11
大佬能否給一個標志位的例程做參考?感激不盡~~

增加一個計時和閃爍標志放在原來的中斷里,輸出閃爍標志位
把LED控制放在主循環(huán)中,以控制LED亮滅和閃爍。

bit Twinkle;//閃爍標志
uchar count1;//閃爍計時變量

void timer0()interrupt 1 //50毫秒16位自動重裝
{
        count1++;
        if(count1>=10)//0.5秒
        {
                count1=0;
                Twinkle=~Twinkle;
        }
        count++;
        if(count<=20) //OUT1輸出1秒(按器件參數(shù)調(diào)整最佳時間)
        {
                OUT1=0;//開
        .......
        .......

作者: TTQ001    時間: 2020-4-29 01:56
這個問題很有趣。 許多新手都會犯同樣的錯誤。 很高興您在這里與我們分享。
作者: wulin    時間: 2020-4-29 11:21
kevind 發(fā)表于 2020-4-28 12:11
大佬能否給一個標志位的例程做參考?感激不盡~~

按STC15F104W配置寄存器改寫程序
使用芯片內(nèi)部時鐘11.0592MHz
樓主自行按實際需求調(diào)整時間參數(shù)。
程序的驅(qū)動輸出按低電平有效,
如使用高電平有效則啟用端口配置推挽模式。
仿真驗證邏輯功能無誤
示例程序.zip (14.66 KB, 下載次數(shù): 9)





作者: kevind    時間: 2020-5-6 21:23
wulin 發(fā)表于 2020-4-29 11:21
按STC15F104W配置寄存器改寫程序
使用芯片內(nèi)部時鐘11.0592MHz
樓主自行按實際需求調(diào)整時間參數(shù)。

感謝大佬的實例,很實用,學習了~~~
嘗試增加一個運行指示燈,閃爍狀態(tài)。
在while里增加延時無效果……
sysled=0;
delay(10);
sysled=1;
delay(10);

作者: wlb6254345    時間: 2021-1-28 21:19
STC15F104W單片機在什么軟件上仿真?
作者: angmall    時間: 2021-1-28 23:52
wlb6254345 發(fā)表于 2021-1-28 21:19
STC15F104W單片機在什么軟件上仿真?

在Proteus8.9 軟件上仿真

http://www.torrancerestoration.com/bbs/dpj-187373-1.html

作者: 654165671    時間: 2023-7-16 00:07
怎么仿真?是實物仿真嗎?
作者: lkc8210    時間: 2023-7-18 15:14
654165671 發(fā)表于 2023-7-16 00:07
怎么仿真?是實物仿真嗎?

新版本Protues 有STC15W4K32S4 仿真模型




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1