交通灯 C语言 单片机。中断函数问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了交通灯 C语言 单片机。中断函数问题相关的知识,希望对你有一定的参考价值。

protues图如下。
P0接红绿灯,P1接数码管选择端,P2接数码管
主程序部分可以流畅运行。就是中断interrupt部分的问题。
开关1和2按下去时可以中断,开关再打开的时候无法回到正常情况时灵时不灵
开关3按下后怎么样都回不到正常状态
#include <reg51.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
uchar h;
uint r=0;
uint s;
uchar code dis[]=
0Xc0,/*0*/
0Xf9,/*1*/
0Xa4,/*2*/
0Xb0,/*3*/
0X99,/*4*/
0X92,/*5*/
0X82,/*6*/
0Xf8,/*7*/
0X80,/*8*/
0X90,/*9*/
0Xff,/*NULL*/
;
void delay(uint c)

uint i,j;
for(i=0;i<c;i++)
for(j=0;j<100;j++);

//interrupt 1
void t0(void) interrupt 0 using 1

delay(2);
if(INT0==0)

r++;
if(r==2)

r=0;

r%=2;
if(r==0)

P0=0xeb;
P1=0x00;
P2=0xff;
while(1)

if(INT0==0|INT1==0|T0==0)

delay(2);
if(INT0==0|INT1==0|T0==0)
break;

;


//interrupt 2
void t1(void) interrupt 2 using 1

delay(2);
if(INT1==0)

r++;
if(r==2)

r=0;

r%=2;
if(r==0)

P0=0xdd;
P1=0x00;
P2=0xff;
while(1)

if(INT1==0|INT0==0|T0==0)

delay(2);
if(INT1==0|INT0==0|T0==0)
break;


;


//interrupt 3
void t2(void) interrupt 1 using 1

TH0=0xff;
TL0=0xff;
delay(2);
if(T0==0)

P0=0xdb;
P1=0x00;
P2=0xff;
while(1)

if(INT0==0|INT1==0)

delay(2);
if(INT0==0|INT1==0)
break;


;


void main(void)

TMOD=0x06;
TH0=0xff;
TL0=0xff;
TR0=1;
EA=1;
EX0=1;
EX1=1;
ET0=1;
while(1)

P0=0xeb;
for(h=28;h>0;h--)

for(s=248;s>0;s--)

P1=0x00;
P2=0xff;
P1=0x01;
P2=dis[h/10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x02;
P2=dis[h%10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x04;
P2=dis[(h+2)/10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x08;
P2=dis[(h+2)%10];
delay(1);


delay(248);
P0=0xf3;
for(h=3;h>0;h--)

delay(392);
P0=0xf3;
delay(1):
P1=0x00;
P2=0xff;
P1=0xaa;
P2=dis[(h-1)%10];
delay(600);
P0=0xfb;

delay(248);
P0=0xdd;
for(h=38;h>0;h--)

for(s=248;s>0;s--)

P1=0x00;
P2=0xff;
P1=0x01;
P2=dis[(h+2)/10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x02;
P2=dis[(h+2)%10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x04;
P2=dis[h/10];
delay(1);
P1=0x00;
P2=0xff;
P1=0x08;
P2=dis[h%10];
delay(1);


delay(248);
P0=0xde;
for(h=3;h>0;h--)

delay(392)
P0=0xde;
delay(1);
P1=0x00;
P2=0xff;
P1=0xaa;
P2=dis[(h-1)%10];
delay(600);
P0=0xdf;

delay(248);


有高手可以帮改的话我可以发C文件和protues图给你,多谢了

参考《51单片机C语言创新教程》温子祺等著。

源码转自:《51单片机C语言创新教程》。

/*实验名称:交通灯实验

 *描    述:交通灯实验要求红灯亮15秒,绿灯亮10秒,黄灯亮5秒,

           当红灯切换为绿灯或者绿灯切换为红灯,

   要实现灯闪烁。红灯、绿灯、黄灯的点亮持续时间可以通过串口来修改,

   并在下一个循环中更新数值。

 *作    者:温子祺

 *修改日期:2010/5/4

 *说    明:代码注释与讲解详见《51单片机C语言创新教程》温子祺等著,北京航空航天大学出版社

 */

#include "stc.h"

typedef unsigned char   UINT8;

typedef unsigned int UINT16;

typedef unsigned long   UINT32;  

typedef char            INT8;

typedef int             INT16;

typedef long            INT32;

   

#define TIMER0_INITIAL_VALUE 5000

#define HIGH               1

#define LOW                0

#define ON                 1

#define OFF                0

#define SEG_PORT           P0

#define LS164_DATA(x)      if((x))P0_4=1;else P0_4=0;         

#define LS164_CLK(x)       if((x))P0_5=1;else P0_5=0; 

#define NORTH_R_LIGHT(x)   if((x))P2_0=0;else P2_0=1;

#define NORTH_Y_LIGHT(x)   if((x))P2_1=0;else P2_1=1;

#define NORTH_G_LIGHT(x)   if((x))P2_2=0;else P2_2=1;

#define SOUTH_R_LIGHT(x)   if((x))P2_3=0;else P2_3=1;

#define SOUTH_Y_LIGHT(x)   if((x))P2_4=0;else P2_4=1;

#define SOUTH_G_LIGHT(x)   if((x))P2_5=0;else P2_5=1;

#define TRAFFIC_STATUS_1   0

#define TRAFFIC_STATUS_2   1

#define TRAFFIC_STATUS_3   2

 

#define UART_MARKER        0xEE    

UINT8  Timer0IRQEvent=0;

UINT8  Time1SecEvent=0;

UINT8  Time500MsEvent=0;

UINT8  TimeCount=0;

UINT8  SegCurPosition=0;

UINT8  LightOrgCount[4]=15,5,15,5;

UINT8  LightCurCount[4]=15,5,15,5;

UINT8  TrafficLightStatus=0;

code UINT8  SegCode[10]   =0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90;

     UINT8  SegBuf[4]     =0;

code UINT8  SegPosition[4]=0x07,0x0b,0x0d,0x0e;

typedef struct _LIGHT_VAL

    UINT8 Head;   

    UINT8 val[4]; 

LIGHT_VAL;

typedef union _LIGHT_VAL_EX

     LIGHT_VAL lv;

     UINT8    p[5]; 

LIGHT_VAL_EX;

void LS164Send(UINT8 byte)

   UINT8 j;

   for(j=0;j<=7;j++)

   

     if(byte&(1<<(7-j)))

     

    LS164_DATA(HIGH);

 

 else

 

    LS164_DATA(LOW);

 

     LS164_CLK(LOW); 

     LS164_CLK(HIGH);

       

   

void RefreshDisplayBuf(UINT8 s1)  //刷新显示缓存

SegBuf[0] = s1%10;

SegBuf[1] = s1/10;

SegBuf[2] = s1%10;

SegBuf[3] = s1/10;

void SegDisplay(void)

   UINT8  t;

   

   t = SegCode[SegBuf[SegCurPosition]]; 

   SEG_PORT |= 0x0f;

   LS164Send(t); 

   SEG_PORT = (SEG_PORT|0x0f) & SegPosition[SegCurPosition];

   if(++SegCurPosition>=4) 

   

    SegCurPosition=0;

   

  

void TimerInit(void)

   TH1 = 0;

   TL1 = 0; 

   TH0 = (65536-TIMER0_INITIAL_VALUE)/256;

   TL0 = (65536-TIMER0_INITIAL_VALUE)%256; //定时1MS

   TMOD = 0x51; /*01010001 T1计数,T0定时*/

  

void Timer0Start(void)

     TR0 = 1; //启动计时器1 

 ET0 = 1;

void Timer0Stop(void)

     TR0 = 0; //启动计时器1 

     ET0 = 0;  

void PortInit(void)

 P0=P1=P2=P3=0xFF;

void UartInit(void)

SCON=0x40;

T2CON=0x34;

RCAP2L=0xD9;

RCAP2H=0xFF;

REN=1;

    ES=1;

void UartSendByte(UINT8 byte)

SBUF=byte;

    while(TI==0);

    TI=0;

void UartPrintfString(INT8 *str)

while(str && *str)

    

UartSendByte(*str++);

    

void main(void)

    UINT8 i=0;

PortInit();

TimerInit();

    Timer0Start();

    UartInit();

    RefreshDisplayBuf(LightCurCount[0]);

    EA=1;

    NORTH_R_LIGHT(ON);

    SOUTH_G_LIGHT(ON);

while(1)

    

if(Timer0IRQEvent)

 

            Timer0IRQEvent=0;

            TimeCount++;

  

            if(TimeCount>=200)

            

TimeCount=0;

if(LightCurCount[0])

                

                    TrafficLightStatus=0;

                

else if(LightCurCount[1])

                

                    TrafficLightStatus=1;

                

else if(LightCurCount[2])

                   

                    TrafficLightStatus=2;

                

                else if(LightCurCount[3])

                

TrafficLightStatus=3;

                

                

                else 

                

                   for(i=0;i<4;i++)

                   

                     LightCurCount[i]=LightOrgCount[i];

                   

                   TrafficLightStatus=0;

                

switch(TrafficLightStatus)

case 0:

                    

                        NORTH_R_LIGHT(ON);

                        SOUTH_R_LIGHT(OFF);

                        NORTH_G_LIGHT(OFF);

                        SOUTH_G_LIGHT(ON);

NORTH_Y_LIGHT(OFF);

                        SOUTH_Y_LIGHT(OFF);

                    

                    break;

                    

                    case 1:

                    

                        if(LightCurCount[1]%2)

                        

   NORTH_R_LIGHT(ON);

                           SOUTH_G_LIGHT(ON);

                        

                        else

                        

   NORTH_R_LIGHT(OFF);

                           SOUTH_G_LIGHT(OFF);

                        

NORTH_Y_LIGHT(ON);

                        SOUTH_Y_LIGHT(ON);

                    

                    break;

                    case 2:

                    

                        NORTH_R_LIGHT(OFF);

                        SOUTH_R_LIGHT(ON);

                        NORTH_G_LIGHT(ON);

                        SOUTH_G_LIGHT(OFF);

NORTH_Y_LIGHT(OFF);

                        SOUTH_Y_LIGHT(OFF);

                    

                    break;

                       

                    case 3:

                    

                        if(LightCurCount[3]%2)

                        

   NORTH_G_LIGHT(ON);

                           SOUTH_R_LIGHT(ON);

                        

                        else

                        

   NORTH_G_LIGHT(OFF);

                           SOUTH_R_LIGHT(OFF);

                        

NORTH_Y_LIGHT(ON);

                        SOUTH_Y_LIGHT(ON);

                    

                    break;  

                    

                   default:break;                  

                

                RefreshDisplayBuf(LightCurCount[TrafficLightStatus]);

                LightCurCount[TrafficLightStatus]--;

            

            

SegDisplay();

        

        

    

void UartIRQ(void)interrupt 4 

  static UINT8 cnt=0;

  static LIGHT_VAL_EX LightValEx;

  if(RI)

     

     RI=0;

 LightValEx.p[cnt++]=SBUF;

     if(LightValEx.lv.Head == UART_MARKER)

       

if(cnt>=5)

        

for(cnt=1;cnt<5;cnt++)

            

LightOrgCount[cnt-1]=LightValEx.lv.val[cnt]; 

                LightCurCount[cnt-1]=LightValEx.lv.val[cnt];

               

            

            cnt=0;

            UartPrintfString("设置交通灯完成\\r\\n");

        

     

     else

     

cnt=0;

     

  

  

void Timer0IRQ(void) interrupt 1 

ET0 =  0;

TH0 = (65536-TIMER0_INITIAL_VALUE)/256;

    TL0 = (65536-TIMER0_INITIAL_VALUE)%256; //定时1MS

Timer0IRQEvent=1;

    

ET0 =  1;

=====================================================================

坐等拿分!

参考技术A #include <reg51.h>
int x,y,i,j,k; //变量声明
int d0,d1,d2,d3;
void com_led(); //函数声明
void com_interrupt();
void delay(x);

void main()
com_led(); // 灯初始化
com_interrupt(); // 外部中断0初始化
doP1=0x0C; //东西向亮红灯55秒,南北向亮绿灯55秒,
delay(11);
P1=0x0A; //东西向亮红灯5秒,南北向亮绿灯5秒,
delay(1);
P1=0x21; //东西向亮绿灯55秒,南北向亮红灯55秒,
delay(11);
P1=0x11; //东西向亮黄灯55秒,南北向亮红灯55秒,
delay(1);

while(1);

//外部中段0服务子程序
int accident() interrupt 0
y=P1; //现场保护
d0=x;
d1=i;
d2=j;
d3=k;
P1=0x09; //急救车通过,东西南北向均亮红灯5秒
delay(1);
x=d0; //现场恢复 1
i=d1;
j=d2;
k=d3;
P1=y;

//交通灯初始化函数
void com_led()
P1=0x09; //东西南北向灯均亮5秒
delay(1);

//外部中段0初始化函数
void com_interrupt()
EA=1;
EX0=1;
IT0=1;

//延时5*X秒函数
void delay(x)
dofor(i=0;i<7;i++)
for(j=0;j<215;j++)
for(k=0;k<200;k++);

while(--x);

单片机c语言中interrupt4表示啥意思

串口中断里用的

参考技术A 对51来说,
中断0
外部中断0
中断1
定时器1中断
中断2
外部中断1
中断3
定时器2中断
中断4
串口中断
当PC机发给51数据(通过RS232串口)时就会触发这个中断
一般要写个函数响应中断,函数名随便,但是格式必须一定:
例如
void
UART_Interrupt_Receive(void)
interrupt
4

unsigned
char
k
=
0;
if
(RI==1)

RI
=
0;
k
=
SBUF;
....

else


以上是关于交通灯 C语言 单片机。中断函数问题的主要内容,如果未能解决你的问题,请参考以下文章

单片机C语言如何满足条件就立即退出中断函数

求51单片机中,用C语言写的五个中断源的中断函数的书写规则,就是进入中断函数时的那个函数名,并说明...

单片机C语言中断函数的定义形式是怎样的?

51单片机c语言中断函数不能进行参数传递,是啥意思,谁能解释一下

51单片机中断 C语言?请教!

单片机C语言中,中断子程序后面为啥要加interrupt这个单词?