Ping-Pong на AVR

в 12:10, , рубрики: avr, diy или сделай сам, MEGA16, Ping-Pong, метки: , ,

В очередную уборку в мастерской довелось мне наткнуться на два матричных индикатора 8х8, там же была найдена Mega16, кнопки, макетка. «Какой же ты программист, если за свою жизнь ни разу не написал Тетрис?», спросил мозг.
Конец дня был посвящен тому, чтобы навесом спаять это все хозяйство.
Ping Pong на AVR

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

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

/*****************************************************
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();         
      }
}

Автор: ParyshevD

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js