You are on page 1of 19

#define F_CPU 16000000UL // tan so hoat dong 16MHz

#include <avr/io.h>
#include <avr/sfr_defs.h> // bit_is_set,bit_is_clear
#include <avr/interrupt.h> // thu vien khai bao ngat
#include <util/delay.h> // thu vien su dung delay ms
#include <stdio.h> // thu vien macro C

int denxanh = 20;


int dendo = 23;
int denvang = dendo-denxanh;
int red = dendo;
int yellow = denvang;
int green = denxanh;
int i, con, dx, dd, dv;
int chedo; // bien chon che do hien thi
int status = 0; //bien bat-tat he thong
int ngaydem = 0;//bien nightmode - normal
int caodiem = 0;//bien rushhor - normal
int menu = 0, menu_num = 0, menu_ok = 0;
/*cac bien chon che do tang giam so menu, den do, den xanh,
den do - den xanh cung luc*/
char somenu[10], sodendo[10], sodenxanh[10], sodenvang[10];
//cac mang luu gia tri hien thi len lcd-usart
char r[3]; //mang nhan chuoi ky tu usart
int check;

//--- HIEN THI TREN LCD ---//


#define E PINB5 // chan enable
#define RW PINB6 // chan chon che do read-write
#define RS PINB7 // chan chon thanh ghi lenh IR- DR

void lcd_setup(char data) // ghi lai 1 ky tu


{
// gui 4 bit cao den A4-A7
PORTA = (PORTA & 0x0F)|(data & 0xF0);
PORTB &= ~(1<<RS); // RS = 0 thanh ghi lenh IR
PORTB &= ~(1<<RW); // RW = 0 hoat dong che do ghi
PORTB |= (1<<E); // RE = 1 bat dau khung truyen
_delay_us(5);
PORTB &= ~(1<<E); // RE = 1 ket thuc khung truyen
_delay_us(100);
// gui 4 bit thap den A4-A7
PORTA = (PORTA & 0x0F)|((data << 4) & 0xF0);
PORTB |= (1<<E); // RE = 1 bat dau khung truyen
_delay_us(5);
PORTB &= ~(1<<E); // RE = 1 ket thuc khung truyen
_delay_us(100);
}

// hien thi 1 ky tu
void lcd_display(char data)
{
// gui 4 bit cao den A4-A7
PORTA = (PORTA & 0x0F)|(data & 0xF0);
PORTB |= (1<<RS); // RS = 1 thanh ghi lenh DR
PORTB &= ~(1<<RW); // RW = 0 hoat dong che do ghi
PORTB |= (1<<E); // RE = 1 bat dau khung truyen
_delay_us(5);
PORTB &= ~(1<<E); // RE = 1 ket thuc khung truyen
_delay_us(100);

// gui 4 bit thap den A4-A7


PORTA = (PORTA & 0x0F)|((data << 4) & 0xF0);
PORTB |= (1<<E); // RE = 1 bat dau khung truyen
_delay_us(5);
PORTB &= ~(1<<E); // RE = 1 ket thuc khung truyen
_delay_us(100);
}

void lcd_init(void) // ham khoi tao lcd


{
_delay_ms(20);
lcd_setup(0x02); // quay ve man hinh chinh
lcd_setup(0x28); // chon che do truyen 4 bit
lcd_setup(0x0C); // bat man hien thi - tat con tro
lcd_setup(0x06); // con tro dich phai
lcd_setup(0x01); // xoa toan man hinh
lcd_setup(0x80); // dua con tro ve vi tri dau tien hang 1
}

// gui chuoi ky tu
void lcd_string (char *str)
{
for(int i = 0; str[i] != 0; i++)
{
lcd_display(str[i]);
}
}

// gui chuoi theo hang_cot


void lcd_xy_string (char row, char col, char *str)
{
if (row == 0 && col < 16){
lcd_setup((col & 0x0F)|0x80);
}
else if (row == 1 && col < 16){
lcd_setup((col & 0x0F)|0xC0);
}
lcd_string(str);
}

// xoa toan man hinh - dua con tro ve vi tri ban dau
void lcd_clear(){
lcd_setup(0x01);
lcd_setup(0x80);
}

//--- HAM HIEN THI TREN LED 7 THANH 2 SO ---//


unsigned char led[10] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
// khai bao mang gom cac so tu 0->9

// hien thi cho lan duong 1


void hienthi1(unsigned int x)
{
uint16_t temp, hc, hdv;
temp = x;
hc = temp/10;
hdv = temp%10;
//hien thi chu so hang chuc
PORTA = (0<<PINA1);
PORTA = (1<<PINA0);
PORTC = 0xFF;
PORTC = led[hc];
_delay_ms(1);
//hien thi chu so hang don vi
PORTA = (0<<PINA0);
PORTA = (1<<PINA1);
PORTC = 0xFF;
PORTC = led[hdv];
_delay_ms(1);
return;
}

// hien thi cho lan duong 2


void hienthi2(unsigned int x)
{
uint16_t temp, hc, hdv;
temp = x;
hc = temp/10;
hdv = temp%10;
//hien thi chu so hang chuc
PORTA = (0<<PINA3);
PORTA = (1<<PINA2);
PORTC = 0xFF;
PORTC = led[hc];
_delay_ms(1);
//hien thi chu so hang don vi
PORTA = (0<<PINA2);
PORTA = (1<<PINA3);
PORTC = 0xFF;
PORTC = led[hdv];
_delay_ms(1);
return;
}

//--- GIAO TIEP USART ---//


//ham khoi tao usart
void usart_init()
{
UBRRH = 0x00;
UBRRL = 103; // toc do baudrate = 9600
UCSRA = 0x00; // khoi tao thanh ghi dieu khien
UCSRB = (1<<TXEN) | (1<<RXEN) | (1<<RXCIE);
//cho phep truyen va nhan du lieu - su dung ngat
UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
//chon thanh ghi UCSRC - khong dong bo - khong kiem tra
bit chan le - 1bit stop - 8bit du lieu
sei(); // ngat toan cuc
}

// ham gui 1 ky tu
void usart_tx(char x)
{
UDR = x; // dua du lieu toi thanh ghi UDR de truyen
while ((UCSRA & (1<<UDRE)) == 0);// kiem tra bit UDRE rong
}
char usart_rx() //ham nhan 1 ky tu
{
while ((UCSRA & (1<<RXC)) == 0); // kiem tra bit RXC
return(UDR); // doc du lieu tu thanh ghi UDR
}
void usart_msg(char *c) // ham gui mot chuoi ky tu
{
while (*c != 0)
usart_tx(*c++);
}

// ham nhan mot chuoi ky tu


void usart_rstr(char *string)
{
char ch;
int i=0;
while (i<3)
{
ch = usart_rx();
*string = ch;
string++;
i++;
}
}
// ham ngat khi nhan du lieu qua usart
ISR(USART_RXC_vect)
{
usart_rstr(r);
if (r[0] == '0')
{
check = 0;
red = (((int)r[1] - 48)*10)+((int)r[2] - 48);
}
if (r[0] == '1')
{
check = 1;
yellow = (((int)r[1] - 48)*10)+((int)r[2] - 48);
}
if (r[0] == '2')
{
check = 2;
green = (((int)r[1] - 48)*10)+((int)r[2] - 48);
}
}

char tx_data[10]; //mang luu chuoi gui qua usart

//--- HAM DELAY CHO NIGHTMODE SU DUNG TIMER0 ---//


void delay_nightmode() //800ms
{
for(int i = 0; i < 800; i++){
TCNT0 = 192; //TCNT0 = 2^8 - 1 - (16000000*1ms/256)
TCCR0 |= (1<<CS02); // prescaler = 256
while((TIFR&0x01) == 0); // kiem tra bo dem tran TOV0
TCCR0 = 0; // ngung bo dem
TIFR = 0x01;
}
}

int main(void)
{
//--- KHAI BAO CHUC NANG INPUT OUTPUT CAC PORT ---//
DDRA = 0xFF;
//output 4 bit dieu khien led 7 thanh - 4 bit su dung lcd
DDRB = 0b11100000;
// input nut nhan on_off, night, menu, up down - output
RS,RW,E lcd
DDRC = 0b01111111;
// output led 7 thanh - input nut nhan gio cao diem
PORTC = 0xFF;
DDRD = 0xFF; // output den den giao thong
PORTD = 0x00;

//--- KHOI TAO LCD - USART ---//


lcd_init();
usart_init();

//-- KHAI BAO SU DUNG TIMER1 CHO HIEN THI LED 7 THANH --//
TCNT1 = 2900; //TCNT1 = 3035 = 2^16-1-(16000000*1s/256)
TCCR1A = 0x00; //mode normal
TCCR1B |= (1<<CS12); // prescaler = 256
TIMSK |= (1<<TOIE1); // khai bao mat na ngat
sei(); // ngat toan cuc

while (1)
{
if (check == 0)
{
dendo = red;
denxanh = dendo-denvang;
}
if (check == 1)
{
denvang = yellow;
denxanh = dendo-denvang;
}
if (check == 2)
{
denxanh = green;
dendo = denxanh+denvang;
}
// CHE DO BAT-TAT DEN GIAO THONG
if ((bit_is_clear(PINB,0) && status==0) || r[0]=='a'){
//nhan bit a -guide bat he thong
//gui gia tri so dendo, denxanh, denvang qua usart
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
sprintf(sodenvang,"%d",denvang);
usart_tx('s');
usart_tx(0x0d);
usart_msg(sodendo);
usart_tx(0x0d);
usart_msg(sodenvang);
usart_tx(0x0d);
usart_msg(sodenxanh);
usart_tx(0x0d);
usart_tx('p');
usart_tx(0x0d);
_delay_ms(20); // chong doi nut bam
if ((bit_is_clear(PINB,0) && status==0) ||
r[0]=='a'){
status = 1;
denvang = dendo - denxanh;
dd = dendo;
dx = denxanh;
dv = denvang;
i = dd*2;
con = dd*2;
lcd_clear();
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
sprintf(sodenvang,"%d",denvang);
while(bit_is_clear(PINB,0));
//gui gia tri so dendo, denxanh, denvang len lcd
lcd_xy_string(0,0,"SYSTEM: ON");
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);
lcd_xy_string(1,10,"Y:");
lcd_xy_string(1,12,sodenvang);
chedo = 1;
}
}
if ((bit_is_clear(PINB,0) && status==1) || r[0] == 'b')
{ //nhan bit b -guide tat he thong
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
sprintf(sodenvang,"%d",denvang);
usart_tx('s');
usart_tx(0x0d);
usart_msg(sodendo);
usart_tx(0x0d);
usart_msg(sodenvang);
usart_tx(0x0d);
usart_msg(sodenxanh);
usart_tx(0x0d);
usart_tx('p');
usart_tx(0x0d);
_delay_ms(20);
if ((bit_is_clear(PINB,0) && status==1) || r[0] ==
'b') {
status = 0;
menu_ok = 0;
menu = 0;
i = dendo*2;
con = dendo*2;
while(bit_is_clear(PINB,0));
lcd_clear();
chedo = 2;
}
}
// CHE DO BAN DEM - NIGHTMODE
if ((bit_is_clear(PINB,1) && status==1 && ngaydem==0)
|| r[0]=='c'){ // nhan bit c - guide bat che do nightmode
usart_tx('N');
// gui len bit N xac nhan che do nightmode tren guide
usart_tx(0x0d);
_delay_ms(20);
if ((bit_is_clear(PINB,1) && status==1 && ngaydem==0)
||r[0]=='c'){
ngaydem = 1;
while(bit_is_clear(PINB,1));
lcd_clear();
lcd_xy_string(1,0,"NIGHT MODE: ON");
chedo = 3;
}
}
if ((bit_is_clear(PINB,1) && status==1 && ngaydem==1)
|| r[0]=='e'){//nhan bit e - guide dua ve che do mac dinh
usart_tx('n');
// gui len bit n xac nhan ve che do mac dinh
usart_tx(0x0d);
_delay_ms(20);
if ((bit_is_clear(PINB,1) && status==1 &&
ngaydem==1) ||r[0]=='e'){
ngaydem = 0;
lcd_clear();
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
sprintf(sodenvang,"%d",denvang);
while(bit_is_clear(PINB,1));
lcd_xy_string(0,0,"SYSTEM: ON");
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);
lcd_xy_string(1,10,"Y:");
lcd_xy_string(1,12,sodenvang);
chedo = 1;
}
}
// CHE DO CAO DIEM - RUSH HOUR
if ((bit_is_clear(PINC,7) && status==1 && caodiem==0)
|| r[0] == 'd'){ // nhan bit d - guide bat che do rush hour
usart_tx('D');
// gui len bit D xac nhan bat che do rush hour
usart_tx(0x0d);
_delay_ms(20);
if ((bit_is_clear(PINC,7) && status==1 && caodiem==0)
|| r[0] == 'd'){
caodiem = 1;
dd = 50;
dx = 45;
dv = 5;
i = dd*2;
con = dd*2;
while(bit_is_clear(PINC,7));
lcd_clear();
lcd_xy_string(0,0,"RUSH HOUR: ON");
chedo = 1;
}
}
if ((bit_is_clear(PINC,7) && status==1 && caodiem==1)
|| r[0] == 'e'){
usart_tx('n');
// gui len bit n xac nhan ve che do mac dinh
usart_tx(0x0d);
_delay_ms(20);
if ((bit_is_clear(PINC,7) && status==1 &&
caodiem==1) || r[0] == 'e'){
caodiem = 0;
denvang = dendo - denxanh;
dd = dendo;
dx = denxanh;
dv = denvang;
i = dd*2;
con = dd*2;
lcd_clear();
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
sprintf(sodenvang,"%d",denvang);
while(bit_is_clear(PINC,7));
lcd_xy_string(0,0,"SYSTEM: ON");
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);
lcd_xy_string(1,10,"Y:");
lcd_xy_string(1,12,sodenvang);
chedo = 1;
}
}

// CHE DO MENU
if (bit_is_clear(PINB,2) && menu_ok == 0){
_delay_ms(20);
if (bit_is_clear(PINB,2) && menu_ok == 0){
menu_ok = 1;
lcd_clear();
while(bit_is_clear(PINB,2));
lcd_xy_string(0,0,"SETTING");
menu = 0;

}
}
if (bit_is_clear(PINB,2) && menu_ok == 1){
_delay_ms(20);
if (bit_is_clear(PINB,2) && menu_ok == 1){
menu = menu_num;
if (menu == 0){
menu_ok = 1;
}
else {
menu_ok = 0;
}
sprintf(somenu,"%d",menu_num);
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
menu_num = 0;
while(bit_is_clear(PINB,2));
menu = menu;
if (menu != 0) {
lcd_xy_string(0,0,somenu);
}
if (menu==1){
lcd_xy_string(0,3,"RED");
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
}
if (menu==2){
lcd_xy_string(0,3,"GREEN");
lcd_xy_string(1,0,"G:");
lcd_xy_string(1,2,sodenxanh);
}
if (menu==3){
lcd_xy_string(0,3,"RED & GREEN");
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);
}
}
}

// MENU TANG/GIAM THOI GIAN DEN XANH/ DEN DO/ DEN XANH
- DEN DOCUNG MOT LUC
switch(menu){
// che do tang giam so menu
case 0:
if (bit_is_clear(PINB,3) && menu_ok==1){
_delay_ms(20);
if (bit_is_clear(PINB,3) && menu_ok==1){
menu_num++;
if (menu_num>=4){
menu_num = 1;
}
lcd_clear();
sprintf(somenu,"%d",menu_num);
while(bit_is_clear(PINB,3));
lcd_xy_string(0,0,somenu);
if (menu_num==1){
lcd_xy_string(0,3,"RED");
}
if (menu_num==2){
lcd_xy_string(0,3,"GREEN");
}
if (menu_num==3){
lcd_xy_string(0,3,"RED & GREEN");
}

}
}
if (bit_is_clear(PINB,4) && menu_ok==1){
_delay_ms(20);
if (bit_is_clear(PINB,4) && menu_ok==1){
menu_num--;
if (menu_num <= 0){
menu_num = 3;
}
lcd_clear();
sprintf(somenu,"%d",menu_num);
while(bit_is_clear(PINB,4));
lcd_xy_string(0,0,somenu);
if (menu_num==1){
lcd_xy_string(0,3,"RED");
}
if (menu_num==2){
lcd_xy_string(0,3,"GREEN");
}
if (menu_num==3){
lcd_xy_string(0,3,"RED & GREEN");
}
}
}
break;

// che do tang giam so den do


case 1:
if (bit_is_clear(PINB,3) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,3) && menu_ok==0){
if (red<99){
red++;
}
dendo = red;
denvang = dendo-denxanh;
yellow = denvang;
sprintf(sodendo,"%d",dendo);
while(bit_is_clear(PINB,3));
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);

}
}
if (bit_is_clear(PINB,4) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,4) && menu_ok==0){
if (red>green){
red--;
}
dendo = red;
denvang = dendo-denxanh;
yellow = denvang;
sprintf(sodendo,"%d",dendo);
while(bit_is_clear(PINB,4));
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);

}
}
break;

// che do tang giam so den xanh


case 2:
if (bit_is_clear(PINB,3) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,3) && menu_ok==0){
if (green<red){
green++;
}
denxanh = green;
denvang = dendo-denxanh;
yellow = denvang;
sprintf(sodenxanh,"%d",denxanh);
while(bit_is_clear(PINB,3));
lcd_xy_string(1,0,"G:");
lcd_xy_string(1,2,sodenxanh);

}
}
if (bit_is_clear(PINB,4) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,4) && menu_ok==0){
if (green>0){
green--;
}
denxanh = green;
denvang = dendo-denxanh;
yellow = denvang;
sprintf(sodenxanh,"%d",denxanh);
while(bit_is_clear(PINB,4));
lcd_xy_string(1,0,"G:");
lcd_xy_string(1,2,sodenxanh);

}
}
break;

// che do tang giam so den do den xanh cung luc


case 3:
if (bit_is_clear(PINB,3) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,3) && menu_ok==0){
if (red<99){
red++;
green++;
}
dendo = red;
denxanh = green;
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
while(bit_is_clear(PINB,3));
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);

}
}
if (bit_is_clear(PINB,4) && menu_ok==0){
_delay_ms(20);
if (bit_is_clear(PINB,4) && menu_ok==0){
if (green>0){
red--;
green--;
}
dendo = red;
denxanh = green;
sprintf(sodendo,"%d",dendo);
sprintf(sodenxanh,"%d",denxanh);
while(bit_is_clear(PINB,4));
lcd_xy_string(1,0,"R:");
lcd_xy_string(1,2,sodendo);
lcd_xy_string(1,5,"G:");
lcd_xy_string(1,7,sodenxanh);

}
}
break;
}

// CAC CHE DO HIEN THI


switch(chedo){
// hien thi 4 led7 thanh 2 so - 2 lan duong
case 1:
if (i<=con && i>(con-dx)){
PORTD = 0b10000100;
hienthi1(i-(con-dx));
hienthi2(i-(con-dd));
}
if (i<=(con-dx) && i>(con-dd)){
PORTD = 0b10001000;
hienthi1(i-(con-dd));
hienthi2(i-(con-dd));
}
if (i<=(con-dd) && i>(con-dd-dx)){
PORTD = 0b00110000;
hienthi1(i);
hienthi2(i-dv);
}
if (i<=(con-dd-dx) && i>0){
PORTD = 0b01010000;
hienthi1(i);
hienthi2(i);
}
break;

//tat toan bo he thong


case 2:
PORTA = 0x00;
PORTD = 0x00;
PORTC = 0xFF;
i = dd*2;
break;

//hien thi nhap nhay den vang


case 3:
PORTA = 0x00;
PORTC = 0xFF;
i = dd*2;
PORTD = 0x48; // bat den vang1 vang2
delay_nightmode(); //delay 800ms
PORTD = 0x00; // tat den vang 1-2
delay_nightmode(); //delay 800ms
break;
}

}
}
ISR(TIMER1_OVF_vect)
{
TCNT1 = 2900; // dat lai gia tri cho TIMER1
i--;
if(i == 0){
i = dd*2;
}
// gui gia tri bien i qua usart
if (status == 1){
sprintf(tx_data, "%d",i);
usart_msg(tx_data);
usart_tx(0x0d);
}
}

You might also like