當前位置:首頁 » 編程語言 » c語言中斷函數問題
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言中斷函數問題

發布時間: 2022-09-11 18:11:31

A. 交通燈 c語言 單片機。中斷函數問題

參考《51單片機C語言創新教程》溫子祺等著。

源碼轉自:《51單片機C語言創新教程》。

/*實驗名稱:交通燈實驗

*描述:交通燈實驗要求紅燈亮15秒,綠燈亮10秒,黃燈亮5秒,

當紅燈切換為綠燈或者綠燈切換為紅燈,

要實現燈閃爍。紅燈、綠燈、黃燈的點亮持續時間可以通過串口來修改,

並在下一個循環中更新數值。

*作者:溫子祺

*修改日期:2010/5/4

*說明:代碼注釋與講解詳見《51單片機C語言創新教程》溫子祺等著,北京航空航天大學出版社

*/

#include"stc.h"

typedefunsignedcharUINT8;

typedefunsignedint UINT16;

typedefunsignedlongUINT32;

typedefcharINT8;

typedefintINT16;

typedeflongINT32;

#defineTIMER0_INITIAL_VALUE5000

#defineHIGH1

#defineLOW0

#defineON1

#defineOFF0

#defineSEG_PORTP0

#defineLS164_DATA(x){if((x))P0_4=1;elseP0_4=0;}

#defineLS164_CLK(x){if((x))P0_5=1;elseP0_5=0;}

#defineNORTH_R_LIGHT(x){if((x))P2_0=0;elseP2_0=1;}

#defineNORTH_Y_LIGHT(x){if((x))P2_1=0;elseP2_1=1;}

#defineNORTH_G_LIGHT(x){if((x))P2_2=0;elseP2_2=1;}

#defineSOUTH_R_LIGHT(x){if((x))P2_3=0;elseP2_3=1;}

#defineSOUTH_Y_LIGHT(x){if((x))P2_4=0;elseP2_4=1;}

#defineSOUTH_G_LIGHT(x){if((x))P2_5=0;elseP2_5=1;}

#defineTRAFFIC_STATUS_10

#defineTRAFFIC_STATUS_21

#defineTRAFFIC_STATUS_32

#defineUART_MARKER0xEE

UINT8Timer0IRQEvent=0;

UINT8Time1SecEvent=0;

UINT8Time500MsEvent=0;

UINT8TimeCount=0;

UINT8SegCurPosition=0;

UINT8LightOrgCount[4]={15,5,15,5};

UINT8LightCurCount[4]={15,5,15,5};

UINT8TrafficLightStatus=0;

codeUINT8SegCode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

UINT8SegBuf[4]={0};

codeUINT8SegPosition[4]={0x07,0x0b,0x0d,0x0e};

typedefstruct_LIGHT_VAL

{

UINT8Head;

UINT8val[4];

}LIGHT_VAL;

typedefunion_LIGHT_VAL_EX

{

LIGHT_VALlv;

UINT8p[5];

}LIGHT_VAL_EX;

voidLS164Send(UINT8byte)

{

UINT8j;

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

{

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

{

LS164_DATA(HIGH);

}

else

{

LS164_DATA(LOW);

}

LS164_CLK(LOW);

LS164_CLK(HIGH);

}

}

voidRefreshDisplayBuf(UINT8s1) //刷新顯示緩存

{

SegBuf[0]=s1%10;

SegBuf[1]=s1/10;

SegBuf[2]=s1%10;

SegBuf[3]=s1/10;

}

voidSegDisplay(void)

{

UINT8t;

t=SegCode[SegBuf[SegCurPosition]];

SEG_PORT|=0x0f;

LS164Send(t);

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

if(++SegCurPosition>=4)

{

SegCurPosition=0;

}

}

voidTimerInit(void)

{

TH1=0;

TL1=0;

TH0=(65536-TIMER0_INITIAL_VALUE)/256;

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

TMOD=0x51; /*01010001T1計數,T0定時*/

}

voidTimer0Start(void)

{

TR0=1; //啟動計時器1

ET0=1;

}

voidTimer0Stop(void)

{

TR0=0; //啟動計時器1

ET0=0;

}

voidPortInit(void)

{

P0=P1=P2=P3=0xFF;

}

voidUartInit(void)

{

SCON=0x40;

T2CON=0x34;

RCAP2L=0xD9;

RCAP2H=0xFF;

REN=1;

ES=1;

}

voidUartSendByte(UINT8byte)

{

SBUF=byte;

while(TI==0);

TI=0;

}

voidUartPrintfString(INT8*str)

{

while(str&&*str)

{

UartSendByte(*str++);

}

}

voidmain(void)

{

UINT8i=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;

}

elseif(LightCurCount[1])

{

TrafficLightStatus=1;

}

elseif(LightCurCount[2])

{

TrafficLightStatus=2;

}

elseif(LightCurCount[3])

{

TrafficLightStatus=3;

}

else

{

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

{

LightCurCount[i]=LightOrgCount[i];

}

TrafficLightStatus=0;

}

switch(TrafficLightStatus)

{

case0:

{

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;

case1:

{

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;

case2:

{

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;

case3:

{

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();

}

}

}

voidUartIRQ(void)interrupt4

{

staticUINT8cnt=0;

staticLIGHT_VAL_EXLightValEx;

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("設置交通燈完成 ");

}

}

else

{

cnt=0;

}

}

}

voidTimer0IRQ(void)interrupt1

{

ET0 =0;

TH0=(65536-TIMER0_INITIAL_VALUE)/256;

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

Timer0IRQEvent=1;

ET0 =1;

}

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

坐等拿分!

B. 怎樣在C語言中使用中斷函數

首先你要寫中斷函數
然後在主程序中像調用子函數一樣調用就可以了
舉個例子吧
#define uchar unsigned char
#define uchar unsigned char
sbit D1=P1^0;
uchar aa;
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}

void main()
{
init();
while(1)
{
if(aa==20)
{
D1=~D1;
aa=0;
}
}
}

void T0time()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}

C. 單片機C語言中斷函數的定義形式是怎樣的

形式如下:

void 中斷名(void) inerrupt 中斷號 using 工作寄存器組

比如外部中斷0

void ext0(void) interrupt 0 using 1 //後面的using 1可以省略,預設為0

定時器1

void t1isr() interrupt 3

(3)c語言中斷函數問題擴展閱讀:

單片機內部結構

1、CPU

它的名字沒有改,還是稱為CPU(Central Processing Unit)。它是單片機的核心部件,包括運算器和控制器。

運算器既是算術邏輯單元ALU(Arithmetic logic Unit),其功能是進行算術運算和邏輯運算。

控制器一般由指令寄存器、指令解碼器、時序電路和控制電路組成。其作用是完成取指令、將指令解碼形成各種微操作並執行指令,同時控制計算機的各個部件有條不紊地工作。

2、單片機內部結構之一ROM

硬碟」,改了名字,稱為程序存儲器,也叫只讀存儲器。用ROM(Read only memery)表示。其作用和計算機的硬碟差不多,用來存放用戶編寫的程序。特點是:掉電後不會丟失數據(程序)。

D. 51的C語言中斷是函數,那這個中斷是否可以調用如果能,怎麼調用

51的C語言中斷是函數,那這個中斷是否可以調用?如果能,怎麼調用?
只從計算機原理來講,是可以的。
理論上,中斷函數也是一個程序的入口,只要把程序指令指針指向這個中斷的入口地址,
就可以執行相應的代碼,從這個角度來講,是可操作的。
但在實際問題處理中,通常不行,因為中斷是提供給系統處理應急事件的,
並非設計來作為常規函數呼叫。
如果只是想要使用中斷處理中的某些功能,可把那些功能封裝為獨立的函數,
供給中斷處理和一般流程來調用。
應用程序直接調用中斷,是有違中斷設計的初衷的,
不建議這樣使用,易導致原本正常的流程的莫名異常,
因為調用中斷處理,會佔用中斷的相關資源,導致正常的中斷無法執行,出現異常。

E. 單片機c語言中斷函數

using1
表示用寄存器工作組1.。其實不加也可以,在c語言中,是自動分配寄存器的,所以可以不加。。
interrupt
1
後面數字是中斷源
,表示啟用中斷源1(定時器0).(51單片機里有5個中斷源)

F. C語言中斷/定時的疑問

中斷函數是不需要額外通過代碼調用的

當中斷條件滿足,單片機會打斷當前執行的語句,跳轉到中斷函數,然後執行完中斷函數後,再次返回之前被打斷的語句繼續執行

中斷函數中,每次都會對定時器重新初始化,即頭兩句對TH1和TL1的賦值,這樣每50ms會再次進入一次中斷函數.每20次進入中斷,即經過了1秒,然後對全局變數miao自增1

而main函數則是不斷對變數miao進行輸出

G. 單片機中斷函數C語言的問題

蜂鳴器響,需要每隔約 2ms 令 BEEP 翻轉一次。

這就需要用 T1 定時 2ms。

如果需要低頻,就需要更長的的定時。

參考程序如下:

H. 單片機c語言中斷函數

這是單片機C語言中斷函數的編程格式,()後面的只是告訴編譯系統該函數是一個中斷函數,具體的執行還是按照C語言函數的執行方式去執行。

I. 單片機c語言中斷函數中可以定義形參嗎

單片機c語言中斷函數中可以定義形參,但一般不需要這樣做。
中斷函數的定義格式如下:
函數類型
函數名
(形參)
interrupt
N
using
n
我們平時用的大多是KEIL編譯器,對於KEIL編譯器來說,中斷函數不需要輸入,也不返回參數,因此這里的函數類型和函數形參都應該為
void
類型。
n
表示使用的寄存器組,為
0---3,using是一個選項,可以省略,如果省略,有編譯器來選擇一個寄存器組作為絕對寄存器組。
N
表示中斷號(這個不能省略,而且比較重要),下列出來普通51單片機的中斷號和中斷源的對應關系:
中斷號
中斷源
0
外部中斷0
1
定時器0中斷
2
外部中斷1
3
定時器1中斷
4
串列口中斷
5
定時器2中斷
總之,一般來說,中斷函數不需要定義形參。

J. 51單片機c語言中斷函數不能進行參數傳遞,是什麼意思,誰能解釋一下

是指中斷處理函數不能有輸入參數也不能有函數返回。因為中斷都是些硬體自動調用,沒有程序去給他傳遞參數,也沒有硬體去接收參數。
不過x86計算機的軟中斷可以有參數傳遞,不過他是用寄存器傳遞的。