大哈欠E 发表于 2013-4-5 17:40:52

我还是学生,第一次凭自己的思路写程序,请大神指教,急

这次写的是基于单片机控制的交通灯,由于第一次写,外部中断服务程序还没写,只写了数码管倒计时 红黄绿状态变化的代码,我就编译了 把hex文件装入proteus里模拟了一下,行不通,不知道是电路画错了还是程序错了,我实在是检查不出哪里有问题。。求各位大神指教一下,小生感激不尽,好人好报。在这里把代码和模拟电路的文件贴出来。

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define time 50000
sbit red_a=P1^3;
sbit green_a=P1^4;
sbit yellow_a=P1^5;

sbit red_b=P1^0;
sbit green_b=P1^1;
sbit yellow_b=P1^2;
sbit int0_key=P3^2;
sbit kai=P3^7;

uint n1,n2,n3,n4,g1,g2,g3,g4;
uchar mm=0;           //全局变量
uchar flag0=0;//a绿 b红 定义标志位
uchar flag1=0;        //a黄 b红
uchar flag2=0;//a红 b绿
uchar flag3=0;//a红 b黄
uchar t=0;                        //35秒倒计时完 跳变到25倒计时
uchar b=35,a=25,ac=30,bc=20;//分别为b车道和a车道红灯时间 a车道和b车道绿灯时间
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};

void inittime01()               //初始化定时器0 外部中断0
{
TMOD=0X11; //定时器0和1都工作在方式1
TH0=(65536-50000)/256;//50ms计时
TL0=(65536-50000)%256;
TH1=(65536-50000)/256;//50ms计时
TL1=(65536-50000)%256;
TR0=1;                                  //启动定时器0        开始计时
ET0=1;                  //允许定时器0中断
EA=1;                  //开总中断
IE0=1;                  //启动外部中断0
EX0=1;                                        //开中断0
IT0=1;                     //外部中断0为跳变沿触发
PX0=1;                     //外部中断0优先级设为最高
          
}
void delay(uint num)
{
   while(num--);

}
void timer0() interrupt 1   //定时器0中断服务程序
{
mm++;
TH0=(65536-50000)/256;//50ms计时
TL0=(65536-50000)%256;
   if(mm==20)                //每到一秒都会执行这个语句
   {
   mm=0;
       if(b<=35&&b>0)
           {
             b--;                          //b车道红灯值35
               ac--;                          //a车道绿灯和黄灯的倒计时值30和5
               
               }
       if(t==1)                        //切换状态 倒计时25秒
          {
           a--;                                  //a车道红灯值25
           bc--;                          //b车道绿灯和黄灯倒计时值20和5
             }
       

   }



}

void disp_daojishi1()          //a车道通车b车道红灯停车 数码管倒计时显示
{
n1=ac/10;                                  //a车道十位
n2=ac%10;                                  //a车道个位
n3=b/10;               //b车道十位
n4=b/10;                //b车道个位

P2=0xf7;                                  //b车道个位
P0=led;                               
delay(200);
                                               
P2=0xfb;                                   //b车道十位
P0=led;
delay(200);

P2=0xfd;                                  //a车道个位
P0=led;
delay(200);

P2=0xfe;                                //a车道十位
P0=led;
delay(200);
P0=0xff;
}
void disp_daojishi2()          //a车道红灯b车道通车 数码管倒计时显示
{
g1=a/10;                                  //a车道十位
g2=a%10;                                  //a车道个位
g3=bc/10;               //b车道十位
g4=bc/10;                //b车道个位

P2=0xf7;                                  //b车道个位
P0=led;                               
delay(200);
                                               
P2=0xfb;                                   //b车道十位
P0=led;
delay(200);

P2=0xfd;                                  //a车道个位
P0=led;
delay(200);

P2=0xfe;                                //a车道十位
P0=led;
delay(200);
P0=0xff;
}
void qiehuan()          
{
   if(b)            //b红灯倒计时35s
          {
          a=25;      //又给a赋值25秒
                bc=20;      
                if(b<=35&&b>5)
                   flag0=1;               //a绿 b红
          if(b<=5)                //a黄 b红
             {
                   ac=5;                // a黄灯置初值5秒
                   flag0=0;           //关闭状态0
             flag1=1;
                   if(b==0)
                     t=1;
                }
                 else
                   {
                     flag0=1;
                      }
             }
           if(t==1)
               {       
                   flag1=0;                     //关闭状态1
                      if(a)
                   {
                     if(a<=25&&a>=5)
                      {
                          flag2=1;       //a红 b绿
                      }
                          if(a<=5)
                           {
                             bc=5;      //置b车道黄灯初值5秒
                             flag2=0;       //关闭状态2
                             flag3=1;        //a红 b黄
                                  if(b==0)
                                   {
                                  b=35;                       //又返回第0状态 置初值
                                        ac=30;
                                        flag3=0;           //关闭状态3
                                        t=0;      //关闭切换状态b——倒计时25秒
                                       }
                   }
                        }
                        }
}
void main()
{
kai=1;    //74hc573通断开关
P0=0xff;
P2=0xff; //开始时使a b车道都不亮
inittime01();
while(1)
{
qiehuan();
if(b<=35&&b>0)
   disp_daojishi1();
   if(t==1)
   disp_daojishi2();       
if(flag0)               //状态0 a绿 b红
   {
    green_a=0;
    red_b=0;
   }
   if(flag1)       //启动状态1 a黄b红
   {
   green_a=1;           //关闭状态0
   red_b=1;
          yellow_a=0;
       red_b=0;
       }
        if(flag2)               //启动状态2 a红b绿
        {
           yellow_a=1;
           red_b=1;
           red_a=0;
           green_b=0;
          }
        if(flag3)           //启动状态3 a红b黄
       {
           red_a=1;
           green_b=1;
           red_a=0;
           yellow_a=0;
          }
    }
}

liu_shu 发表于 2013-4-5 18:09:30

第一次就写这么长!好像绝大多数男的第一次都不会高潮吧?女的也是

fqc168 发表于 2013-4-5 18:09:53

我在学校时候还不会用C51呢!

liao1989 发表于 2013-4-5 18:14:42

初步看了一下你的电路图,在交通灯那里,你的LED应该是IO低电平才会亮吧?那为啥里面又是接地呢?

liao1989 发表于 2013-4-5 18:15:05

你应该是接电源吧

sgzzour 发表于 2013-4-5 18:52:05

目测楼主是学习的郭天祥视频教程。。。

大哈欠E 发表于 2013-4-5 21:49:58

liao1989 发表于 2013-4-5 18:14 static/image/common/back.gif
初步看了一下你的电路图,在交通灯那里,你的LED应该是IO低电平才会亮吧?那为啥里面又是接地呢? ...

里面不是地啊,是电源。。

大哈欠E 发表于 2013-4-5 21:51:05

sgzzour 发表于 2013-4-5 18:52 static/image/common/back.gif
目测楼主是学习的郭天祥视频教程。。。

嗯,学习了一些。。凌峰的也学过一些。

大哈欠E 发表于 2013-4-5 21:56:25

liu_shu 发表于 2013-4-5 18:09 static/image/common/back.gif
第一次就写这么长!好像绝大多数男的第一次都不会高潮吧?女的也是

这是我第一次针对课程设计独立按照自己的思路写的,我第一次是达到高潮了,但是是献给自己的右手。。你是大神,我是菜鸟,你要是愿意指教我虚心接受。你要是说其他的你就别在这里扯他妈蛋。

大哈欠E 发表于 2013-4-5 21:59:00

fqc168 发表于 2013-4-5 18:09 static/image/common/back.gif
我在学校时候还不会用C51呢!

我也是在学着用C51,每次做都会遇到这样或那样的困难,这次还没找到原因,我觉得应该是我的程序有问题了。。帮忙看看

liu_shu 发表于 2013-4-5 22:11:57

大哈欠E 发表于 2013-4-5 21:56 static/image/common/back.gif
这是我第一次针对课程设计独立按照自己的思路写的,我第一次是达到高潮了,但是是献给自己的右手。。你是 ...

步子走的大了确实容易扯到蛋,不要否认,这是真理!{:lol:}

大哈欠E 发表于 2013-4-5 22:47:02

liu_shu 发表于 2013-4-5 22:11 static/image/common/back.gif
步子走的大了确实容易扯到蛋,不要否认,这是真理!

步子迈的太大是应为是大神们走的太快,如果慢下来扶我一把我就不会扯着蛋了。

fqc168 发表于 2013-4-6 12:22:28

太忙了,没有时间啊,现在还在失业当中,找工作要紧!忙的事情多着呢!你这个东西简单,折腾几天肯定出来,我学单片机从来不需要人教!有问题自己搞定,因为大多时候没有人教的,必须适应工作环境规则

elecfun 发表于 2013-4-6 14:02:37

P0口加上拉电阻就可以了。
在Resistors → Resistor Packs 里,选 RESPACK-8

scwscw 发表于 2013-4-6 14:24:20

目测郭天祥的,大一时写过交通灯,大二就不学了,现在转行工控方面!帮顶!

男小北 发表于 2013-4-6 14:44:48

程序加仿真交通灯。qq:11023590

liu_shu 发表于 2013-4-6 15:06:58

大哈欠E 发表于 2013-4-5 22:47 static/image/common/back.gif
步子迈的太大是应为是大神们走的太快,如果慢下来扶我一把我就不会扯着蛋了。 ...

自己的问题还推卸给别人,典型的学生党啊狡辩

USACH 发表于 2013-4-6 15:21:18

elecfun 发表于 2013-4-6 14:02 static/image/common/back.gif
P0口加上拉电阻就可以了。
在Resistors → Resistor Packs 里,选 RESPACK-8

proteus里面不加上拉也会亮的吧?

很多年前这个问题把我难倒啦,为什么proteus里面可以,实际不行。

elecfun 发表于 2013-4-6 17:25:27

USACH 发表于 2013-4-6 15:21 static/image/common/back.gif
proteus里面不加上拉也会亮的吧?

很多年前这个问题把我难倒啦,为什么proteus里面可以,实际不行。 ...

不加上拉的话,P0口的高电平状态指示显示的是灰色,加了上拉后才红色。
我一直困惑的是仿真三极管驱动数码管时三极管不导通,所以一直用的反向器仿真。 {:biggrin:}

USACH 发表于 2013-4-6 17:28:04

elecfun 发表于 2013-4-6 17:25 static/image/common/back.gif
不加上拉的话,P0口的高电平状态指示显示的是灰色,加了上拉后才红色。
我一直困惑的是仿真三极管驱动数 ...

为什么我反正是通的,很多年啦,印象还是很深刻啊。

一样的原理图,proteus是可以的,手工焊接了的不行,然后我看到了上拉。

大哈欠E 发表于 2013-4-6 21:57:53

fqc168 发表于 2013-4-6 12:22 static/image/common/back.gif
太忙了,没有时间啊,现在还在失业当中,找工作要紧!忙的事情多着呢!你这个东西简单,折腾几天肯定出来, ...

嗯,好的,也祝你早日找到工作。。

大哈欠E 发表于 2013-4-6 21:59:50

elecfun 发表于 2013-4-6 14:02 static/image/common/back.gif
P0口加上拉电阻就可以了。
在Resistors → Resistor Packs 里,选 RESPACK-8

嗯 我加了,亮了,但是运行不正常啊,可能是程序问题吧,我自己先看看,找不出原因,再来求大神帮助。。谢谢

大哈欠E 发表于 2013-4-6 22:01:49

USACH 发表于 2013-4-6 17:28 static/image/common/back.gif
为什么我反正是通的,很多年啦,印象还是很深刻啊。

一样的原理图,proteus是可以的,手工焊接了的不行 ...

是啊,以前我也是这样,但现在加上去上拉就可以亮了,但是运行错乱 可能是程序问题吧。。

大哈欠E 发表于 2013-4-6 22:04:09

liu_shu 发表于 2013-4-6 15:06 static/image/common/back.gif
自己的问题还推卸给别人,典型的学生党啊狡辩

我承认自己是有问题,就是有问题自己解决不了了才来求助。

liu_shu 发表于 2013-4-6 22:34:31

大哈欠E 发表于 2013-4-6 22:04 static/image/common/back.gif
我承认自己是有问题,就是有问题自己解决不了了才来求助。

你的问题不是你程序的问题,是你的心态、态度、方式方法的问题,一口吃个胖子,学技术慢慢积累,一个模块一个模块学,上来就显牛X,有用吗?扎实点

elecfun 发表于 2013-4-6 22:54:18

小白问个问题都在这里JJYY,照你这说法遇到问题是不是非得自己研究到死?

wmsky 发表于 2013-4-6 23:00:02

逐个模块测试,(函数)。

电源模块 发表于 2013-4-7 00:27:02

27楼正解。第一次写程序,包括一个新项目,板子做好之后,第一次试着运行的程序,尽量段,一般七八行,十几行,控制一个灯亮灭就足矣,然后每次增加几句,下进去看运行结果,这样容易发现问题

苏子木00 发表于 2013-4-7 10:47:24

程序亟待优化。。。lz思路很乱啊

censtar 发表于 2013-4-7 11:06:12

第一次就写这么长!好像绝大多数男的第一次都不会高潮吧?女的也是
+1

icoyool 发表于 2013-4-7 12:20:14

用个typedef一下,这样就不会搞错了。老是flag0,flag1,flag下去,能不出错么?

icoyool 发表于 2013-4-7 12:24:34


typedef struct
{
        uchar RedTimer;
        uchar GreenTimer;
        uchar YellowTimer;
        union
        {
                uchar All;
                struct
                {
                        uchar RedLigt:1;
                        uchar GreenLigt:1;
                        uchar YellowLigt:1;
                } Solo;
        }Flags;
}TrafficLight;

shenghui12321 发表于 2013-4-8 09:59:14

c语言功底还需要磨练啊

shenghui12321 发表于 2013-4-8 09:59:37

c语言功底还需要磨练啊

47okey 发表于 2013-4-8 16:09:34

icoyool 发表于 2013-4-7 12:24 static/image/common/back.gif
typedef struct
{
        uchar RedTimer;


学习了!!!{:handshake:}

大哈欠E 发表于 2013-4-9 16:06:00

liu_shu 发表于 2013-4-6 22:34 static/image/common/back.gif
你的问题不是你程序的问题,是你的心态、态度、方式方法的问题,一口吃个胖子,学技术慢慢积累,一个模块 ...

谁显牛叉了,你不要没事找事,不指教就算了,还在这里排斥新手,倚老卖老。

大哈欠E 发表于 2013-4-9 16:07:19

shenghui12321 发表于 2013-4-8 09:59 static/image/common/back.gif
c语言功底还需要磨练啊

嗯,我知道。

大哈欠E 发表于 2013-4-9 16:13:14

icoyool 发表于 2013-4-7 12:24 static/image/common/back.gif
typedef struct
{
        uchar RedTimer;


嗯,我已经该正确了,能运行了,我现在想写个中断,比如说这交通灯有个人为的控制按钮,他的功能是当有车的车道是红灯而无车的车道却是绿灯时,我可以改变一下,让有车的车道是绿灯 无车的车道红灯 通行时间是15秒

我想问的是在中断当中可以调用延时函数延时这15秒吗??
困惑。

大哈欠E 发表于 2013-4-9 16:15:22

电源模块 发表于 2013-4-7 00:27 static/image/common/back.gif
27楼正解。第一次写程序,包括一个新项目,板子做好之后,第一次试着运行的程序,尽量段,一般七八行,十几 ...

嗯 我找到原因了 谢谢

大哈欠E 发表于 2013-4-9 16:16:01

elecfun 发表于 2013-4-6 22:54 static/image/common/back.gif
小白问个问题都在这里JJYY,照你这说法遇到问题是不是非得自己研究到死?

谢谢帮忙说好话。。呵呵

solojimes 发表于 2013-4-9 16:16:50

liu_shu 发表于 2013-4-5 18:09 static/image/common/back.gif
第一次就写这么长!好像绝大多数男的第一次都不会高潮吧?女的也是

我高潮了

mhw 发表于 2013-4-9 16:19:36

搞个板子吧……

icoyool 发表于 2013-4-9 17:30:44

大哈欠E 发表于 2013-4-9 16:13 static/image/common/back.gif
嗯,我已经该正确了,能运行了,我现在想写个中断,比如说这交通灯有个人为的控制按钮,他的功能是当有车 ...

中断中还延时15秒?0.5ms我都认为是程序有问题了

大哈欠E 发表于 2013-4-9 21:53:15

苏子木00 发表于 2013-4-7 10:47 static/image/common/back.gif
程序亟待优化。。。lz思路很乱啊

嗯 由于第一次写,不懂模块化,等以后再模块化编程吧。。我现在又要写一个中断,前面的问题解决了,我现在又要写一个中断,感觉进行不下去了,更加混乱,掌控不了这个程序了。。。哎 菜鸟啊

大哈欠E 发表于 2013-4-9 21:53:47

icoyool 发表于 2013-4-9 17:30 static/image/common/back.gif
中断中还延时15秒?0.5ms我都认为是程序有问题了

嗯,那应该怎样写啊。。

Lu.Shi 发表于 2013-4-10 11:32:07

程序写的太不好读了,太长了,建议一步一步的实现,我认为首先实现以下单个路口的交通灯的指示,然后这样把问题可以简单化,也可以检验一下你的电路是否有问题,然后第一步实现之后,你在加上一个函数,实现十字路口的交通灯控制。

bearalan 发表于 2013-4-11 23:20:15

确实好凌乱,作为大四的师兄应该说一点看法,首先思路问题,交通灯其实就是计时然后切换led的状态,在interrupt的时候只是用来加量计时和判断清零的同时增加的一个标志位来控制,比如说你上面的程序中每次进入中断mm++,那么下面加个判断例如
...
if(mm >= 60)
{
    flag_A=1;
    mm=0;
}
else if(mm >= 25)
flag_B=1;
...
这样的话你就等于有了两个计时控制,一个是25秒,一个是35秒;当然,中断里面不要执行太多的命令,具体怎么写还是要想一想的。

然后是led切换的问题,其实可以用switch case根据状态来控制,这样会很简单。

siyeb 发表于 2013-4-12 15:03:02

状态机。

电子爱好者_MCU 发表于 2013-4-12 15:50:43

好好学习 天天向上

绿茶山人 发表于 2013-4-16 14:36:15

大哈欠E 发表于 2013-4-5 21:51 static/image/common/back.gif
嗯,学习了一些。。凌峰的也学过一些。

楼主要注意编码风格了!

大哈欠E 发表于 2013-4-21 08:27:00

bearalan 发表于 2013-4-11 23:20 static/image/common/back.gif
确实好凌乱,作为大四的师兄应该说一点看法,首先思路问题,交通灯其实就是计时然后切换led的状态,在inter ...

恩 我已经重新写了 。。现在思路很清晰,折腾;了几天已经做好了 ,呵呵 谢谢
页: [1]
查看完整版本: 我还是学生,第一次凭自己的思路写程序,请大神指教,急