#include "stm32f1xx_hal.h"
// Array to store the GPIO banks and pins for each LED in the sequential order
const GPIO_TypeDef* gpioBanks[] = {
GPIOB, GPIOB, GPIOB, GPIOB, GPIOA, GPIOA, GPIOA, GPIOA,
GPIOA, GPIOA, GPIOA, GPIOA, GPIOA, GPIOA, GPIOB, GPIOB,
GPIOB, GPIOB, GPIOB, GPIOB, GPIOB
};
const uint16_t ledPins[] = {
GPIO_PIN_11, GPIO_PIN_10, GPIO_PIN_1, GPIO_PIN_0, GPIO_PIN_7, GPIO_PIN_6, GPIO_PIN_5, GPIO_PIN_4,
GPIO_PIN_3, GPIO_PIN_2, GPIO_PIN_1, GPIO_PIN_0, GPIO_PIN_11, GPIO_PIN_12, GPIO_PIN_13, GPIO_PIN_14,
GPIO_PIN_15, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7, GPIO_PIN_3,
};
// Define a constant for the ground pin
#define GROUND_PIN GPIO_PIN_3
// Define the input pin for signal detection
#define INPUT_PIN_B3 GPIO_PIN_15
// Function to initialize GPIO pins
static void MX_GPIO_Init(void)
{
// Enable GPIOA and GPIOB clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
// Configure all the LED pins as output
for (int i = 0; i < sizeof(ledPins) / sizeof(ledPins[0]); i++)
{
GPIO_InitStruct.Pin = ledPins[i];
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Output push-pull mode
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // Higher GPIO speed
HAL_GPIO_Init((GPIO_TypeDef*)gpioBanks[i], &GPIO_InitStruct);
}
// Configure the ground pin as input with a pull-up resistor
GPIO_InitStruct.Pin = GROUND_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// Configure B3 as input with a pull-up resistor
GPIO_InitStruct.Pin = INPUT_PIN_B3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// Function to perform the sequential lighting effect
void sequentialEffect(int repeatCount)
{
int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
for (int repeat = 0; repeat < repeatCount; repeat++)
{
// Forward sequence
for (int i = 0; i < ledCount - 2; i++)
{
// Turn on the three LEDs together
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 1], ledPins[i + 1], GPIO_PIN_RESET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 2], ledPins[i + 2], GPIO_PIN_RESET);
HAL_Delay(20); // LEDs will be OFF for 20 milliseconds
// Turn off the three LEDs together
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 1], ledPins[i + 1], GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 2], ledPins[i + 2], GPIO_PIN_SET);
}
// Backward sequence
for (int i = ledCount - 3; i >= 0; i--)
{
// Turn on the three LEDs together
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 1], ledPins[i + 1], GPIO_PIN_RESET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 2], ledPins[i + 2], GPIO_PIN_RESET);
HAL_Delay(20); // LEDs will be OFF for 20 milliseconds
// Turn off the three LEDs together
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 1], ledPins[i + 1], GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i + 2], ledPins[i + 2], GPIO_PIN_SET);
}
HAL_Delay(5); // Wait for 5 milliseconds before repeating the effect
}
}
// Function to perform the Tetris effect
void tetrisEffect(int repeatCount)
{
int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
for (int repeat = 0; repeat < repeatCount; repeat++)
{
int startIndex = 0;
int endIndex = ledCount - 1;
int direction = 1; // Direction of the stack movement (1 = left, -1 = right)
while (1)
{
// Turn on both the start and end LEDs together
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[startIndex], ledPins[startIndex], GPIO_PIN_RESET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[endIndex], ledPins[endIndex], GPIO_PIN_RESET);
HAL_Delay(15); // LEDs will be ON for 10 milliseconds
startIndex += direction;
endIndex -= direction;
// Check if the stack has reached the middle
if (startIndex == endIndex || startIndex - 1 == endIndex)
{
HAL_Delay(0); // Delay when the stack reaches the middle
direction = -direction; // Change the direction to move back
// Move the start index back to include the middle LED in the turn-off process
startIndex += direction;
}
// Check if the stack has reached the ends
if (startIndex < 0 || endIndex >= ledCount)
{
break; // Exit the loop when the stack reaches the ends
}
}
// Turn off the remaining LEDs from both sides
for (int i = 0; i < ledCount; i++)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[ledCount - 1 - i], ledPins[ledCount - 1 - i], GPIO_PIN_SET);
HAL_Delay(15); // LEDs will be OFF for 20 milliseconds
}
HAL_Delay(0); // Wait for 100 milliseconds before repeating the effect
}
}
// Function to perform the Line Move effect
void lineMoveEffect(int repeatCount)
{
int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
// Repeat the effect for the specified number of times
for (int repeat = 0; repeat < repeatCount; repeat++)
{
// Move the lines back to their original positions
for (int startIndexLeft = ledCount - 3, startIndexRight = 0; startIndexLeft >= 0; startIndexLeft--, startIndexRight++)
{
// Turn on the LEDs in the lines
for (int i = 0; i < ledCount; i++)
{
if (i >= startIndexLeft && i < startIndexLeft + 3) // Choose the number of LEDs in the line (3 in this case)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET); // Set the pin high
}
else if (i >= startIndexRight && i < startIndexRight + 3)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET); // Set the pin high
}
else
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET); // Set the pin low
}
}
HAL_Delay(20); // LEDs in the lines will be ON for 20 milliseconds
// Turn off the LEDs in the lines
for (int i = 0; i < ledCount; i++)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET); // Set the pin low
}
}
HAL_Delay(5); // Wait for 100 milliseconds before repeating the effect
}
}
// Function to perform the Rotation effect
void rotationEffect(int repeatCount)
{
int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
for (int repeat = 0; repeat < repeatCount; repeat++)
{
for (int i = 0; i < ledCount; i++)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET);
HAL_Delay(20); // LED will be ON for 20 milliseconds
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET);
}
HAL_Delay(10); // Wait for 100 milliseconds before repeating the effect
}
}
// Function to perform the Alternating Effect
void alternatingEffect(int repeatCount)
{
int ledCount = sizeof(ledPins) / sizeof(ledPins[0]);
for (int repeat = 0; repeat < repeatCount; repeat++)
{
for (int i = 0; i < ledCount; i++)
{
if (i % 2 == 0)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET); // Turn on the LED
}
else
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET); // Turn off the LED
}
}
HAL_Delay(50);
for (int i = 0; i < ledCount; i++)
{
if (i % 2 == 0)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET); // Turn off the LED
}
else
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET); // Turn on the LED
}
}
HAL_Delay(50);
}
}
// Function to perform a sequential blinking effect
void sequentialBlink(int repeatCount)
{
for (int repeat = 0; repeat < repeatCount; repeat++)
{
// Light up the LEDs from the bottom to the top
for (int i = 0; i < sizeof(ledPins) / sizeof(ledPins[0]); i++)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_SET);
HAL_Delay(0); // LED will be ON for 50 milliseconds
}
// Turn off the LEDs from the top to the bottom
for (int i = sizeof(ledPins) / sizeof(ledPins[0]) - 1; i >= 0; i--)
{
HAL_GPIO_WritePin((GPIO_TypeDef*)gpioBanks[i], ledPins[i], GPIO_PIN_RESET);
HAL_Delay(20); // LED will be OFF for 50 milliseconds
}
HAL_Delay(10); // Wait for 100 milliseconds before repeating the effect
}
}
// Function to read the state of PA15 multiple times and filter noise
int readPA15WithNoiseFilter(void)
{
int numReadings = 5; // Number of readings to take
int noiseThreshold = 3; // Threshold for noise (adjust as needed)
int readings = 0;
// Read PA15 multiple times and count the number of HIGH readings
for (int i = 0; i < numReadings; i++)
{
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) == GPIO_PIN_SET)
{
readings++;
}
}
// If most readings are HIGH, consider it HIGH, else LOW
if (readings >= (numReadings - noiseThreshold))
{
return GPIO_PIN_RESET;
}
else
{
return GPIO_PIN_SET;
}
}
// Function to read the state of pin B3 multiple times and filter noise
int readB3WithNoiseFilter(void)
{
int numReadings = 5; // Number of readings to take
int noiseThreshold = 3; // Threshold for noise (adjust as needed)
int readings = 0;
// Read pin B3 multiple times and count the number of HIGH readings
for (int i = 0; i < numReadings; i++)
{
if (HAL_GPIO_ReadPin(GPIOA, INPUT_PIN_B3) == GPIO_PIN_SET)
{
readings++;
}
}
// If most readings are LOW, consider it LOW, else HIGH
if (readings >= (numReadings - noiseThreshold))
{
return GPIO_PIN_RESET;
}
else
{
return GPIO_PIN_SET;
}
}
// Function to detect and perform an action when the ground pin is grounded
void detectGround(void)
{
// Use the filtered reading of PA15
if (readPA15WithNoiseFilter() == GPIO_PIN_SET)
{
// Ground pin is connected to ground, perform your action here
// For example, you can call the sequentialEffect function:
lineMoveEffect(5);
alternatingEffect(10);
sequentialEffect(3);
tetrisEffect(3);
sequentialBlink(0);
// Call the sequentialBlink function when B3 is high
if (HAL_GPIO_ReadPin(GPIOA, INPUT_PIN_B3) == GPIO_PIN_SET)
{
sequentialBlink(1); // Adjust the delay as needed
}
}
}
int main(void)
{
// Initialize HAL library and system
HAL_Init();
// Initialize GPIO pins, including B3
MX_GPIO_Init();
int repeatCount = 1; // Set the number of times you want to repeat each effect
while (1)
{
// Check the state of pin B3 with noise filtering
if (readB3WithNoiseFilter() == GPIO_PIN_RESET)
{
// Pin B3 is grounded or LOW, call the sequentialBlink function
sequentialBlink(1); // Adjust the delay as needed
}
else
{
// Pin B3 is high, continue with other effects
// Call the Line Move effect multiple times
for (int i = 0; i < repeatCount; i++)
{
detectGround(); // Check if the ground pin is grounded and perform the action
}
// ... (other effects and their respective function calls)
// Call the Tetris effect multiple times
for (int i = 0; i < repeatCount; i++)
{
detectGround(); // Check if the ground pin is grounded and perform the action
}
}
}
}
Loading
stm32-bluepill
stm32-bluepill