Микропроцессорные средства и системы / mps5
.docxМинистерство образования и науки Кыргызской Республики
Кыргызский Государственный Технический Университет им. Разакова
Факультет Информационных Технологий
Кафедра «Информатика и Вычислительная техника»
Отчет
Микроконтроллеры и микропроцессоры.
Лабораторная работа № 5
Бишкек 2019
Реализовать Игру “Ping Pong” используя Atmega328 и цветной TFT дисплей
Листинг кода:
/*
* GccApplication1.c
*
* Created: 01.11.2019 21:39:49
* Author : ntzta
*/
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define DATA_DDR DDRD
#define DATA_PORT PORTD
#define DATA_PIN PIND
#define COMMAND_DDR DDRB
#define COMMAND_PORT PORTB
#define LCD_CS 2//Chip Select
#define LCD_CD 1//Command/Data
#define LCD_WR 3//LCD Write
#define LCD_RD 4//LCD Read
#define LCD_RESET 0//LCD Reset
#define RESET_IDLE COMMAND_PORT|=(1<<LCD_RESET)
#define CS_IDLE COMMAND_PORT|=(1<<LCD_CS)
#define WR_IDLE COMMAND_PORT|=(1<<LCD_WR)
#define RD_IDLE COMMAND_PORT|=(1<<LCD_RD)
#define RESET_ACTIVE COMMAND_PORT&=~(1<<LCD_RESET)
#define CS_ACTIVE COMMAND_PORT&=~(1<<LCD_CS)
#define WR_ACTIVE COMMAND_PORT&=~(1<<LCD_WR)
#define RD_ACTIVE COMMAND_PORT&=~(1<<LCD_RD)
#define CD_COMMAND COMMAND_PORT&=~(1<<LCD_CD)
#define CD_DATA COMMAND_PORT|=(1<<LCD_CD)
#define WR_STROBE {WR_ACTIVE;WR_IDLE;}
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0x0F800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define PIN_LEFT PC0
#define PIN_RIGHT PC1
#define COLUMN_ADDR 0x2A
#define PAGE_ADDR 0x2B
#define GRAM 0x2C
#define FRAME_X1 0
#define FRAME_X2 240
#define FRAME_X3 10
#define FRAME_X4 230
#define FRAME_Y1 0
#define FRAME_Y2 10
#define FRAME_Y3 320
#define FRAME_Y4 310
#define BALL_SIZE 10
#define CLEAR_SIZE 10
#define BALL_Y 270
#define PLAYER_X 50
#define PLAYER_Y1 280
#define PLAYER_Y2 290
#define BALL_UPR 111
#define BALL_UPL 110
#define BALL_DOWNR 101
#define BALL_DOWNL 100
#define X_SIZE 240
#define Y_SIZE 320
unsigned int x_ball = X_SIZE/2;
unsigned int y_ball = BALL_Y;
unsigned int ball_direction = BALL_UPR;
unsigned int x1_position = (X_SIZE/2)-(PLAYER_X/2);
unsigned int x2_position = (X_SIZE/2)+(PLAYER_X/2);
ISR(PCINT1_vect){
if (!(PINC & 0b00000001)) {
move_left();
}
if (!(PINC & 0b00000010)) {
move_right();
}
}
void port_ini(void)
{
DATA_PORT=0x00;
DATA_DDR=0xFF;//Шина данных на выход
COMMAND_DDR=0x1F;//Командные лапки также все на выход
}
void tft_SetCursorPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
tft_SendCommand(COLUMN_ADDR);
tft_SendData(x1 >> 8);
tft_SendData(x1 & 0xFF);
tft_SendData(x2 >> 8);
tft_SendData(x2 & 0xFF);
tft_SendCommand(PAGE_ADDR);
tft_SendData(y1 >> 8);
tft_SendData(y1 & 0xFF);
tft_SendData(y2 >> 8);
tft_SendData(y2 & 0xFF);
}
void tft_DrawPixel(uint16_t x, uint16_t y, uint16_t color) {
tft_SetCursorPosition(x, y, x+10, y+10);
tft_SendCommand(GRAM);
tft_SendData(color >> 8);
tft_SendData(color & 0xFF);
}
void tft_SendCommand(unsigned char cmd)
{
CD_COMMAND;//в состоянии посылки команды
RD_IDLE;//отключим чтение
CS_ACTIVE;//выбор дисплея
DATA_PORT=cmd;
WR_STROBE;
CS_IDLE;
}
void tft_SendData(unsigned char dt)
{
CD_DATA;//в состоянии посылки данных
RD_IDLE;//отключим чтение
CS_ACTIVE;//выбор дисплея
DATA_PORT=dt;
WR_STROBE;
CS_IDLE;
}
void tft_reset(void)
{
CS_IDLE;
WR_IDLE;
RD_IDLE;
RESET_ACTIVE;
RESET_IDLE;
CS_ACTIVE;
tft_SendCommand(0x01); //Reset
for (uint8_t i=0;i<3;i++) WR_STROBE;
CS_IDLE;
}
void tft_SetRotation(){
tft_SendCommand(0x36);
tft_SendData(0x48);
}
void tft_FillRectangle(uint16_t color,uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
for (int i=x1;i<x2;i++)
for (int j=y1;j<y2;j++){
tft_DrawPixel(i,j,color);
}
}
void tft_ini(void)
{
port_ini();
tft_reset();
CS_ACTIVE;
tft_SendCommand(0x01);//Software Reset
tft_SendCommand(0xCB);//Power Control A
tft_SendData(0x39);
tft_SendData(0x2C);
tft_SendData(0x00);
tft_SendData(0x34);
tft_SendData(0x02);
tft_SendCommand(0xCF);//Power Control B
tft_SendData(0x00);
tft_SendData(0xC1);
tft_SendData(0x30);
tft_SendCommand(0xE8);//Driver timing control A
tft_SendData(0x85);
tft_SendData(0x00);
tft_SendData(0x78);
tft_SendCommand(0xEA);//Driver timing control B
tft_SendData(0x00);
tft_SendData(0x00);
tft_SendCommand(0xED);//Power on Sequence control
tft_SendData(0x64);
tft_SendData(0x03);
tft_SendData(0x12);
tft_SendData(0x81);
tft_SendCommand(0xF7);//Pump ratio control
tft_SendData(0x20);
tft_SendCommand(0xC0);//Power Control 1
tft_SendData(0x10);
tft_SendCommand(0xC1);//Power Control 2
tft_SendData(0x10);
tft_SendCommand(0xC5);//VCOM Control 1
tft_SendData(0x3E);
tft_SendData(0x28);
tft_SendCommand(0xC7);//VCOM Control 2
tft_SendData(0x86);
tft_SetRotation();
tft_SendCommand(0x3A);//Pixel Format Set
tft_SendData(0x55);//16bit
tft_SendCommand(0xB1);
tft_SendData(0x00);
tft_SendData(0x18);// Частота кадров 79 Гц
tft_SendCommand(0xB6);//Display Function Control
tft_SendData(0x08);
tft_SendData(0x82);
tft_SendData(0x27);//320 строк
tft_SendCommand(0xF2);//Enable 3G (пока не знаю что это за режим)
tft_SendData(0x00);//не включаем
tft_SendCommand(0x26);//Gamma set
tft_SendData(0x01);//Gamma Curve (G2.2) (Кривая цветовой гаммы)
tft_SendCommand(0xE0);//Positive Gamma Correction
tft_SendData(0x0F);
tft_SendData(0x31);
tft_SendData(0x2B);
tft_SendData(0x0C);
tft_SendData(0x0E);
tft_SendData(0x08);
tft_SendData(0x4E);
tft_SendData(0xF1);
tft_SendData(0x37);
tft_SendData(0x07);
tft_SendData(0x10);
tft_SendData(0x03);
tft_SendData(0x0E);
tft_SendData(0x09);
tft_SendData(0x00);
tft_SendCommand(0xE1);//Negative Gamma Correction
tft_SendData(0x00);
tft_SendData(0x0E);
tft_SendData(0x14);
tft_SendData(0x03);
tft_SendData(0x11);
tft_SendData(0x07);
tft_SendData(0x31);
tft_SendData(0xC1);
tft_SendData(0x48);
tft_SendData(0x08);
tft_SendData(0x0F);
tft_SendData(0x0C);
tft_SendData(0x31);
tft_SendData(0x36);
tft_SendData(0x0F);
tft_SendData(0x0F);
tft_SendCommand(0x11);//Выйдем из спящего режим
_delay_ms(15);
tft_SendCommand(0x29);//Включение дисплея
tft_SendData(0x2C);
_delay_ms(15);
}
void clear_ball(uint16_t x, uint16_t y){
tft_FillRectangle(WHITE,x,y,x+BALL_SIZE,y+BALL_SIZE);
}
void draw_ball(uint16_t x, uint16_t y){
tft_FillRectangle(BLUE,x,y,x+BALL_SIZE,y+BALL_SIZE);
}
void draw_player(){
tft_FillRectangle(RED,(X_SIZE/2)-(PLAYER_X/2),PLAYER_Y1,(X_SIZE/2)+(PLAYER_X/2),PLAYER_Y2);
}
void update_player(uint16_t x){
tft_FillRectangle(RED,x,PLAYER_Y1,x+CLEAR_SIZE,PLAYER_Y2);
}
void clear_player(uint16_t x){
tft_FillRectangle(WHITE,x,PLAYER_Y1,x+CLEAR_SIZE,PLAYER_Y2);
}
void remove_player(){
tft_FillRectangle(WHITE,x1_position,PLAYER_Y1,x2_position+CLEAR_SIZE,PLAYER_Y2);
}
void move_left(){
if (x1_position >= 10)
{
x1_position -= 10;
update_player(x1_position);
x2_position -= 10;
clear_player(x2_position);
}
}
void move_right(){
if (x2_position + 10 <= X_SIZE)
{
update_player(x2_position);
x2_position += 10;
clear_player(x1_position);
x1_position += 10;
}
}
void tft_write8(unsigned char dt){
DATA_PORT = dt;
WR_STROBE;
}
void ball_movement(){
if (ball_direction == BALL_UPR | ball_direction == BALL_UPL)
{
while(y_ball!=FRAME_Y2){
clear_ball(x_ball,y_ball);
if (ball_direction==BALL_UPR)x_ball+=10;
else x_ball-=10;
y_ball -= 10;
draw_ball(x_ball,y_ball);
_delay_ms(3);
if(ball_direction==BALL_UPR) { if (x_ball == FRAME_X4-10)ball_direction = BALL_UPL;}
else {if (x_ball == FRAME_X3)ball_direction = BALL_UPR;}
if (y_ball == FRAME_Y2)
{
ball_direction = (ball_direction==BALL_UPR) ? BALL_DOWNR : BALL_DOWNL;
}
}
}
if (ball_direction == BALL_DOWNR | ball_direction == BALL_DOWNL)
{
while(y_ball!=PLAYER_Y2){
clear_ball(x_ball,y_ball);
if (ball_direction==BALL_DOWNR)x_ball+=10;
else x_ball-=10;
y_ball += 10;
draw_ball(x_ball,y_ball);
_delay_ms(3);
if(ball_direction==BALL_DOWNR) { if (x_ball == FRAME_X4-10)ball_direction = BALL_DOWNL;}
else {if (x_ball == FRAME_X3)ball_direction = BALL_DOWNR;}
if (y_ball == PLAYER_Y1-10)
{
if (x_ball<x2_position & x_ball>x1_position)
{
ball_direction = (ball_direction==BALL_DOWNR) ? BALL_UPR : BALL_UPL;
break;
}
else{
clear_ball(x_ball,y_ball);
remove_player();
init_game();
x_ball = X_SIZE/2;
y_ball = BALL_Y;
ball_direction = BALL_UPR;
x1_position = (X_SIZE/2)-(PLAYER_X/2);
x2_position = (X_SIZE/2)+(PLAYER_X/2);
break;
}
}
}
}
}
void init_game(){
draw_player();
draw_ball(X_SIZE/2,BALL_Y);
}
int main(void)
{
DDRC = 0x00;
PORTC = 0b00000011;
tft_ini();
init_game();
PCICR = (1 << PCIE1); // interrupt from C
PCMSK1 = 0b00000011;
sei();
while (1)
{
ball_movement();
}
}
Схема подключения