日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]基于51單片機的貪吃蛇實例

 一、元器件

1、AT89C51

關(guān)于51單片機就不在啰嗦了,相信大家都已經(jīng)很熟悉了。

2、8x8點陣

點陣里面就是一些二極管啦,通過縱橫交叉連接,橫8豎8,每個交叉點都接一個二極管。這里給大家找到一個點陣的實物圖

 


 

我想大家看到這個圖就應(yīng)該知道如何去點亮一個點陣了。假如要點亮最左上角那個,那么9號引腳拉高,13號引腳拉低,這樣既可。

二、原理圖

 


 

 


 

三、項目分析

1、首先定義一個結(jié)構(gòu)體

struct snake{

unsigned char x[20];

unsigned char y[20];

unsigned char length;

unsigned char direction;

}snk;

數(shù)組x,y分別存放每一個點的橫縱坐標,length為蛇的長度,direction為蛇前進的方向

2、坐標系:點陣的左下角為點(0,0),橫縱坐標都是正向增長,P2控制橫坐標;P0控制縱坐標。通過坐標可以找到點陣中點的位置,然后將其點亮

假設(shè)現(xiàn)在有第2個點的坐標x[2] = 1, y[2] = 2,那么點亮這個點的方式為

P2 = 0x04; //0000 0100

P0 = 0xfb; //1111 1011

3、按鍵產(chǎn)生外部中斷,在中斷里判斷按下那個方向get_direction(),并且同時設(shè)置坐標set_location()

4、定時器每隔1s就應(yīng)該更新位置,因為蛇要不停的前進。定時器不需要更新方向,因為方向只有按鍵才會改動,定時器用前一步的方向

5、關(guān)于點的位置更新方式

1)、向上移動

后面的點去覆蓋前面的點,第一個點用新坐標表示x[0]不變,y[0]+1

2)、向下移動

后面的點去覆蓋前面的點,第一個點用新坐標表示x[0]不變,y[0]-1

3)、向左移動

后面的點去覆蓋前面的點,第一個點用新坐標表示x[0]-1,y[0]不變

4)、向右移動

后面的點去覆蓋前面的點,第一個點用新坐標表示x[0]+1,y[0]不變

6、關(guān)于邊界問題:

1)、任何一個點的橫坐標 0 <= x[i] < 8

2)、任何一個點的縱坐標 0 <= y[i] < 8

3)、第一個點在移動的時候不能和其他點重復,否則就自己追尾了

7、關(guān)于原理圖按鍵的設(shè)計

貪吃蛇要求系統(tǒng)能迅速響應(yīng)按鍵,因此輪詢的方式并不可取,只有靠外部中斷。然而51只有2個外部中斷,我們起碼需要4個方向鍵,這樣就不能一個按鍵配一個外部中斷,通過使用4輸入與門,將所有按鍵狀態(tài)集合在一起,然后送給外部中斷0。我們將4個按鍵都接在與門,只要有一個按下,那么與門的輸出就會產(chǎn)生一個下降沿,從而產(chǎn)生外部中斷。

四、源代碼

main.c

#include "snake.h"

int error = 0;

int time=0;

void interrupt_init()

{

EA = 0; //關(guān)閉總中斷

IT0 = 1; //外部中斷0方式 下降沿

EA = 1; //開啟總中斷

EX0 = 1; //開啟外部中斷

}

void timer_init()

{

EA = 0; //關(guān)總中斷

ET0 = 1; //開定時器0中斷

TMOD = 0x02; //定時器0工作方式2

TL0 = 6; //定時250us

TH0 = 6;

EA = 1; //開總中斷

TR0 = 1; //開始定時

}

int main()

{

// unsigned char tempx, tempy;

// unsigned char i,j;

interrupt_init();

timer_init();

snk_init();

while(1)

{

//如果位置錯了就重新初始化蛇

if(error)

snk_init();

//點亮點陣

matrix();

}

}

void inter0() interrupt 0

{

//按鍵產(chǎn)生外部中斷,獲取新的方向

get_direction();

//設(shè)置新的位置

error = set_location();

// matrix();

}

void timer0() interrupt 1

{

time++;

//定時器為250us 積累4000次就是1s

if(time == 4000)

{

//每隔1s都需要重新設(shè)置位置,讓蛇前進

error = set_location();

time = 0;

}

}

snake.c

點擊(此處)折疊或打開

#include "snake.h"

//蛇的結(jié)構(gòu)體,x為橫坐標,y為縱坐標,length為蛇的長度,direction為蛇的前進方向

struct snake{

unsigned char x[20];

unsigned char y[20];

unsigned char length;

unsigned char direction;

}snk;

void matrix()

{

unsigned char i;

int count=500;

//關(guān)閉所有的點

P2 = 0x00;

P0 = 0xff;

//根據(jù)蛇每一個點的坐標,將對應(yīng)的點陣點亮

for(i=0; i

{

P2 = 1<

P0 = ~(1<

}

}

void snk_init()

{

//初始化坐標,總共4個點(3,0) (2,0) (1,0) (1,0)

snk.x[0] = 3;

snk.y[0] = 0;

snk.x[1] = 2;

snk.y[1] = 0;

snk.x[2] = 1;

snk.y[2] = 0;

snk.x[3] = 0;

snk.y[3] = 0;

//初始長度4

snk.length = 4;

//初始移動方向 向右

snk.direction = RIGHT;

//點亮點陣

matrix();

}

void get_direction()

{

//通過按鍵的狀態(tài)獲取方向

if(!up)

snk.direction = UP;

if(!down)

snk.direction = DOWN;

if(!left)

snk.direction = LEFT;

if(!right)

snk.direction = RIGHT;

}

int set_location()

{

unsigned char i;

int err = 0;

if(snk.direction == UP)

{

for(i=snk.length-1; i>0; i--)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//如果向上運動,第0個點的橫坐標不變,縱坐標加1

snk.x[0] = snk.x[0];

snk.y[0] = snk.y[0] + 1;

}

else if(snk.direction == DOWN)

{

for(i=snk.length-1; i>0; i--)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//如果向下運動,第0個點的橫坐標不變,縱坐標減1

snk.x[0] = snk.x[0];

snk.y[0] = snk.y[0] - 1;

}

else if(snk.direction == LEFT)

{

for(i=snk.length-1; i>0; i--)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//如果向左運動,第0個點的橫坐標減1,縱坐標不變

snk.x[0] = snk.x[0] - 1;

snk.y[0] = snk.y[0];

}

else

{

for(i=snk.length-1; i>0; i--)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//如果向右運動,第0個點的橫坐標加1,縱坐標不變

snk.x[0] = snk.x[0] + 1;

snk.y[0] = snk.y[0];

}

err = is_location_error();

return err;

}

int is_location_error()

{

unsigned char i;

//如果第0個點的坐標和其他任意一個點重復,那么蛇就自己撞自己,出錯

for(i=1; i

{

if((snk.x[0]==snk.x[i]) && (snk.y[0]==snk.y[i]))

return 1;

}

//如果蛇的坐標超出范圍,也出錯

if(snk.x[0]>7 || snk.y[0]>7)

return 1;

return 0;

}

snake.h

#include

//定義四個方向按鍵

sbit up = P3^4;

sbit down = P3^5;

sbit left = P3^6;

sbit right = P3^7;

//定義1個游戲級別按鍵

sbit level = P3^0;

//定義一個復位按鍵

sbit reset = P3^1;

//定義4個方向的值

#define RIGHT 0

#define UP 1

#define LEFT 2

#define DOWN 3

void delay_us();

void delay_10us();

void delay_ms();

void delay_10ms();

void delay_100ms();

void delay_s();

int is_location_error();

void matrix();

void snk_init();

void set_direction();

int get_location();

int is_location_error();

『本文轉(zhuǎn)載自網(wǎng)絡(luò),版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系刪除』

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉