Pull to refresh

Ping-Pong на AVR

Reading time 3 min
Views 21K
В очередную уборку в мастерской довелось мне наткнуться на два матричных индикатора 8х8, там же была найдена Mega16, кнопки, макетка. «Какой же ты программист, если за свою жизнь ни разу не написал Тетрис?», спросил мозг.
Конец дня был посвящен тому, чтобы навесом спаять это все хозяйство.



Схема выглядит следующим образом:



К сожалению руки до Тетриса пока не дошли, размялся тем, что написал Пинг-Понг.
Видео работы устройства можно посмотреть тут (видео).

/*****************************************************
Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega16.h>
#include <delay.h>
#include <math.h>
#include <stdlib.h> 
#include <stdio.h>

int cnt = 0;
char src = 0, start = 0, tmp = 0, cx = 3, cy = 14, mx = 2, my = 15, ex = 3, ey = 0, dx = 1, dy = 1, fld[16][8], speed = 200;
char flds[16][8] = {{0,1,1,1,1,1,1,0},   // 0
                   {1,0,0,0,0,0,0,1},   // 1
                   {1,0,1,0,0,1,0,1},   // 2
                   {1,0,0,0,0,0,0,1},   // 3
                   {1,0,1,0,0,1,0,1},   // 4
                   {1,0,0,1,1,0,0,1},   // 5
                   {0,1,0,0,0,0,1,0},   // 6
                   {0,0,1,1,1,1,0,0},   // 7
                   
                   {0,0,0,0,0,0,0,0},   // 8
                   {0,0,0,0,0,0,0,0},   // 9
                   {0,0,0,0,0,0,0,0},   // 10
                   {0,0,0,0,0,0,0,0},   // 11
                   {0,0,0,0,0,0,0,0},   // 12
                   {0,0,0,0,0,0,0,0},   // 13
                   {0,0,0,0,0,0,0,0},   // 14
                   {0,0,0,0,0,0,0,0}};  // 15   
                   
void showsrc(void) {
char x = 0, y = 0;
    src = 0, start = 0, tmp = 0, cx = 3, cy = 14, mx = 2, my = 15, ex = 3, ey = 0, dx = 1, dy = 1, speed = 200;
    while (y < 16) { 
        x = 0;
        while (x < 8) {
            fld[y][x] = flds[y][x];
            x++;
        }
        y++;
    }
}
                              
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
    if (cnt >= speed) {
        if (start == 0) 
        {       
            fld[9][5]  = 0; fld[10][5] = 0;
            fld[11][5] = 0; fld[12][5] = 0; 
            fld[12][3] = 0; fld[12][7] = 0;
            fld[13][3] = 0; fld[13][5] = 0;
            fld[13][7] = 0; fld[13][4] = 0;
            fld[13][6] = 0; fld[14][4] = 0;
            fld[14][5] = 0; fld[14][6] = 0;
            fld[15][5] = 0;
            if (tmp == 0) { 
                fld[10][5] = 1; fld[11][5] = 1;
                fld[12][5] = 1; fld[13][3] = 1;
                fld[13][5] = 1; fld[13][7] = 1;
                fld[14][4] = 1; fld[14][5] = 1;
                fld[14][6] = 1; fld[15][5] = 1;           
            }
            else {
                fld[9][5]  = 1; fld[10][5] = 1;
                fld[11][5] = 1; fld[12][3] = 1;
                fld[12][5] = 1; fld[12][7] = 1;
                fld[13][4] = 1; fld[13][5] = 1;
                fld[13][6] = 1; fld[14][5] = 1;      
            };
            tmp++;
            if (tmp == 2) tmp = 0; 
        }
        else //game cycle
        {   
            fld[cy][cx] = 0;
            if (dy == 1) {
                if (cy > 0) cy--; 
                else {tmp = 0; start = 0; showsrc();}
            }
            else {
                if (cy < 15) cy ++;
                else {tmp = 0; start = 0; showsrc();}
            }      
            if ((cy == 1) && (fld[0][cx] == 1)) dy = 2;
            if ((cy == 1) && (fld[0][cx] == 0)) {tmp = 0; start = 0; showsrc();}  
            if ((cy == 14) && (fld[15][cx] == 1)) dy = 1;
            if ((cy == 14) && (fld[0][cx] == 0)) {tmp = 0; start = 0; showsrc();} 
            if (start == 1) {           
                if (dx == 1) {
                    cx--;
                    if (cx == 0) {dx = 2;} 
                }
                else {
                    cx++;
                    if (cx == 7) {dx = 1;}
                }
                fld[cy][cx] = 1;      
                if (PINC.7 == 0) {
                    delay_ms(1);
                    if (PINC.7 == 0) {
                        if ((mx > 0) && (mx != 0)) {mx--; fld[my][mx+3] = 0;}
                    }
                }    
                if (PINC.6 == 0) {
                    delay_ms(1);
                    if (PINC.6 == 0){ 
                        if ((mx < 5) && (mx != 5)) {mx++; fld[my][mx-1] = 0;}
                    }  
                } 
                ex = cx;
                if (cx > 5) ex = 5; 
                if (ex > 0) fld[ey][ex-1] = 0; 
                if (ex < 5) fld[ey][ex+3] = 0;
                fld[my][mx] = 1; fld[my][mx+1] = 1; fld[my][mx+2] = 1; 
                fld[ey][ex] = 1; fld[ey][ex+1] = 1; fld[ey][ex+2] = 1;
            }                     
        } 
    cnt = 0;    
    }
    cnt++;
}

void paint(void)
{
char x = 0;
    while (x <= 7) {
        PORTA = 0b00000000;
        PORTB = 0b00000000;
        PORTD = 0b11111111;
        if (src == 0) {
            PORTA.0 = fld[0][x];  PORTA.1 = fld[1][x];
            PORTA.2 = fld[2][x];  PORTA.3 = fld[3][x];
            PORTA.4 = fld[4][x];  PORTA.5 = fld[5][x];
            PORTA.6 = fld[6][x];  PORTA.7 = fld[7][x];
        } else {    
            PORTB.0 = fld[8][x];  PORTB.1 = fld[9][x];
            PORTB.2 = fld[10][x]; PORTB.3 = fld[11][x];
            PORTB.4 = fld[12][x]; PORTB.5 = fld[13][x];
            PORTB.6 = fld[14][x]; PORTB.7 = fld[15][x];
        }    
        switch (x) {
            case 0: {PORTD = 0b11111110; break;} case 1: {PORTD = 0b11111101; break;}
            case 2: {PORTD = 0b11111011; break;} case 3: {PORTD = 0b11110111; break;}
            case 4: {PORTD = 0b11101111; break;} case 5: {PORTD = 0b11011111; break;}
            case 6: {PORTD = 0b10111111; break;} case 7: {PORTD = 0b01111111; break;}
        }    
        delay_us(50);
        x++;
    }
    src++;
    if (src == 2) src = 0; 
}

void initgame(void) {
char x = 0, y = 0;
    #asm("cli")
    while (y < 16) { 
        x = 0;
        while (x < 8) {
            fld[y][x] = 0;
            x++;
        }
        y++;
    } 
    tmp = 1; 
    speed = 50;
    #asm("sei")
}

void inkey(void){
char key = 0;
    if (PINC.1 == 0) {
        delay_ms(1);
        if (PINC.1 == 0) key = 3;
    } 
    if (PINC.0 == 0) {
        delay_ms(1);
        if (PINC.0 == 0) key = 4;
    }   
    switch (key) {
    case 1: {
    
        break;}
    case 2: {

        break;}
    case 3: {

        break;}
    case 4: {
        if (start == 0) {
            start = 1;
            initgame();
        }    
        break;} 
    default: {
    }
    };         
} 

void main(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0xFF;
PORTC=0xFF;
DDRC=0x00;
PORTD=0x00;
DDRD=0xFF;
TCCR0=0x02;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x01;
UCSRB=0x00;
ACSR=0x80;
SFIOR=0x00;
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;
showsrc();
#asm("sei")
while (1)
      {
      paint();
      inkey();         
      }
}
Tags:
Hubs:
+3
Comments 11
Comments Comments 11

Articles