找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3920|回复: 16
收起左侧

STC15F104W单片机下载后运行和仿真完全不一样?

[复制链接]
ID:594633 发表于 2020-4-17 00:21 | 显示全部楼层 |阅读模式
以下程序在Proteus里仿真正常,延时时间(不需要十分精准)和切换显示都可以达到预定效果,但是把程序下载到STC15F104W后就完全不是Proteus里的仿真效果了,不知道哪里的问题。
下载程序的时候发现程序基本下载不进去,P3.0只接一个按键,P3.1空的,下载的时候始终显示检测单片机,后来发现要把P3.4和P3.5的限流电阻拆掉才可以顺利下载程序。懵逼了……

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

sbit key =P3^0;                //开始结束按键
sbit LED1=P3^2;         //开始绿灯
sbit LED2=P3^3;         //停止红灯
sbit relay =P3^4;      //开始继电器
sbit relay1=P3^5;        //结束继电器

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)//到达设定时间
                {
                    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;
                     }
}



回复

使用道具 举报

ID:213173 发表于 2020-4-17 08:08 | 显示全部楼层
STC15F104W是1T单片机,楼主的程序是按12T单片机编写,仿真不能真实反映实际应用。楼主的在定时中断中使用阻滞型延时,且延时时间远远大于中断周期,根本不可能正常运行。根据楼主以前的帖子解释是用于驱动磁保持继电器,给你按STC15F104W配置寄存器改写程序,未经实物验证,但逻辑关系给你理顺了并有详细注释。楼主自行按实际需求调整时间参数。程序的驱动输出按低电平有效,如使用高电平有效则启用端口配置推挽模式。 示例程序.zip (13.77 KB, 下载次数: 30)
回复

使用道具 举报

ID:235200 发表于 2020-4-17 08:22 | 显示全部楼层
该单片机要选择1T或12T模式,况且仿真速度是由设置的晶振频率决定
回复

使用道具 举报

ID:594633 发表于 2020-4-17 09:59 来自手机 | 显示全部楼层
wulin 发表于 2020-4-17 08:08
STC15F104W是1T单片机,楼主的程序是按12T单片机编写,仿真不能真实反映实际应用。楼主的在定时中断中使用 ...

感谢大佬的指点,谢谢!
试运行看看结果再反馈。
回复

使用道具 举报

ID:594633 发表于 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;          //开始结束按键
sbit LED1=P3^2;         //开始绿灯
sbit LED2=P3^3;         //停止红灯
sbit relay=P3^4;      //开始继电器
sbit relay1=P3^5;        //结束继电器

uint count;//计时计数变量

void delay(uint ms)           //延时函数
{        
        int i;                                       
        while(ms--)                             
        {
                for(i=0;i<1150;i++);
        }
}

void Timer0Init(void)        //50毫秒@11.0592MHz
{
        AUXR &= 0x7F;        //定时器时钟12T模式
        TMOD &= 0xF0;        //设置定时器16位自动重装模式
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x4C;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 0;                //定时器0关闭
        ET0 =1;
        EA =1;
}

void main()    //主函数
{
        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;                //设置定时初值
             //TH0 = 0x4C;                //设置定时初值

        count++;

         if (count ==1 && LED2==0)//到达设定时间
                {
            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第一次触发,delay延时1秒,LED2闪烁大延时后LED1常亮,LED2灭。KEY第二次触发后,delay1延时1秒,应该LED1闪烁大延时后LED2常亮,LED1灭,以此循环。但是KEY第二次触发后,delay2延时1秒,LED2闪烁,大延时后LED1常亮,LED2灭,以此循环……
回复

使用道具 举报

ID:594633 发表于 2020-4-19 19:05 | 显示全部楼层
csmyldl 发表于 2020-4-17 08:22
该单片机要选择1T或12T模式,况且仿真速度是由设置的晶振频率决定

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

上真机运行还是有问题……
回复

使用道具 举报

ID:594633 发表于 2020-4-21 19:12 | 显示全部楼层
wulin 发表于 2020-4-17 08:08
STC15F104W是1T单片机,楼主的程序是按12T单片机编写,仿真不能真实反映实际应用。楼主的在定时中断中使用 ...

定时器中断里不要有延时。如此情况需要在指定的时间内循环让指示灯闪烁有什么推荐的方法吗?
当前程序跑的还顺利,基本满足要求,不知道有没有什么不良影响?能否长时间运行使用呢?
望大佬指点,感谢。
回复

使用道具 举报

ID:213173 发表于 2020-4-22 07:38 | 显示全部楼层
kevind 发表于 2020-4-21 19:12
定时器中断里不要有延时。如此情况需要在指定的时间内循环让指示灯闪烁有什么推荐的方法吗?
当前程序跑 ...

大于中断周期的延时函数放在定时器中断中会破坏定时准确度。LED闪烁功能要放在主函数中运行。中断中只要输出闪烁标志即可。
回复

使用道具 举报

ID:594633 发表于 2020-4-28 12:11 | 显示全部楼层
wulin 发表于 2020-4-22 07:38
大于中断周期的延时函数放在定时器中断中会破坏定时准确度。LED闪烁功能要放在主函数中运行。中断中只要 ...

大佬能否给一个标志位的例程做参考?感激不尽~~
回复

使用道具 举报

ID:213173 发表于 2020-4-28 20:48 | 显示全部楼层
kevind 发表于 2020-4-28 12:11
大佬能否给一个标志位的例程做参考?感激不尽~~

增加一个计时和闪烁标志放在原来的中断里,输出闪烁标志位
把LED控制放在主循环中,以控制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秒(按器件参数调整最佳时间)
        {
                OUT1=0;//开
        .......
        .......
回复

使用道具 举报

ID:420836 发表于 2020-4-29 01:56 | 显示全部楼层
这个问题很有趣。 许多新手都会犯同样的错误。 很高兴您在这里与我们分享。
回复

使用道具 举报

ID:213173 发表于 2020-4-29 11:21 | 显示全部楼层
kevind 发表于 2020-4-28 12:11
大佬能否给一个标志位的例程做参考?感激不尽~~

按STC15F104W配置寄存器改写程序
使用芯片内部时钟11.0592MHz
楼主自行按实际需求调整时间参数。
程序的驱动输出按低电平有效,
如使用高电平有效则启用端口配置推挽模式。
仿真验证逻辑功能无误
示例程序.zip (14.66 KB, 下载次数: 9)
回复

使用道具 举报

ID:594633 发表于 2020-5-6 21:23 | 显示全部楼层
wulin 发表于 2020-4-29 11:21
按STC15F104W配置寄存器改写程序
使用芯片内部时钟11.0592MHz
楼主自行按实际需求调整时间参数。

感谢大佬的实例,很实用,学习了~~~
尝试增加一个运行指示灯,闪烁状态。
在while里增加延时无效果……
sysled=0;
delay(10);
sysled=1;
delay(10);
回复

使用道具 举报

ID:235386 发表于 2021-1-28 21:19 | 显示全部楼层
STC15F104W单片机在什么软件上仿真?
回复

使用道具 举报

ID:155507 发表于 2021-1-28 23:52 | 显示全部楼层
wlb6254345 发表于 2021-1-28 21:19
STC15F104W单片机在什么软件上仿真?

在Proteus8.9 软件上仿真

http://www.51hei.com/bbs/dpj-187373-1.html
回复

使用道具 举报

ID:1088608 发表于 2023-7-16 00:07 | 显示全部楼层
怎么仿真?是实物仿真吗?
回复

使用道具 举报

ID:161164 发表于 2023-7-18 15:14 | 显示全部楼层
654165671 发表于 2023-7-16 00:07
怎么仿真?是实物仿真吗?

新版本Protues 有STC15W4K32S4 仿真模型
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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