#include "Arduino.h"
extern "C" {
#include "stm32c0xx_hal.h"
}
/* ================= LCD LOW LEVEL ================= */
void LCD_PulseE()
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
delay(1);
}
void LCD_Write4(uint8_t nibble)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, (nibble & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET); // D4
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, (nibble & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET); // D5
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, (nibble & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET); // D6
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, (nibble & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET); // D7
LCD_PulseE();
}
void LCD_Send(uint8_t val, bool rs)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, rs ? GPIO_PIN_SET : GPIO_PIN_RESET); // RS
LCD_Write4(val >> 4); // high nibble
LCD_Write4(val & 0x0F); // low nibble
}
void LCD_Command(uint8_t cmd)
{
LCD_Send(cmd, false);
delay(2);
}
void LCD_Data(char data)
{
LCD_Send(data, true);
}
/* ================= LCD HIGH LEVEL ================= */
void LCD_Init()
{
delay(40);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // RS=0
LCD_Write4(0x03);
delay(5);
LCD_Write4(0x03);
delay(5);
LCD_Write4(0x03);
delay(5);
LCD_Write4(0x02); // 4-bit mode
LCD_Command(0x28); // 4-bit, 2 line
LCD_Command(0x0C); // display ON
LCD_Command(0x01); // clear
delay(2);
LCD_Command(0x06); // entry mode
}
void LCD_Print(const char *s)
{
while (*s) LCD_Data(*s++);
}
/* ================= KEYPAD ================= */
char Keypad_Scan()
{
const char keymap[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
GPIO_TypeDef* rPort[4] = {GPIOA, GPIOA, GPIOB, GPIOA};
uint16_t rPin[4] = {GPIO_PIN_12, GPIO_PIN_11, GPIO_PIN_1, GPIO_PIN_4};
GPIO_TypeDef* cPort[4] = {GPIOA, GPIOA, GPIOC, GPIOC};
uint16_t cPin[4] = {GPIO_PIN_1, GPIO_PIN_0, GPIO_PIN_14, GPIO_PIN_13};
for (int r = 0; r < 4; r++)
{
for (int i = 0; i < 4; i++)
HAL_GPIO_WritePin(rPort[i], rPin[i], GPIO_PIN_SET);
HAL_GPIO_WritePin(rPort[r], rPin[r], GPIO_PIN_RESET);
delay(1);
for (int c = 0; c < 4; c++)
if (HAL_GPIO_ReadPin(cPort[c], cPin[c]) == GPIO_PIN_RESET)
return keymap[r][c];
}
return 0;
}
/* ================= SETUP / LOOP ================= */
void setup()
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef g = {0};
g.Mode = GPIO_MODE_OUTPUT_PP;
g.Pull = GPIO_NOPULL;
g.Speed = GPIO_SPEED_FREQ_LOW;
g.Pin = GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_12 | GPIO_PIN_11 | GPIO_PIN_4;
HAL_GPIO_Init(GPIOA, &g);
g.Pin = GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_10 | GPIO_PIN_3 | GPIO_PIN_1;
HAL_GPIO_Init(GPIOB, &g);
g.Mode = GPIO_MODE_INPUT;
g.Pull = GPIO_PULLUP;
g.Pin = GPIO_PIN_1 | GPIO_PIN_0;
HAL_GPIO_Init(GPIOA, &g);
g.Pin = GPIO_PIN_13 | GPIO_PIN_14;
HAL_GPIO_Init(GPIOC, &g);
LCD_Init();
LCD_Command(0x80);
LCD_Print("Key Pressed:");
}
void loop()
{
char k = Keypad_Scan();
if (k)
{
LCD_Command(0xC0);
LCD_Data(k);
delay(300);
}
}