#include "MDR32Fx.h"
#include "MDR32F9Qx_port.h"
#include "MDR32F9Qx_rst_clk.h"
// Константы для логики
#define ZONE_HIT 1
#define ZONE_MISS 0
// Инициализация портов
void Init_Hardware(void) {
// Включаем тактирование портов A (LED), B (KEY 1-8) и C (SELECT)
RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTA | RST_CLK_PCLK_PORTB | RST_CLK_PCLK_PORTC, ENABLE);
PORT_InitTypeDef PortInit;
PORT_StructInit(&PortInit);
// Светодиоды LED1-LED8: PORTA, пины 0-7, на выход
PortInit.PORT_Pin = 0x00FF;
PortInit.PORT_OE = PORT_OE_OUT;
PortInit.PORT_FUNC = PORT_FUNC_PORT;
PortInit.PORT_MODE = PORT_MODE_DIGITAL;
PortInit.PORT_SPEED = PORT_SPEED_SLOW;
PORT_Init(MDR_PORTA, &PortInit);
// Кнопки KEY1-KEY8: PORTB, пины 0-7, на вход
PortInit.PORT_Pin = 0x00FF;
PortInit.PORT_OE = PORT_OE_IN;
PORT_Init(MDR_PORTB, &PortInit);
// Кнопка SELECT: PORTC, пин 0, на вход
PortInit.PORT_Pin = PORT_Pin_0;
PORT_Init(MDR_PORTC, &PortInit);
}
// Функция получения числа из 4-х бит (Знак + 3 бита значения)
int8_t Get_Coordinate(uint8_t raw_bits) {
int8_t value = raw_bits & 0x07; // Младшие 3 бита (0, 1, 2)
if (raw_bits & 0x08) { // 4-й бит (старший) - знак
value = -value;
}
return value;
}
// Математическая проверка области
uint8_t Check_Area(int8_t x, int8_t y) {
// 1. Ограничение квадратом [-3; 3]
if (x < -3 || x > 3 || y < -3 || y > 3) return ZONE_MISS;
// 2. Условие "вне верхней левой окружности" (центр -3, 3, R=3)
// (x + 3)^2 + (y - 3)^2 >= 9
uint16_t dist1 = (x + 3)*(x + 3) + (y - 3)*(y - 3);
// 3. Условие "вне нижней правой окружности" (центр 3, -3, R=3)
// (x - 3)^2 + (y + 3)^2 >= 9
uint16_t dist2 = (x - 3)*(x - 3) + (y + 3)*(y + 3);
if (dist1 >= 9 && dist2 >= 9) {
return ZONE_HIT;
}
return ZONE_MISS;
}
// Простая задержка
void SimpleDelay(uint32_t cycles) {
for (volatile uint32_t i = 0; i < cycles; i++);
}
// Мигание всеми LED
void Blink(uint8_t times) {
for (uint8_t i = 0; i < times; i++) {
MDR_PORTA->RXTX = 0xFF; // Включить
SimpleDelay(1000000);
MDR_PORTA->RXTX = 0x00; // Выключить
SimpleDelay(1000000);
}
}
int main(void) {
Init_Hardware();
while (1) {
// Проверяем нажатие кнопки SELECT (предположим, активный уровень - 0)
if (PORT_ReadInputDataBit(MDR_PORTC, PORT_Pin_0) == 0) {
SimpleDelay(50000); // Антидребезг
// Читаем все кнопки с PORTB
uint16_t keys = PORT_ReadInputData(MDR_PORTB);
// X - KEY1-4 (биты 0-3), Y - KEY5-8 (биты 4-7)
int8_t x = Get_Coordinate(keys & 0x0F);
int8_t y = Get_Coordinate((keys >> 4) & 0x0F);
if (Check_Area(x, y) == ZONE_HIT) {
Blink(1); // Попал - 1 раз
} else {
Blink(2); // Не попал - 2 раза
}
// Ждем отпускания кнопки SELECT
while (PORT_ReadInputDataBit(MDR_PORTC, PORT_Pin_0) == 0);
}
}
}