Traffic light – lập trình đèn giao thông phiên bản set time

  Ở phiên bản trước project Traffic light chỉ có chức năng điều khiển các đèn led và hiển thị số đếm, không thể cài đặt thời gian cho từng led bằng tay được. Trong phiên bản này, chúng ta hoàn toàn có thể cài đặt thời gian cho các đèn thông qua hệ thống button một cách dễ dàng.

   Để hiểu được project này nhanh hơn, bạn có thể xem lại các project cơ bản sau:

 Về cơ bản project này cũng giống như project “Mô phỏng đèn giao thông – Traffic light“, nhưng ở đây có sự update phần hệ thống cài đặt thời gian. Có nghĩa rằng, bạn hoàn toàn có thể thiết đặt thời gian cho các led một cách dễ dàng thông qua hệ thống các nút ấn.

Hệ thống nút ấn để cài đặt đèn giao thông

Bạn nhìn vào hình trên, hệ thống các button dùng để cài đặt thời gian cho các led bao gồm:

  • Nút (+): có chức năng tăng 1 đơn vị (s).
  • Nút (-): có chức năng giảm một đơn vị (s)
  • Set Red Led: khi bạn dùng các button (+), (-) để chọn thời gian, sử dụng button này để set thời gian cho LED đỏ.
  • Set Yellow Led: set thời gian cho LED vàng.
  • Set Blue Led: set thời gian cho LED vàng.
  • Enter: khi hoàn thành việc set thời gian cho các led, ta nhấn Enter để hệ thống vào hoạt động.

Khi bạn muốn thiết lập lại các thông số thì ấn button (Reset), lúc này chương trình sẽ khởi chạy từ đầu và bạn có thể cài đặt lại thời gian.

Bạn cần quan tâm đoạn code điều khiển của các button (khác với phiên bản trước):

/*Set thoi gian cho cac led*/
void set_time(){
do{
          if(Button(&portb,0,1,0)){ //Giam mot don vi
                                    time=time-1;
                                    i=time;
                                    display();
                                    delay_ms(100);
                     }
           if(Button(&portb,1,1,0)){ //Tang 1 don vi
                                    time=time++;
                                    i=time;
                                    display();
                                    delay_ms(100);
                     }
           if(Button(&portb,2,1,0)){  //set den do
                                    dkd=time;
                                    }
           if(Button(&portb,3,1,0)){ //set den vang
                                    dkv=time;
                                    }
           if(Button(&portb,4,1,0)){ //set den xanh
                                    dkx=time;
                                    }
           if(Button(&portb,5,1,0)){ //Enter
                                    break;
                                    }
}while(1);
}

Sau đây là code C của project, các chú thích và kết nối phần cứng được ghi rõ trong code, bạn cũng có thể xem trong file mô phỏng proteus.

/*
Ten Project: Traffic light, co them chuc nang dat thoi gian cho cac den led
Cmu: pic 16f877A, thach anh 8Mhz
Ket noi: Ta su dung porta de dieu khien 2 led 7 doan, portd (RD0…RD7) ket noi den 7 segment (a, b, c….dp),
         dieu khien 2 led ket noi RA0, RA1.
         He thong cac button dieu khien set thoi gian ket noi portb:
         -> giam 1 don vi ket noi RB0.
         -> tang 1 don vi ket noi RB1.
         -> set thoi gian led do ket noi RB2.
         -> set thoi gian led vang ket noi RB3.
         -> set thoi gian led xanh ket noi RB4.
         -> Enter thuc thi ket noi RB5.
         3 dn led ket noi nhu sau:
         -> Red led ket noi RC1.
         -> Yellow led ket noi RC2.
         -> Blue led ket noi RC3.
Author: localhost/dientudieukhien.net
Websire: localhost/dientudieukhien.net
*/
/*Tao ma hex cho led 7 doan CA*/
unsigned short mask(unsigned short num) {
         switch (num) {
         case 0 : return 0xc0;
         case 1 : return 0xf9;
         case 2 : return 0xa4;
         case 3 : return 0xb0;
         case 4 : return 0x99;
         case 5 : return 0x92;
         case 6 : return 0x82;
         case 7 : return 0xf8;
         case 8 : return 0x80;
         case 9 : return 0x90;
                         }
                                        }
unsigned short mask(unsigned short num);
unsigned short digit_no, digit10, digit1, digit, i, time, dkd, dkv, dkx;
/*Ngat interrupt de quet 2 led*/
void interrupt() {
if (digit_no==0) {
PORTA = 0; // Turn off both displays
PORTD = digit1; // Set mask for displaying ones on PORTD
PORTA = 1; // Turn on display for ones (LSD)
digit_no = 1;
} else {
PORTA = 0; // Turn off both displays
PORTD = digit10; // Set mask for displaying tens on PORTD
PORTA = 2; // Turn on display for tens (MSD)
digit_no = 0;
}
TMR0 = 0; // Reset counter TMRO
INTCON = 0x20; // Bit T0IF=0, T0IE=1
}
/*Ham con de chuyen doi, hien thi so*/
void display(){
digit = i % 10u;
digit1 = mask(digit); // Prepare mask for displaying ones
digit = (char)(i / 10u) % 10u;
digit10 = mask(digit); // Prepare mask for displaying tens
}
/*Set thoi gian cho cac led*/
void set_time(){
do{
          if(Button(&portb,0,1,0)){ //Giam mot don vi
                                    time=time-1;
                                    i=time;
                                    display();
                                    delay_ms(100);
                     }
           if(Button(&portb,1,1,0)){ //Tang 1 don vi
                                    time=time++;
                                    i=time;
                                    display();
                                    delay_ms(100);
                     }
           if(Button(&portb,2,1,0)){  //set den do
                                    dkd=time;
                                    }
           if(Button(&portb,3,1,0)){ //set den vang
                                    dkv=time;
                                    }
           if(Button(&portb,4,1,0)){ //set den xanh
                                    dkx=time;
                                    }
           if(Button(&portb,5,1,0)){ //Enter
                                    break;
                                    }
}while(1);
}
//Red led
void dendo(){
             for(i=0;i<=dkd;i++){
                 PORTC.F1=1;
                 PORTC.F2=0;
                 PORTC.F3=0;
                 display();
                 delay_ms(500);
                 }
              }
//Yellow led
void denvang(){
             for(i=0;i<=dkv;i++){
                 PORTC.F1=0;
                 PORTC.F2=1;
                 PORTC.F3=0;
                 display();
                 delay_ms(500);
                 }
              }
//Blue led
void denxanh(){
             for(i=0;i<=dkx;i++){
                 PORTC.F1=0;
                 PORTC.F2=0;
                 PORTC.F3=1;
                 display();
                 delay_ms(500);
                 }
              }
              
void main() {
OPTION_REG = 0x80; // Set RBPU
TMR0 = 0;          //Clear TMR0
INTCON = 0xA8; // Enable GIE, TMR0IE, RBIE
PORTA = 0; // Turn off both displays
TRISA = 0; // All port A pins are configured as outputs
TRISB=0XFF; // Port B as inputs
PORTB=0;    //Clear port B
TRISC=0X00; //Port C as outputs
PORTC=0;    //Clear port C
PORTD = 0; // Turn off all display segments
TRISD = 0; // All port D pins are configured as outputs
i=0;
time=0;
display();
set_time(); //Set time for three leds
do {
denxanh();
denvang();
dendo();
} while (1); // Endless loop
}