신호등 C 언어 마이크로컨트롤러. 인터럽트 기능 문제
Wen Ziqi 등의 "51 마이크로컨트롤러 C 언어 혁신 튜토리얼"을 참조하세요.
소스 코드는 "51 Microcontroller C Language Innovation Tutorial"에서 가져왔습니다.
/*실험명 : 신호등 실험*설명 : 신호등 실험은 빨간색 신호등 15초, 녹색 신호등 10초, 노란색 신호등이 켜져야 합니다. 5초 동안.
빨간불이 녹색불로 전환되거나 녹색불이 빨간불로 전환되면
빛이 깜박입니다. 빨간색 표시등, 녹색 표시등, 노란색 표시등의 조명 지속 시간은 직렬 포트를 통해 수정할 수 있으며,
값은 다음 주기에 업데이트됩니다.
*저자: Wen Ziqi* 수정일: 2010/5/4 *참고: 코드 설명 및 설명은 "51 마이크로컨트롤러 C 언어 혁신 튜토리얼" Wen Ziqi et al., Beijing University of Aeronautics and Astronautics Press*/를 참조하세요. p>
#include?"stc.h"
typedef?unsigned?charUINT8;
typedef?unsigned?int UINT16;
typedef?unsigned ?longUINT32;?
typedef?charINT8;
typedef?int?INT16;
typedef?longINT32;
#define?TIMER0_INITIAL_VALUE ?5000
p>#define?HIGH1
#define?LOW0
#define?ON?1
#define?OFF0
#define?SEG_PORTP0
#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;}
# 정의?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_10
#define?TRAFFIC_STATUS_21
# 정의?TRAFFIC_STATUS_32
#define?UART_MARKER0xEE
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;
<p>UINT8?val[4];?
}LIGHT_VAL;
typedef?union?_LIGHT_VAL_EX
{ LIGHT_VAL?lv[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(무효)
{
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을 시작하시겠습니까?
}
void?PortInit(void )
{
?P0=P1=P2=P3=0xFF;
}
void?UartInit(void) p >
{
SCON=0x40;
T2CON=0x34;
RCAP2L=0xD9;
RCAP2H=0xFF
REN=1;
ES=1;
}
void?UartSend
바이트(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;
}
그렇지 않습니까?
{
for(i=0;i<4;i++)
{ LightCurCount[i]=LightOrgCount[i];
}
TrafficLightStatus=0;
}
스위치(TrafficLightStatus)
{
케이스?0 :
{
NORTH_R_LIGHT(켜짐);
SOUTH_R_LIGHT(꺼짐);
NORTH_G_LIGHT(꺼짐);
SOUTH_G_LIGHT(ON);
NORTH_Y_LIGHT(OFF);
SOUTH_Y_LIGHT(OFF);
}
휴식;
p> p>사례?1:
{
if(LightCurCount[1]%2)
{
NORTH_R_LIGHT( 켜짐);
SOUTH_G_LIGHT(켜짐);
}
else
{
NOR
TH_R_LIGHT(끄기);
SOUTH_G_LIGHT(끄기);
}
NORTH_Y_LIGHT(켜기);
SOUTH_Y_LIGHT(켜기);
}
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 )인터럽트?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 )? 인터럽트?1?
{
ET0 =?0;
TH0?=?(65536-TIMER0_INITIAL_VALUE)/256;
TL0?=?(65536-TIMER0_INITIAL_VALUE)%256;?//타이밍 1MS
Timer0IRQEvent=1;<
/p>
ET0 =?1;
}
======================== ============================================
편히 앉아서 포인트를 얻으세요!