0% found this document useful (0 votes)
69 views60 pages

KTMT

Uploaded by

hosynguyenfc
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views60 pages

KTMT

Uploaded by

hosynguyenfc
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 60

KHOA ĐIỆN – ĐIỆN TỬ

MÔN: THỰC TẬP KIẾN TRÚC VÀ TỔ CHỨC MÁY TÍNH

BÁO CÁO CUỐI KỲ


***

Hồ Sỹ Nguyên 22119203
Huỳnh Kim Phát 22119209

HK1 NĂM HỌC 2024 -2025


MỤC LỤC

BÀI 1: CHẠY LED ...........................................................................................


BÀI 2: ĐÈN GIAO THÔNG ..............................................................................
BÀI 3: ĐÈN GIAO THÔNG TRÊN KIT………………………………………
BÀI 4: LỊCH VẠN NIÊN...................................................................................
BÀI 5: LỊCH VẠN NIÊN TRÊN KIT ...............................................................
BÀI 6: ĐIỀU KHIỂN TỪ XA ............................................................................
BÀI 7: NHÀ THÔNG MINH .............................................................................
BÀI 8: GAME CON RẮN ..................................................................................

1
Bài 1: CHẠY LED

#include <reg51.h>

void delay(unsigned int time) {


while( time--);
}

void main() {
unsigned i;
while (1) {
P0 = 0x00;
//sangdan
for(i=0;i<8;i++){
P0 = (P0<<1)|0x01;
delay(100000000);
}
//tatdan
for(i=0;i<8;i++){
P0= P0<<1 ;
delay(100000000);}
}
}

BÀI 2 : ĐÈN GIAO THÔNG

#include <REGX52.h>
#define Do0 P1_0
#define Do1 P1_1
#define Vang0 P1_2
#define Vang1 P1_3
#define Xanh0 P1_4
#define Xanh1 P1_5
#define SW_chedo P1_6
#define SW P1_7
#define dvi_DT P0_0
#define chuc_DT P0_1
#define dvi_BN P0_2
#define chuc_BN P0_3
#define Display P2
unsigned char Code7seg[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90};
int dem;
int tanso;
void delay_ms(unsigned int time)
{
unsigned int x, y;
for (x = 0; x < time; x++)
{
for (y = 0; y < 50; y++)
;
}
}

void Traffic_Auto(void)
{
Do0 = 0x01;
Do1 = 0x00;
Vang0 = 0x00;
Vang1 = 0x00;
Xanh0 = 0x00;
Xanh1 = 0x01;

// delay10s
for (dem = 18; dem >= 3; dem--)
{
for (tanso = 0; tanso < 35; tanso++)
{
int dem2 = dem - 3;
int chuc = dem2 / 10;
int dvi = dem2 % 10;
dvi_DT = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_DT = 0;
dvi_BN = 1;
Display = Code7seg[dvi];
delay_ms(10);
dvi_BN = 0;
chuc_DT = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_DT = 0;
chuc_BN = 1;
Display = Code7seg[chuc];
delay_ms(10);
chuc_BN = 0;
}
}
Vang0 = 0x00;
Vang1 = 0x01;
Xanh0 = 0x00;
Xanh1 = 0x00;
// delay3s
for (dem = 2; dem >= 0; dem--)
{
for (tanso = 0; tanso < 35; tanso++)
{

dvi_DT = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_DT = 0;
dvi_BN = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_BN = 0;
chuc_DT = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_DT = 0;
chuc_BN = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_BN = 0;
}
}
Do0 = 0x00;
Do1 = 0x01;
Vang0 = 0x00;
Vang1 = 0x00;
Xanh0 = 0x01;
Xanh1 = 0x00;
// delay10s

for (dem = 18; dem >= 3; dem--)


{
for (tanso = 0; tanso < 35; tanso++)
{
int dem2 = dem - 3;
int chuc = dem2 / 10;
int dvi = dem2 % 10;
dvi_BN = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_BN = 0;
dvi_DT = 1;
Display = Code7seg[dvi];
delay_ms(10);
dvi_DT = 0;
chuc_BN = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_BN = 0;
chuc_DT = 1;
Display = Code7seg[chuc];
delay_ms(10);
chuc_DT = 0;
}
}
Vang0 = 0x01;
Vang1 = 0x00;
Xanh0 = 0x00;
Xanh1 = 0x00;
// delay3s
for (dem = 2; dem >= 0; dem--)
{
for (tanso = 0; tanso < 35; tanso++)
{

dvi_BN = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_BN = 0;
dvi_DT = 1;
Display = Code7seg[dem % 10];
delay_ms(10);
dvi_DT = 0;
chuc_BN = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_BN = 0;
chuc_DT = 1;
Display = Code7seg[dem / 10];
delay_ms(10);
chuc_DT = 0;
}
}
}
void main(void)
{

while (SW_chedo == 1)
{

if (SW == 1)
{
if (Do1 == 1)
{
Do0 = 0x00;
Do1 = 0x01;
Vang0 = 0x00;
Vang1 = 0x00;
Xanh0 = 0x01;
Xanh1 = 0x00;

delay_ms(50);
}
Do0 = 0x00;
Do1 = 0x01;
Vang0 = 0x00;
Vang1 = 0x00;
Xanh0 = 0x01;
Xanh1 = 0x00;
dvi_BN = 0;
// Display = Code7seg[dem % 10];
delay_ms(10);

}
if (SW == 0)
{
if (Do0 == 1)
{
Do0 = 0x01;
Do1 = 0x00;
Xanh0 = 0x00;
Xanh1 = 0x01;
Vang0 = 0x00;
Vang1 = 0x00;
delay_ms(50);
}
Do0 = 0x01;
Do1 = 0x00;
Xanh0 = 0x00;
Xanh1 = 0x01;
Vang0 = 0x00;
Vang1 = 0x00;
dvi_BN = 0;
// Display = Code7seg[dem % 10];
delay_ms(10);

}
}

while (SW_chedo == 0)
{
Traffic_Auto();
}
}

BÀI 3 ĐÈN GIAO THÔNG TRÊN KIT

#include <AT89X52.h>

sbit SW_chedo = P3 ^ 2; //chan nhan tin hieu chuyen che do


sbit SW = P3 ^ 3; //chan nhan tin hieu chuyen huong
#define Display P0 //xuat du lieu led 7 doan
#define chonLED P2 //P2.4,P2.3,P2.2 dieukhien 8 led 7 doan

int chedo = 1;
int chuyenhuong = 1;
int chuyenVang = 0;

//du lien hien thi so


unsigned char code Code7segCatot[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,
0x7d, 0x07, 0x7f, 0x6f, 0x77};
//du lieu trang thai den
/*4 trang thai*/
/*do0 sang, vang0 tat, xanh0 tat, do1 tat, vang1 tat, xanh1 sang*/
/*do0 sang, vang0 tat, xanh0 tat, do1 tat, vang1 sang, xanh1 tat*/
/*do0 tat, vang0 tat, xanh0 sang, do1 sang, vang1 tat, xanh1 tat*/
/*do0 tat, vang0 sang, xanh0 tat, do1 sang, vang1 tat, xanh1 tat*/
unsigned char code StatusLED[] = {0x81, 0x82, 0x24, 0x44};

/*du lieu chan chon hien thi led P2 = {0}{0}{0}{P2.4}_{P2.3}{P2.2}{0}{0}*/


unsigned char code BNsochay[] = {0x00, 0x18, 0x04, 0x1c}, //Bacnam
DTsochay[] = {0x18, 0x00, 0x1c, 0x04}; //dongtay

void delay_ms(unsigned int time) {


/* f = 12M hz*/
/*f vào timer 1 = 12Mhz/12 = 1Mhz*/
/*T = 1/1Mhz= 1us*/
//1ms=1000us
// bo dem 16bit 2^16-1000=64536=E890
// dem 1000 lan
while (time--) {
TMOD = 0x01;// cau hinh timer1 16bit
TH1 = 0xE8;
TL1 = 0x90;
TR1 = 1;
while (!TF1) //bao tran bo nho
TF1 = 0; //rs timer1
}
}
void HienThiDen(char Status) {

int i;
P3_6 = 0; /*clock canh len*/
P3_5 = 0;/*chan chot du lieu*/
/*74hc595 nhan du lieu noi tiep khi xung canh lenh SH_CP tac dong,
moi xung canh len la nhan 1 bit
xuat du lieu khi xung canh lenh ST_CP tac dong*/
for (i = 0; i < 8; i++) {
P3_4 = Status>>7; // dich stt sang phai 7 bit , gan gtri vAO P3_4
Status <<=1; //dich trai 1 bit , de day them cac bit
delay_ms(1);
P3_6 = 1;
delay_ms(1);
P3_6 = 0; // moi xung giup ic ghi 1 bit du lieu tu P3_4 vao thanh ghi
}
P3_5 = 1;
//ghi du 8 bit vao thanh ghi dich , kich hoat chan de xuat du lieu

}
/*chi ho tro so 2 chu so*/ // chuyen so cac den
void HienThiSoChay(char *Huong, int demA, int demB) {
int tanso;
int dem;
for (dem = demA; dem >= demB; dem--) {
if (chedo == 1) {
return;
}
for (tanso = 0; tanso < 60; tanso++) {
chonLED = Huong[0];
Display = Code7segCatot[dem % 10]; // don vi
delay_ms(3);
chonLED = Huong[1];
Display = Code7segCatot[(dem - 3) % 10];
delay_ms(3);
chonLED = Huong[2];
Display = Code7segCatot[dem / 10]; // chuc
delay_ms(3);
chonLED = Huong[3];
Display = Code7segCatot[(dem - 3) / 10];
delay_ms(3);
Display = 0x00;
delay_ms(3);
}
}
}
/*chi ho tro so 2 chu so*/ // hieu ung nhap nhay
void HienThiSoVang(char *Huong, int demA, int demB) {
int tanso;
int dem;
for (dem = demA; dem >= demB; dem--) {
if (chedo == 1) // ngat dot ngot
{
return;
}
for (tanso = 0; tanso < 60; tanso++) {
chonLED = Huong[0];
Display = Code7segCatot[dem % 10]; // hang don vi
delay_ms(3);
chonLED = Huong[1];
Display = Code7segCatot[dem % 10];
delay_ms(3);
chonLED = Huong[2];
Display = Code7segCatot[dem / 10]; // hang chuc
delay_ms(3);
chonLED = Huong[3];
Display = Code7segCatot[dem / 10];
delay_ms(3);
Display = 0x00;
delay_ms(3);
}
}
}
void Traffic_Auto(void) {
// delay10s
HienThiDen(StatusLED[0]);
HienThiSoChay(BNsochay, 25, 4);
// delay3s
HienThiDen(StatusLED[1]);
HienThiSoVang(BNsochay, 4, 0);
// delay10s
HienThiDen(StatusLED[2]);
HienThiSoChay(DTsochay, 25, 4);
// delay3s
HienThiDen(StatusLED[3]);
HienThiSoVang(DTsochay, 4, 0);
}
void Interrupt_Timer0(void) {
/* f = 12M hz*/
/*f vào timer 0 = 12M/12 = 1M*/
/*T = 1/6M s*/
/* 1000 --> 1ms*/
/*64536--> 65535 -> 0 = 1ms*/
/* 16 bits timer */
TMOD = 0x01;
/* setup 1ms for overforlow */
TH0 = 0xFC;
TL0 = 0x18;
/* Enable interrupt */
ET0 = 1;
EA = 1;
/* Enable timer0 */
TR0 = 1;
}

void ISR_TIMER(void) interrupt 1 {


if (ET0 == 1) {
if (SW_chedo == 0) {
delay_ms(100);
if (SW_chedo == 1) {
chedo++;
}
if (chedo > 1)
chedo = 0;
}
/*setup 1ms for overforlow*/
TH0 = 0xFC;
TL0 = 0x18;
}
}

void main(void) {
Interrupt_Timer0();/*1ms interrupt se kiem tra trang thai chan SW_chedo*/
while (1) {
if (chedo) {
P0 = 0x00;
if (SW == 0) {
delay_ms(100);
if (SW == 1) {
chuyenhuong++;
}
if (chuyenhuong > 1)
chuyenhuong = 0;
}
if (chuyenhuong) {
if(chuyenVang){
HienThiDen(StatusLED[3]);
delay_ms(2000);
}
HienThiDen(StatusLED[0]);
chuyenVang = 0;
} else {
if(!chuyenVang){
HienThiDen(StatusLED[1]);
delay_ms(2000);
}
HienThiDen(StatusLED[2]);
chuyenVang = 1;
}
} else
Traffic_Auto();
}
}
BÀI 4 LỊCH VẠN NIÊN

#include"main.h"
#include"..\lib\Soft_I2c.h"
#include"..\lib\Lcd4.h"
#include"..\lib\Rtc_Ds1307.h"
#include"..\lib\LunarCalendar.h"
#include"Port.h"

unsigned char * code Days[] =


{"SUN","MON","TUE","WED","THU","FRI","SAT"};

void main()
{
unsigned char Hour, Minute, Second, Mode, Day, Date, Month, Year,
old_second;
unsigned char SolarDate, SolarMonth;
char SolarYear;

Soft_I2c_Init();
Ds1307_Init();
Lcd_Init();

while(1)
{
Ds1307_Read_Time(&Hour, &Minute, &Second, &Mode);
if(old_second != Second)
{
old_second = Second;

Lcd_Chr(1,5,Hour/10+0x30);
Lcd_Chr_Cp(Hour%10+0x30);
Lcd_Chr_Cp(':');
Lcd_Chr_Cp(Minute/10+0x30);
Lcd_Chr_Cp(Minute%10+0x30);
Lcd_Chr_Cp(':');
Lcd_Chr_Cp(Second/10+0x30);
Lcd_Chr_Cp(Second%10+0x30);

Ds1307_Read_Date(&Day, &Date, &Month, &Year);


if(BTN == 1)
{
Lcd_Out(2,1," ");
Lcd_Out(2,2,Days[Day-1]);
Lcd_Chr_Cp(' ');
Lcd_Chr_Cp(Date/10+0x30);
Lcd_Chr_Cp(Date%10+0x30);
Lcd_Chr_Cp('/');
Lcd_Chr_Cp(Month/10+0x30);
Lcd_Chr_Cp(Month%10+0x30);
Lcd_Out_Cp("/20");
Lcd_Chr_Cp(Year/10+0x30);
Lcd_Chr_Cp(Year%10+0x30);
}
else
{
Solar2Lunar(Date, Month, Year, &SolarDate,
&SolarMonth, & SolarYear);
Lcd_Out(2,1,"LUNAR:");
Lcd_Chr_Cp(SolarDate/10+0x30);
Lcd_Chr_Cp(SolarDate%10+0x30);
Lcd_Chr_Cp('/');
Lcd_Chr_Cp(SolarMonth/10+0x30);
Lcd_Chr_Cp(SolarMonth%10+0x30);
Lcd_Chr_Cp('/');
Lcd_Chr_Cp((Year+2000)/1000+0x30);
Lcd_Chr_Cp((Year+2000)/100%10+0x30);
Lcd_Chr_Cp((Year+2000)/10%10+0x30);
Lcd_Chr_Cp((Year+2000)%10+0x30);
}
}
}
}

+ Thư viện lcd

void Lcd_Init()
{
LCD_RS = 0;
LCD_EN = 0;
#ifdef USE_LCD_RW
LCD_RW = 0;
#endif

Delay_ms(20);
Lcd_Write_Low_Nibble(0x03);
LCD_EN = 1;
LCD_EN = 0;
Delay_ms(5);

Lcd_Write_Low_Nibble(0x03);
LCD_EN = 1;
LCD_EN = 0;
Lcd_Delay_us(100);

Lcd_Write_Low_Nibble(0x03);
LCD_EN = 1;
LCD_EN = 0;
#ifdef USE_CHECK_BUSY
Lcd_Busy();
#else
Delay_ms(1);
#endif

Lcd_Write_Low_Nibble(0x02);
LCD_EN = 1;
LCD_EN = 0;
Delay_ms(1);

Lcd_Cmd(_LCD_4BIT_2LINE_5x7FONT);
Lcd_Cmd(_LCD_TURN_ON);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_ENTRY_MODE);
}

void Lcd_Cmd(unsigned char cmd)


{
#ifdef USE_LCD_RW
LCD_RW = 0;
#endif
LCD_RS = 0;
Lcd_Write_High_Nibble(cmd);
LCD_EN = 1;
LCD_EN = 0;
Lcd_Write_Low_Nibble(cmd);
LCD_EN = 1;
LCD_EN = 0;

#ifdef USE_CHECK_BUSY
Lcd_Busy();
#else
switch(cmd)
{
case _LCD_CLEAR:
case _LCD_RETURN_HOME:
Delay_ms(2);
break;
default:
Lcd_Delay_us(37);
break;
}
#endif
}

void Lcd_Chr_Cp(unsigned char achar)


{
#ifdef USE_LCD_RW
LCD_RW = 0;
#endif
LCD_RS = 1;
Lcd_Write_High_Nibble(achar);
LCD_EN = 1;
LCD_EN = 0;

Lcd_Write_Low_Nibble(achar);
LCD_EN = 1;
LCD_EN = 0;

#ifdef USE_CHECK_BUSY
Lcd_Busy();
#else
Lcd_Delay_us(37+4);
#endif
}

void Lcd_Chr(unsigned char row, unsigned char column,


unsigned char out_char)
{
unsigned char add;
add = (row==1?0x80:0xC0);
add += (column - 1);
Lcd_Cmd(add);
Lcd_Chr_Cp(out_char);
}

void Lcd_Out_Cp(unsigned char * str)


{
unsigned char i = 0;
while(str[i])
{
Lcd_Chr_Cp(str[i]);
i++;
}
}

void Lcd_Out(unsigned char row, unsigned char column,


unsigned char* text)
{
unsigned char add;
add = (row==1?0x80:0xC0);
add += (column - 1);
Lcd_Cmd(add);
Lcd_Out_Cp(text);
}

+Thư viện i2c

void Soft_I2c_Init()
{
SOFT_I2C_SCL=1;
SOFT_I2C_SDA=1;
}

void Soft_I2c_Start()
{
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
SOFT_I2C_SDA = 0;
Soft_I2c_Delay();
SOFT_I2C_SCL = 0;
}

bit Soft_I2c_Get_Ack()
{
bit result;
SOFT_I2C_SDA = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
result = SOFT_I2C_SDA;
SOFT_I2C_SCL = 0;
return result;
}

bit Soft_I2c_Write(unsigned char dat)


{
unsigned char i;
for(i=0;i<8;i++)
{
SOFT_I2C_SDA = (bit)(dat&0x80);
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 0;
dat<<=1;
}
return(Soft_I2c_Get_Ack());
}

void Soft_I2c_Ack()
{
SOFT_I2C_SDA = 0;
Soft_I2c_Delay();
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 0;
}

void Soft_I2c_Nak()
{
SOFT_I2C_SDA = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 0;
}

unsigned char Soft_I2c_Read(bit ack)


{
unsigned char i, dat=0;
for(i=0;i<8;i++)
{
SOFT_I2C_SDA = 1;
Soft_I2c_Delay();
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
dat <<= 1;
if(SOFT_I2C_SDA)
{
dat |= 0x01;
}
SOFT_I2C_SCL = 0;
}
if(ack)
{
Soft_I2c_Ack();
}
else
{
Soft_I2c_Nak();
}
return dat;
}

void Soft_I2c_Stop()
{
SOFT_I2C_SDA = 0;
Soft_I2c_Delay();
SOFT_I2C_SCL = 1;
Soft_I2c_Delay();
SOFT_I2C_SDA = 1;
}

+Thư viện Ds1307

void Ds1307_Read_Date(unsigned char * day, unsigned char * date,


unsigned char * month, unsigned char * year)
{
Soft_I2c_Start();
Soft_I2c_Write(0xD0);
Soft_I2c_Write(0x03);
Soft_I2c_Start();
Soft_I2c_Write(0xD1);
*day = Soft_I2c_Read(1);
*date = Soft_I2c_Read(1);
*month= Soft_I2c_Read(1);
*year = Soft_I2c_Read(0);
Soft_I2c_Stop();
*day &= 0x07;
*date &= 0x3F;
*date = (*date>>4)*10 + (*date & 0x0F);
*month &= 0x1F;
*month = (*month>>4)*10 + (*month & 0x0F);
*year = (*year>>4)*10 + (*year & 0x0F);
}

bit Ds1307_Read_Time(unsigned char * hour, unsigned char * minute,


unsigned char * second, unsigned char * mode)
{
unsigned char h_tmp, m_tmp, s_tmp;
bit am_pm;
Soft_I2c_Start();
Soft_I2c_Write(0xD0);
Soft_I2c_Write(0x00);
Soft_I2c_Start();
Soft_I2c_Write(0xD1);
s_tmp = Soft_I2c_Read(1);
m_tmp = Soft_I2c_Read(1);
h_tmp = Soft_I2c_Read(0);
Soft_I2c_Stop();

s_tmp &= 0x7F;


*second = (s_tmp>>4)*10+(s_tmp&0x0F);
m_tmp &= 0x7F;
*minute = (m_tmp>>4)*10+(m_tmp&0x0F);

if(h_tmp & 0x40) // Mode 12h


{
*mode = 12;
if(h_tmp & 0x20)
{
am_pm = 1; // PM
}
else
{
am_pm = 0;
}
h_tmp &= 0x1F;
*hour = (h_tmp>>4)*10+(h_tmp&0x0F);
}
else
{
*mode = 24;
h_tmp &= 0x3F;
*hour = (h_tmp>>4)*10+(h_tmp&0x0F);
if(*hour<12)
{
am_pm = 0; // AM
}
else
{
am_pm = 1;
}
}
return am_pm;
}

+Thư viện LunarCalendar

#include"LunarCalendar.h"

// Lunar Calendar Lookup Table


// From 1/1/2000 to 31/12/2099
#define BEGINNING_YEAR 0
unsigned int code LUNAR_CALENDAR_LOOKUP_TABLE[] = {

//2000

0x1B79,0x099A,0x1A3A,0x125B,0x187B,0x109D,0x1ABE,0x18E2,0x1304,0x
1924,0x1346,0x1B66,

//2001

0x1987,0x0229,0x1A47,0x1068,0x1A89,0x108A,0x1AAB,0x18CC,0x10EE,0x1
B0F,0x1130,0x1B51,
//2002

0x1972,0x0394,0x1A32,0x1253,0x1873,0x1295,0x18B5,0x1AD7,0x10F8,0x191
9,0x133B,0x195B,……
//2099}

void Solar2Lunar(unsigned char SolarDate, unsigned char SolarMonth, unsigned


char SolarYear,
unsigned char * LunarDate, unsigned char * LunarMonth, char *
LunarYear)
{
unsigned char N_AL_DT_DL;
unsigned char T_AL_DT_DL;
unsigned char SN_CT_AL;
unsigned char TN_B_THT;
unsigned char N_AL_DT_DL_TT;
unsigned char T_AL_DT_DL_TT;

union LUNAR_RECORD lr;

lr.Word = LUNAR_CALENDAR_LOOKUP_TABLE[(SolarYear-
BEGINNING_YEAR)*12+SolarMonth -1];
N_AL_DT_DL = lr.Info.N_AL_DT_DL;
T_AL_DT_DL = lr.Info.T_AL_DT_DL;
SN_CT_AL = lr.Info.SN_CT_AL + 29;
TN_B_THT = lr.Info.TN_B_THT;

lr.Word = LUNAR_CALENDAR_LOOKUP_TABLE[(SolarYear-
BEGINNING_YEAR)*12+SolarMonth];
N_AL_DT_DL_TT = lr.Info.N_AL_DT_DL;
T_AL_DT_DL_TT = lr.Info.T_AL_DT_DL;

// Tinh ngay & thang


if(N_AL_DT_DL == SN_CT_AL && N_AL_DT_DL_TT == 2)
{
if(SolarDate==1)
{
(*LunarDate) = N_AL_DT_DL;
(*LunarMonth) = T_AL_DT_DL;
}
else if(SolarDate==31)
{
(*LunarDate) = 1;
(*LunarMonth) = T_AL_DT_DL_TT;
}
else
{
(*LunarDate) = SolarDate - 1;
if(TN_B_THT)
{
(*LunarMonth) = T_AL_DT_DL;
}
else
{
(*LunarMonth) = T_AL_DT_DL==12?1:
(T_AL_DT_DL + 1);
}
}
}
else
{
(*LunarDate) = SolarDate + N_AL_DT_DL - 1;
if((*LunarDate)<= SN_CT_AL)
{
(*LunarMonth) = T_AL_DT_DL;
}
else
{
(*LunarDate) -= SN_CT_AL;

(*LunarMonth) = T_AL_DT_DL + 1 - TN_B_THT;


if((*LunarMonth) == 13) (*LunarMonth) = 1;
}
}

// Tinh Nam
if(SolarMonth >= (*LunarMonth))
{
(*LunarYear) = SolarYear;
}
else
{
(*LunarYear) = SolarYear - 1;
}
}
BÀI 5 LỊCH VẠN NIÊN TRÊN KIT

#include <reg52.h> // Thư viện dành cho 8051, cung cấp các định nghĩa
cho cổng I/O và thanh ghi

// Định nghĩa các chân giao tiếp DS1302

sbit RST = P3^5; // Chân Reset (RST) của DS1302, dùng để bắt đầu
hoặc kết thúc giao tiếp

sbit SCLK = P3^6; // Chân xung clock (SCLK) để đồng bộ hóa dữ liệu
truyền và nhận

sbit IO = P3^4; // Chân truyền/nhận dữ liệu (I/O) của DS1302

// Định nghĩa nút nhấn chuyển đổi chế độ

sbit BUTTON = P3^7; // Chân kết nối nút nhấn, dùng để chuyển đổi giữa
hiển thị thời gian và ngày tháng

// Định nghĩa các chân điều khiển IC 74HC138 (giải mã 3 sang 8)

sbit SELECT_A = P2^2; // Đầu vào A của IC 74HC138

sbit SELECT_B = P2^3; // Đầu vào B của IC 74HC138

sbit SELECT_C = P2^4; // Đầu vào C của IC 74HC138

// Cổng dữ liệu LED 7 đoạn

#define SEG_PORT P0 // Cổng xuất dữ liệu để điều khiển LED 7 đoạn

// Biến toàn cục

unsigned char mode = 0; // Biến chế độ: 0 hiển thị thời gian, 1 hiển thị
ngày tháng

unsigned char debounce = 0; // Biến chống dội phím (debounce) khi nhấn nút

// Mã hiển thị LED 7 đoạn (0-9)


// Mỗi phần tử là mã nhị phân để hiển thị số tương ứng trên LED 7 đoạn (Cathode
Chung)

unsigned char code SEG_CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D,
0x07, 0x7F, 0x6F};

void delay_ms(unsigned int ms); // Hàm tạo độ trễ tính bằng mili giây

void DS1302_Init(void); // Hàm khởi tạo DS1302

// Hàm ghi dữ liệu vào DS1302

void DS1302_WriteByte(unsigned char addr, unsigned char dat);

// Hàm đọc dữ liệu từ DS1302

unsigned char DS1302_ReadByte(unsigned char addr);

void DisplayTime(void); // Hàm hiển thị thời gian trên LED 7 đoạn

void DisplayDate(void); // Hàm hiển thị ngày tháng trên LED 7 đoạn

void SelectSegment(unsigned char seg); // Hàm chọn LED 7 đoạn thông


qua IC 74HC138

/* Hàm cài đặt trước thời gian cho ds1302

void SetTime(void);

*/

void main() {

DS1302_Init(); // Khởi tạo DS1302 (đặt các chân RST và SCLK ở trạng
thái ổn định)
// SetTime(); // Cài đặt thời gian ban đầu

while (1) {

// Kiểm tra nút nhấn chuyển đổi chế độ

if (BUTTON == 0 && debounce == 0) { // Nếu nút được nhấn và


không bị dội

debounce = 1; // Đánh dấu trạng thái nút đã nhấn

mode = !mode; // Chuyển đổi chế độ: 0 <-> 1

delay_ms(50); // Trễ 50ms để chống dội phím

else if (BUTTON == 1) { // Thả nút nhấn

debounce = 0; // Đặt lại trạng thái khi nút được thả

// Hiển thị dữ liệu dựa trên chế độ hiện tại

if (mode == 0) { // Chế độ hiển thị thời gian

DisplayTime(); // Hiển thị thời gian (giờ, phút, giây)

else { // Chế độ hiển thị ngày tháng năm( mode = 1)

DisplayDate(); // Hiển thị ngày tháng (ngày, tháng, năm)

// Hàm tạo độ trễ (khoảng 1ms)

void delay_ms(unsigned int ms) {

unsigned int i, j;
for (i = 0; i < ms; i++) {

for (j = 0; j < 123; j++); // Dựa trên tần số dao động của vi điều khiển
(~12MHz)

// Khởi tạo DS1302

void DS1302_Init(void) {

RST = 0; // Đặt RST ở mức thấp

SCLK = 0; // Đặt SCLK ở mức thấp

// Hàm ghi 1 byte vào DS1302

void DS1302_WriteByte(unsigned char addr, unsigned char dat) {

unsigned char i;

RST = 1; // Kích hoạt giao tiếp DS1302 bằng cách đặt RST ở mức cao

// Gửi địa chỉ thanh ghi (8 bit)

for (i = 0; i < 8; i++) {

IO = addr & 0x01; // Xuất bit thấp nhất của địa chỉ lên chân I/O

SCLK = 1; // Xung clock tăng

addr >>= 1; // Dịch địa chỉ sang phải 1 bit

SCLK = 0; // Xung clock giảm

// Gửi dữ liệu (8 bit)

for (i = 0; i < 8; i++) {

IO = dat & 0x01; // Xuất bit thấp nhất của dữ liệu lên chân I/O

SCLK = 1; // Xung clock tăng

dat >>= 1; // Dịch dữ liệu sang phải 1 bit


SCLK = 0; // Xung clock giảm

RST = 0; // Kết thúc giao tiếp

// Hàm đọc 1 byte từ DS1302

unsigned char DS1302_ReadByte(unsigned char addr) {

unsigned char i, dat = 0;

addr |= 0x01; // Chuyển địa chỉ sang chế độ đọc (bit thấp nhất = 1)

RST = 1; // Kích hoạt giao tiếp

// Gửi địa chỉ thanh ghi (8 bit)

for (i = 0; i < 8; i++) {

IO = addr & 0x01; // Xuất bit thấp nhất của địa chỉ

SCLK = 1; // Xung clock tăng

addr >>= 1; // Dịch địa chỉ sang phải 1 bit

SCLK = 0; // Xung clock giảm

// Nhận dữ liệu (8 bit)

for (i = 0; i < 8; i++) {

dat >>= 1; // Dịch dữ liệu sang phải 1 bit

if (IO) dat |= 0x80; // Nếu IO = 1, đặt bit cao nhất của dữ liệu

SCLK = 1; // Xung clock tăng

SCLK = 0; // Xung clock giảm

RST = 0; // Kết thúc giao tiếp

return dat; // Trả về dữ liệu đọc được

}
// Hàm chọn LED 7 đoạn thông qua IC 74HC138 - giãi mã 3-8

void SelectSegment(unsigned char seg) {

SELECT_A = seg & 0x01; // Bit 0 của seg điều khiển SELECT_A

SELECT_B = (seg >> 1) & 0x01; // Bit 1 của seg điều khiển SELECT_B

SELECT_C = (seg >> 2) & 0x01; // Bit 2 của seg điều khiển SELECT_C

/*

// Cài đặt thời gian ban đầu

void SetTime(void) {

unsigned char hour = 12, minute = 30, second = 0; // Thời gian mặc định

unsigned char date = 25, month = 11, year = 24; // Ngày tháng mặc định

// Ghi dữ liệu vào DS1302

DS1302_WriteByte(0x84, hour);

DS1302_WriteByte(0x82, minute);

DS1302_WriteByte(0x80, second);

DS1302_WriteByte(0x86, date);

DS1302_WriteByte(0x88, month);

DS1302_WriteByte(0x8C, year);

*/

// Hàm hiển thị thời gian trên LED 7 đoạn

void DisplayTime(void) {

unsigned char hour, minute, second;


// Đọc giờ, phút, giây từ DS1302 dựa vào datasheet ds1302

hour = DS1302_ReadByte(0x85);

minute = DS1302_ReadByte(0x83);

second = DS1302_ReadByte(0x81);

// Hiển thị lần lượt từng giá trị

SEG_PORT = SEG_CODE[hour / 10]; // Hiển thị hàng chục của giờ

SelectSegment(7); delay_ms(5);

SEG_PORT = SEG_CODE[hour % 10]; // Hiển thị hàng đơn vị của giờ

SelectSegment(6); delay_ms(5);

SEG_PORT = SEG_CODE[minute / 10]; // Hiển thị hàng chục của phút

SelectSegment(4); delay_ms(5);

SEG_PORT = SEG_CODE[minute % 10]; // Hiển thị hàng đơn vị của phút

SelectSegment(3); delay_ms(5);

SEG_PORT = SEG_CODE[second / 10]; // Hiển thị hàng chục của giây

SelectSegment(1); delay_ms(5);

SEG_PORT = SEG_CODE[second % 10]; // Hiển thị hàng đơn vị của giây

SelectSegment(0); delay_ms(5);

// Hàm hiển thị ngày tháng trên LED 7 đoạn

void DisplayDate(void) {

unsigned char date, month, year;


// Đọc ngày, tháng, năm từ DS1302 dựa vào datasheet ds1302

date = DS1302_ReadByte(0x87);

month = DS1302_ReadByte(0x89);

year = DS1302_ReadByte(0x8D);

// Hiển thị lần lượt từng giá trị

SEG_PORT = SEG_CODE[date / 10]; // Hiển thị hàng chục của ngày

SelectSegment(7); delay_ms(5);

SEG_PORT = SEG_CODE[date % 10]; // Hiển thị hàng đơn vị của ngày

SelectSegment(6); delay_ms(5);

SEG_PORT = SEG_CODE[month / 10]; // Hiển thị hàng chục của tháng

SelectSegment(4); delay_ms(5);

SEG_PORT = SEG_CODE[month % 10]; // Hiển thị hàng đơn vị của tháng

SelectSegment(3); delay_ms(5);

SEG_PORT = SEG_CODE[year / 10]; // Hiển thị hàng chục của năm

SelectSegment(1); delay_ms(5);

SEG_PORT = SEG_CODE[year % 10]; // Hiển thị hàng đơn vị của năm

SelectSegment(0); delay_ms(5);

}
BÀI 6 ĐIỀU KHIỂN TỪ XA

#include "reg52.h" // Bao gồm thư viện chuẩn cho vi điều khiển
8051, cung cấp các định nghĩa cổng I/O

// Định nghĩa các chân điều khiển LED

sbit LED0 = P2^0; // Chân LED0 kết nối với P2^0

sbit LED1 = P2^1; // Chân LED1 kết nối với P2^1

sbit LED2 = P2^2; // Chân LED2 kết nối với P2^2

// Định nghĩa chân nhận tín hiệu IR và nút nhấn

sbit IRIN = P3^2; // Chân nhận tín hiệu IR (P3^2)

sbit BUTTON0 = P1^0; // Chân nút nhấn 0 (P1^0) để điều khiển LED0

sbit BUTTON1 = P1^1; // Chân nút nhấn 1 (P1^1) để điều khiển LED1

sbit BUTTON2 = P1^2; // Chân nút nhấn 2 (P1^2) để điều khiển LED2

unsigned char IrValue[6]; // Mảng lưu trữ giá trị tín hiệu IR nhận
được (6 byte)

unsigned char Time; // Biến đếm thời gian (dùng để phân biệt các tín hiệu
IR nhận được với nhau)

// Hàm tạo độ trễ (0.14ms mỗi lần lặp)

void DelayMs(unsigned int x)

unsigned char i;

while(x--) // Thực hiện vòng lặp x lần

for (i = 0; i < 13; i++) {} // Mỗi lần lặp tạo độ trễ nhỏ (khoảng 0.14ms)

}
}

// Hàm khởi tạo IR

void IrInit()

// Cấu hình ngắt ngoài và khởi động bộ thu IR

IT0 = 1; // Cấu hình ngắt ngoài INT0 ở chế độ cạnh xuống


(ngắt từ chân P3^2)

EX0 = 1; // Cho phép ngắt INT0

EA = 1; // Cho phép tất cả các ngắt trong hệ thống

IRIN = 1; // Khởi động bộ thu IR (sử dụng chân P3^2 để


nhận tín hiệu IR)

// Hàm xử lý ngắt IR

void ReadIr() interrupt 0

unsigned char j, k;

unsigned int err;

Time = 0; // Reset thời gian

DelayMs(70); // Delay nhỏ để xử lý tín hiệu IR

// Tín hiệu bắt đầu mức thấp

if (IRIN == 0) // Nếu tín hiệu IR đang ở mức thấp (bắt đầu


nhận tín hiệu IR)

err = 1000; // Thời gian chờ cho tín hiệu bắt đầu (9ms)

while((IRIN == 0) && (err > 0)) // Chờ tín hiệu xuống trong khoảng 9ms

DelayMs(1);
err--;

// Tín hiệu bắt đầu mức cao

if (IRIN == 1) // Nếu tín hiệu IR lên lại sau 9ms

err = 500;

while((IRIN == 1) && (err > 0)) // Chờ tín hiệu lên trong khoảng 4.5ms

DelayMs(1);

err--;

// Hàm đọc IR

for(k = 0; k < 6; k++) // Đọc 6 byte dữ liệu từ tín hiệu IR

for(j = 0; j < 8; j++) // Đọc từng bit trong mỗi byte

// Đọc bit 0

err = 60;

while((IRIN == 0) && (err > 0)) // Chờ tín hiệu thấp


trong khoảng 560us

DelayMs(1);

err--;

// Đọc bit 1

err = 500;
while((IRIN == 1) && (err > 0)) // Chờ tín hiệu lên
trong khoảng 560us

DelayMs(1);

Time++; // Đếm thời gian tín hiệu lên

err--;

if (Time > 30) // Nếu quá thời gian quy định, thoát

return;

IrValue[k] >>= 1; // Dịch trái giá trị nhận được

if (Time >= 8) // Nếu thời gian lên dài hơn 565us, ghi
1 vào bit hiện tại

IrValue[k] |= 0x80;

Time = 0; // Reset Time sau mỗi bit

if(IrValue[2] != ~IrValue[3]) // Kiểm tra mã tín hiệu và checksum

return; // Nếu mã không hợp lệ, thoát hàm

// Hàm chính
void main()

unsigned char i;

IrInit(); // Khởi tạo IR, thiết lập các ngắt và cấu hình tín hiệu IR

while(1)

// Kiểm tra tín hiệu IR và điều khiển LED dựa trên giá trị nhận được

if (IrValue[2] == 0x0c) // Nếu tín hiệu IR nhận được là 0x0c

LED0 = ~LED0; // Đảo trạng thái của LED0 (bật nếu


tắt, tắt nếu bật)

if (IrValue[2] == 0x18) // Nếu tín hiệu IR nhận được là 0x18

LED1 = ~LED1; // Đảo trạng thái của LED1

if (IrValue[2] == 0x5e) // Nếu tín hiệu IR nhận được là 0x5e

LED2 = ~LED2; // Đảo trạng thái của LED2

IrValue[2] = 0; // Reset giá trị IrValue[2] sau khi xử lý tín hiệu

// Kiểm tra trạng thái của các nút nhấn để điều khiển LED

if (BUTTON0 == 0) // Nếu nút nhấn 0 được nhấn (giả sử nút nhấn


sử dụng kiểu active-low)

LED0 = ~LED0; // Đảo trạng thái của LED0 (bật/tắt khi nhấn nút)

if (BUTTON1 == 0) // Nếu nút nhấn 1 được nhấn

LED1 = ~LED1; // Đảo trạng thái của LED1

if (BUTTON2 == 0) // Nếu nút nhấn 2 được nhấn

LED2 = ~LED2; // Đảo trạng thái của LED2


}

BÀI 7 NHÀ THÔNG MINH

#include"reg51.h"

#include"XPT2046.h"

#define GPIO_DIG P0

sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;

sbit led=P2^7;

unsigned char code DIG_CODE[17]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

// 0 1 2 3 4 5 6 7 8 9 A B C D E

unsigned char irKey = 0;//luu mã phím ir sau khi giải mã

unsigned long bitPattern = 0;//luu mã phím ir đã nhận được từ bộ thu ir

unsigned long newKey = 0;ma // mã phím ir mới vua nhận được

unsigned long pre_newKey = 0;

unsigned char timerValue;//luu giá trị thời gian đo được giữa các xung

unsigned char msCount = 0;

char pulseCount = 0;// đếm số lượng ir đã nhận từ 0 – 32 để hoàn thành một khung ir
void Timer0_Init(void);

unsigned char Decode_IRKey(unsigned char key);

void ToggleLED(unsigned char ledNum); // dao trang thai led

unsigned char DisplayData[8]; //

void DigDisplay(void);

void delay(unsigned int ms) {

unsigned int i, j;

for (i = 0; i < ms; i++) {

for (j = 0; j < 120; j++) {

; // Do nothing for delay

void main(void)

uint temp;

uint sec=5;

P2 = 0xFF; //

Timer0_Init(); //

EA = 1; //

while (1)

temp = Read_AD_Data(0xA4);// đọc giá


trị từ cảm biến ánh sáng
if(temp<150) led=0; // r quang tro <125
thi den sang

else led=1;

// đèn tắt

if ((newKey != 0) && (pre_newKey !=


newKey)) // bam phim moi

irKey = Decode_IRKey(newKey);
// giai ma phim

if (irKey == 1 ) // phim 1 thi


dao led 1

ToggleLED(irKey);

//

if( irKey==2 ) // phim 2 thi dao led


2

for(sec=5; sec>=0;sec--)

LSA=0;

LSB=0;

LSC=0;

GPIO_DIG=DIG_CODE[sec];

delay(1000);

if(sec==0)
{ToggleLED(irKey); break; }

}
}

// hen gio sang den

pre_newKey = newKey; // cap nha gia tri


truoc

void DigDisplay(void)

unsigned char i;

unsigned int j;

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

switch(i) //

case(0):

LSA=0;LSB=0;LSC=0; delay(1000); break;// led 0

case(1):

LSA=1;LSB=0;LSC=0; break;// led 1

case(2):

LSA=0;LSB=1;LSC=0; break;// led 2

case(3):

LSA=1;LSB=1;LSC=0; break;// led 3

case(4):

LSA=0;LSB=0;LSC=1; break;// led 4

case(5):

LSA=1;LSB=0;LSC=1; break;// led 5


case(6):

LSA=0;LSB=1;LSC=1; break;// led 6

case(7):

LSA=1;LSB=1;LSC=1; break;// led 7

GPIO_DIG=DisplayData[i];//?

j=50; //

while(j--);

GPIO_DIG=0x00;//

unsigned char Decode_IRKey(unsigned char key){

unsigned char returnValue = 0;

switch (key)

case 0xFF30CF: // Phim '1'

returnValue = 1;

break;

case 0xFF18E7: // Phim '2'

returnValue = 2;

break;

case 0xFF7A85: // Phim '3'

returnValue = 3;

break;

default:

returnValue = 0; // các phím khác ko hợp lệ

break;
}

return returnValue;

// Ngắt timer 0 đếm miligiaay

void timer0_isr() interrupt 1

if (msCount < 50)

msCount++;

// Cấu hình lại giá trị timer 0 để tiếp tục đếm 1ms

TH0 = 0xFC;

TL0 = 0x18; // Giá trị được tính cho tấn số 12MHz

//ngắt ngoài ir nhận tín hiện ir

void externalIntr0_ISR() interrupt 0

timerValue = msCount;// độ dài xung

msCount = 0;

TH0 = 0xFC;

TL0 = 0x18; // cấu hình lại timer 0

pulseCount++;

if ((timerValue >= 50)) // đánh dấu bắt đầu khung dữ liệu (Start Of Frame)

pulseCount = -2; // Bỏ qua hai xung của bit start


bitPattern = 0;//reset để lưu mã nhị phân mới dể cb nhận dữ liệu

else if ((pulseCount >= 0) && (pulseCount < 32)) // Tich luy gia tri bit tu 0 den 31

if (timerValue >= 2) // dô rông > 2ms tương ứng bit 1

bitPattern |= (unsigned long)1 << (31 - pulseCount);// Phép dịch bit (<<) được
sử dụng để tạo một giá trị chỉ chứa 1 bit 1 tại vị trí cụ thể,
}

else if (pulseCount >= 32) // Ket thuc khung khi nhan du 32 bit

newKey = bitPattern; // Luu ma phim moi

pulseCount = 0;

// Kh?i tao Timer0

void Timer0_Init(){

TMOD |= 0x01; // cau hinh timer 0 16-bit (MODE 1)

TH0 = 0xFC;

TL0 = 0x18; // dam bao rang ngat timer 0 sau 1ms

TR0 = 1; // Bat dau Timer0

ET0 = 1; // Cho phep ngat Timer0

IT0 = 1; // Cau hinh ngat ngoai INT0 kich hoat ? canh xuong

EX0 = 1; // Cho phep ngat ngoai INT0

// H?m d?i tr?ng th?i LED tuong ?ng

void ToggleLED(unsigned char ledNum){

// ledNum = 1, 2, 3 tuong ?ng v?i LED t?i P2.0, P2.1, P2.2


switch (ledNum) {

case 1:

P2 ^= 0x01; // LED1 (P2.0)

break;

case 2:

P2 ^= 0x02; // LED2 (P2.1)

break;

case 3:

P2 ^= 0x04; // LED3 (P2.

+Thư viện XPT2046

#include"XPT2046.h"

void SPI_Start(void)

CLK = 0;

CS = 1;

DIN = 1;

CLK = 1;

CS = 0;

void SPI_Write(uchar dat)

uchar i;

CLK = 0;

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


{

DIN = dat >> 7;

dat <<= 1;

CLK = 0;

CLK = 1;

uint SPI_Read(void)

uint i, dat=0;

CLK = 0;

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

dat <<= 1;

CLK = 1;

CLK = 0;

dat |= DOUT;

return dat;

uint Read_AD_Data(uchar cmd)

{
uchar i;

uint AD_Value;

CLK = 0;

CS = 0;

SPI_Write(cmd);

for(i=6; i>0; i--);

CLK = 1;

_nop_();

_nop_();

CLK = 0;

_nop_();

_nop_();

AD_Value=SPI_Read();

CS = 1;

return AD_Value;

BÀI 8 GAME RẮN SĂN MỒI

#include <regx52.h>

#include <stdlib.h>

/* Difficulty */

#define TIMER0_COUNTER_MAX 10

#define SNAKE_MAX_LENGTH 64

#define GAME_OVER 1

#define GAME_PLAYING 0

/* Define 74HC595 Pin */

sbit CLOCK = P3^6;


sbit LATCH = P3^5;

sbit DATA = P3^4;

/* Counter variables */

unsigned char timer2_counter = 0;// đếm các hàm hiển thị trên ma trận led

unsigned char timer0_counter = 0;// đếm số chu ky timer 0 để quyết định khi nào rắn di
chuyển

/* 8x8 Matrix Buffer */

unsigned char xdata displayBuffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};// lưu dữ liệu hiển thị cho
ma trân môi phần tử đại diện cho một hàng

// lưu giá trị của các phím nhan

/* 4x4 Keypad assigned value */

char code keypad[17] = {

10, 'u', 10, 10,

'l', 's', 'r', 10,

10, 'd', 10, 10,

10, 10, 10, 10,

10

};

/* A point on display */

typedef struct {

unsigned char x;

unsigned char y;

} Point;

/* Game objects */

Point xdata snake[SNAKE_MAX_LENGTH];

Point apple;
unsigned char snakeLength = 0;

unsigned char snakeDirection = 0;//luu hướng di chuyển hiện tại của rắn r,l,u,d

bit gameState = GAME_OVER;

void Snake_Display();

void Snake_Step();// xử lý rắn di chuyển

unsigned char isSnakeHitItself();

void Apple_Create();

void Apple_Display();

void Display_Clear();

void Display_Point(Point);

void Display_Point2(unsigned x, unsigned y);

void Keypad_Read();

char Keypad_Check();

char Keypad_Position(unsigned short value);// chuyển đổi giá trj cua ban phím thành
chỉ số trong mang keypad

/*//////////////////////////////////////2////////////////////////////*/

void Matrix_StartDisplay();

void Game_Init();

void Game_Start();

void Game_Stop();

void main () {

/* Variable to handle the keypad */

unsigned char counter2 = 0;

char key_clicked = 0;

char pre_key_clicked = 0;

/* Setup */

P1 = 0xff; //Set to 1 to use as input


P2 = 0;

P0 = 0;

EA = 1;

LATCH = 0;

DATA = 0;

CLOCK = 0;

/* Start display */

Matrix_StartDisplay();

/* Initialize the game */

Game_Init();

/* While loop. Check clicked key*/

while(1){

key_clicked = keypad[Keypad_Check()];

if((pre_key_clicked != key_clicked) && (key_clicked !=10)){

if ((gameState == GAME_OVER) && (key_clicked ='s'))

Game_Init();

Game_Start();

else if (gameState == GAME_PLAYING){

snakeDirection = key_clicked;

pre_key_clicked = key_clicked;

}
void Snake_Display(){

unsigned char counter2 = 0;

/*//////////////////////////////////////////3//////////////////////////*/

Display_Clear();

Apple_Display();

for(counter2 = 0; counter2 < snakeLength; counter2++){

Display_Point(snake[counter2]);

void Snake_Step(){

unsigned char counter2 = 0;

/* Remember the position of the tail */

Point snake_tail;

snake_tail.x = snake[snakeLength - 1].x;

snake_tail.y = snake[snakeLength - 1].y;

switch (snakeDirection)

/* Turn right */

// unsigned char là số nguyên không có dâu chạy tu 0 - 255

case 'r':

for(counter2 = snakeLength - 1; counter2 > 0; counter2--){

/* counter2 run from last point to 1 */

snake[counter2].x = snake[counter2 - 1].x;


snake[counter2].y = snake[counter2- 1].y;

snake [0].x = snake[0].x + 1; //Try to go right

if(snake[0].x == 8){

/* If hit the edge */

snake [0].x = 0;

break;

/* Turn left */

case 'l':

for(counter2 = snakeLength - 1; counter2 > 0; counter2--){

/* counter2 run from last point to 1 */

snake [counter2].x = snake[counter2 - 1].x;

snake[counter2].y = snake[counter2- 1].y;

snake [0].x --; //Try to go left

if (snake[0].x == 255){

/* If hit the edge */

snake [0].x = 7;

break;

case 'u':

for(counter2 = snakeLength - 1; counter2 > 0; counter2--){

/* counter2 run from last point to 1 */

snake [counter2].x = snake[counter2 - 1].x;

snake[counter2].y = snake[counter2 - 1].y;

}
snake [0].y++; //Try to go up

if(snake[0].y == 8){

/* If hit the edge */

snake [0].y = 0;

break;

case 'd':

for(counter2 = snakeLength - 1; counter2 > 0; counter2--){

/* counter2 run from last point to 1 */

snake [counter2].x = snake[counter2 - 1].x;

snake [counter2].y = snake[counter2 - 1].y;

snake[0].y --; //Try to go down

if(snake[0].y == 255){

/* If hit the edge */

snake[0].y = 7;

break;

default:

break;

/* If snake eat an apple */

if((snake[0].x == apple.x) && (snake[0].y == apple.y)){

snake[snakeLength].x = snake_tail.x;

snake[snakeLength].y = snake_tail.y;

snakeLength++; //Increase snake's length


Apple_Create();

/*///////////////////////////////////////////////////////////////////*/

/* If snake hit itself */

if(isSnakeHitItself()){

Game_Stop();

/* Update the snake on display */

Snake_Display();

unsigned char isSnakeHitItself(){

unsigned char returnValue = 0;

unsigned char counter2 = 0;

for(counter2 = 1; counter2 < snakeLength; counter2++){

returnValue = (snake[0].x == snake[counter2].x) && (snake[0].y ==


snake[counter2].y);

if (returnValue) break;

return returnValue;

void Apple_Display(){

Display_Point (apple);

void Apple_Create(){

unsigned char check = 1;

unsigned char counter2 = 0;

do

{
apple.x = ((unsigned int) rand()) % 8;

apple.y = ((unsigned int) rand()) % 8;

for (counter2 = 0; counter2 < snakeLength; counter2++)

check = (apple.x == snake[counter2].x) && (apple.y == snake [counter2].y);

if(check) break;

while (check);

/* Clear the display */

void Display_Clear(){

/*/////////////////////////////////////////////////////////////////////////////*/

unsigned char counter2 = 0;

for (counter2 = 0; counter2 < 8; counter2++)

displayBuffer [counter2] = 0;

/* Display a Point */

void Display_Point(Point point){

unsigned char x = point.x;

unsigned char y = point.y;

displayBuffer[7 - y] =displayBuffer[7- y] | (1 << (7-x));


}

char Keypad_Check(){

// mỗi lần đọc gái trị P1 sẽ thu được 4 bit giá trị cổng và dịch chúng vào clickpos

unsigned short clickPos = 0;

P1 = 0xef;

clickPos = (clickPos << 4) | (P1 & 0x0f);

P1 = 0xdf;

clickPos = (clickPos << 4) | (P1 & 0x0f);

P1 = 0xbf;

clickPos = (clickPos << 4) | (P1 & 0x0f);

P1 = 0x7f;

clickPos = (clickPos << 4) | (P1 & 0x0f);

return Keypad_Position(clickPos);

char Keypad_Position(unsigned short value){

char returnvalue = 16;

switch (value & 0xff)

case 0xf7:

returnvalue = 0;

break;

case 0xfb:

returnvalue = 1;

break;

case 0xfd:

returnvalue = 2;

break;

case 0xfe:

returnvalue = 3;
break;

case 0x7f:

returnvalue = 4;

break;

case 0xbf:

returnvalue = 5;

break;

case 0xdf:

returnvalue = 6;

break;

case 0xef:

returnvalue = 7;

break;

default:

value = value >> 8;

switch (value & 0xff)

case 0xf7:

returnvalue = 8;

break;

case 0xfb:

returnvalue = 9;

break;

case 0xfd:

returnvalue = 10;

break;

case 0xfe:

returnvalue = 11;

break;
case 0x7f:

returnvalue = 12;

break;

case 0xbf:

returnvalue = 13;

break;

case 0xdf:

returnvalue = 14;

break;

case 0xef:

returnvalue = 15;

break;

/*/////////////////////////////////////////////////////////////*/

break;

return returnvalue;

void Timer0_Isr(void) interrupt 1

TL0 = 0x00;

TH0 = 0x04;

timer0_counter++;

if(timer0_counter == TIMER0_COUNTER_MAX){

timer0_counter = 0;

Snake_Step();

//Initial timer vatue

//Initial timer value


}

void Game_Init(){

snakeLength = 3;

/* Initial apple position */

apple.x = 5;

apple.y = 5;

/* Initial snake position */

snake [2].x = 3;

snake [2].y = 3;

snake [1].x = 4;

snake [1].y = 3;

snake [0].x = 5;

snake [0].y = 3;

/* Initial direction */

snakeDirection = 'r';

gameState = GAME_OVER;

Snake_Display();

void Game_Start(void)

TMOD &= 0xF0;

TMOD |= 0x01;

TL0 = 0x00;

TH0 = 0x04;

TF0 = 0;

TR0 = 1;

//[email protected]
//Set timer work mode

//Set timer work mode

//Initial timer value

//Initial timer value

//Clear TF0 flag

//Timer0 start run

/*///////////////////////////////////////////////////*/

ET0 = 1;

//Stop the timer0

//[email protected]

//Initial timer work mode register

//Initial timer control register

//Initial timer value

//Initial timer value

//Set reload value

//Timer2 start run

//Enable timer0 interrupt

gameState = GAME_PLAYING;

void Game_Stop(){

TR0 = 0;
gameState = GAME_OVER;

void Timer2_Isr(void) interrupt 5

TF2 = 0;

DATA = timer2_counter == 0;

CLOCK = 1;

P0 = ~displayBuffer[7 - timer2_counter];// đảo giá trị của từng trạng thái của từng phần
tử

LATCH = 1;

timer2_counter++;

if(timer2_counter == 8) timer2_counter = 0;

CLOCK = 0;

LATCH = 0;

void Matrix_StartDisplay(void)

T2MOD =0;

T2CON = 0;

TL2 = 0xCD;

TH2 = 0xF8;

RCAP2L = 0xCD;

RCAP2H = 0xF8;

TR2 =1;

ET2 = 1;

You might also like