#include "main.h"
#include "stm32c0xx_hal.h"
I2C_HandleTypeDef hi2c1; // Handle for I2C communication
// Define HX711 pins (Load Cell Amplifier)
#define HX711_DT_PIN GPIO_PIN_0 // Data pin (DT) connected to PA0
#define HX711_DT_GPIO_PORT GPIOA // GPIO port for DT pin
#define HX711_SCK_PIN GPIO_PIN_1 // Clock pin (SCK) connected to PA1
#define HX711_SCK_GPIO_PORT GPIOA // GPIO port for SCK pin
// Define the reed switch pin
#define REED_SWITCH_PIN GPIO_PIN_7
#define REED_SWITCH_GPIO_PORT GPIOA
#define ENGINE_STATUS_PIN GPIO_PIN_10
#define ENGINE_STATUS_PORT GPIOA
// define LCD
#define LCD_PORT GPIOA
#define LCD_RS_Pin GPIO_PIN_1
#define LCD_RW_Pin GPIO_PIN_15
#define LCD_E_Pin GPIO_PIN_4
#define LCD_D4_Pin GPIO_PIN_8
#define LCD_D5_Pin GPIO_PIN_12
#define LCD_D6_Pin GPIO_PIN_2
#define LCD_D7_Pin GPIO_PIN_11
// Function prototypes
void HX711_Init(void); // Initialize HX711 (Load Cell)
int32_t HX711_Read(void); // Read data from HX711
void HX711_Calibrate(void); // Calibrate the load cell
void SystemClock_Config(void); // Configure system clock
static void MX_GPIO_Init(void); // Initialize GPIO pins
static void MX_I2C1_Init(void); // Initialize I2C peripheral
void LCD_Init(void);
void LCD_SendCommand(uint8_t command);
void LCD_SendData(uint8_t data);
void LCD_SendString(char *str);
//void LCD_PulseEnable(void);
void LCD_SetCursor(uint8_t row, uint8_t col);
void Error_Handler(void); // Handle errors
void Engine(void);
volatile int Reed_Switch_flags =0;
volatile int Engine_flag = 0; // Handle errors
volatile int Detection_flag = 0;
volatile int Engine_on = 0;
//volatile int reed_count = 0;
//volatile int reed_flag =1;
//volatile int k = 0;
/*void well(){
int32_t weight = HX711_Read();
if(weight>10){
char weightStr[20];
sprintf(weightStr, "weigth: %ld", weight); // Convert weight to string
LCD_SendString(weightStr); // Display weight on LCD
HAL_Delay(500);
LCD_SendCommand(0x01);
}
}*/
int main(void)
{
HAL_Init(); // Initialize HAL Library
SystemClock_Config(); // Configure system clock
MX_GPIO_Init(); // Initialize GPIO pins
MX_I2C1_Init(); // Initialize I2C peripheral
LCD_Init(); // Initialize the LCD
HX711_Init(); // Calibrate the load cell (tare)
int reed_count = 0;
int reed_flag =1;
while (1)
{
Engine();
int32_t weight = HX711_Read();
if(weight > 10 && Engine_on){
char weightStr[20];
sprintf(weightStr, "weigth: %ld", weight); // Convert weight to string
// LCD_SendString(weightStr); // Display weight on LCD
HAL_Delay(500);
//LCD_SendCommand(0x21);
uint8_t reedSwitchState = HAL_GPIO_ReadPin(REED_SWITCH_GPIO_PORT, REED_SWITCH_PIN);
if(reedSwitchState == 1){
//reed_count++;
LCD_SendString("Seat belt Worn");
HAL_Delay(500);
LCD_SendCommand(0x01);
//continue;
}
/*if(reed_count == 1 ){
LCD_SendString("Seat belt Worn");
HAL_Delay(500);
LCD_SendCommand(0x01);
continue;
// reed_flag =0;
}*/
else if(reed_count==0){
LCD_SendString(" Please wear ");
HAL_Delay(500);
LCD_SetCursor(1, 0);
LCD_SendString(" your seat belt");
HAL_Delay(500);
LCD_SendCommand(0x01);
//reed_count =0;
//reed_flag =1;
}
}
else if(weight <=10 || Engine_on == 0){
LCD_SendCommand(0x01);
//break;
}
// Weight Detection (end)
}
}
// Function to configure the system clock
void SystemClock_Config(void)
{
// Add clock configuration code here
}
// Function to initialize I2C1 peripheral
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1; // Use I2C1 peripheral
hi2c1.Init.Timing = 0x2000090E; // I2C timing configuration
hi2c1.Init.OwnAddress1 = 0; // No own address
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // 7-bit addressing
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // Disable dual address
hi2c1.Init.OwnAddress2 = 0; // No second address
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; // No mask for second address
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // Disable general call
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // Disable clock stretching
if (HAL_I2C_Init(&hi2c1) != HAL_OK) // Initialize I2C
{
Error_Handler(); // Handle initialization error
}
}
// engine function
void Engine(){
uint8_t Engine_State = HAL_GPIO_ReadPin(ENGINE_STATUS_PORT, ENGINE_STATUS_PIN);
//char s[2]={Engine_State+48,'\0'};
//LCD_SendString(s);
// HAL_Delay(2000);
// LCD_SendCommand(0x01);
if(Engine_State == 1 && Engine_flag == 0){ //&& Engine_flag == 0
LCD_SendString(" Engine on");
HAL_Delay(1000);
LCD_SetCursor(1, 0);
LCD_SendString("Welcome user");
HAL_Delay(1000);
LCD_SendCommand(0x01);
Engine_flag =1;
Engine_on = 1;
}
else if(Engine_State == 0){
Engine_flag =0;
// a++;
Engine_on = 0;
// return 0;
}
//LCD_SendCommand(0x01);
}
// Function to initialize GPIO pins
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// Configure the LCD pins as output
GPIO_InitTypeDef gpio_init;
gpio_init.Pin = LCD_RS_Pin | LCD_RW_Pin | LCD_E_Pin;
gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init.Pull = GPIO_NOPULL;
gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_PORT, &gpio_init);
gpio_init.Pin = GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_12|GPIO_PIN_2|GPIO_PIN_11;
HAL_GPIO_Init(LCD_PORT, &gpio_init);
/*__HAL_RCC_GPIOB_CLK_ENABLE(); // Enable GPIOB clock
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_12|GPIO_PIN_2|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// Configure PB6 (SCL) and PB7 (SDA) for I2C1
/*GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; // Select pins
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // Open-drain mode for I2C
GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up/pull-down
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // High speed
GPIO_InitStruct.Alternate = GPIO_AF6_I2C1; // Alternate function for I2C1
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Initialize GPIO pins
// Configure reed switch pin as input
GPIO_InitStruct.Pin = REED_SWITCH_PIN; // Select reed switch pin
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // Set as input
GPIO_InitStruct.Pull = GPIO_PULLDOWN; // Pull-down resistor
HAL_GPIO_Init(REED_SWITCH_GPIO_PORT, &GPIO_InitStruct); // Initialize reed switch pin
//
// Configure ENGINE pin as input
GPIO_InitStruct.Pin = ENGINE_STATUS_PIN; // Select ENGINE switch pin
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // Set as input
GPIO_InitStruct.Pull = GPIO_PULLDOWN; // Pull-down resistor
HAL_GPIO_Init(ENGINE_STATUS_PORT, &GPIO_InitStruct); // Initialize reed switch pin*/
//
}
/*void LCD_Init(void) {
// Wait for the LCD to power up
HAL_Delay(20);
LCD_SendCommand(0x03);
HAL_Delay(5);
LCD_SendCommand(0x03);
HAL_Delay(1);
LCD_SendCommand(0x03);
LCD_SendCommand(0x02);
LCD_SendCommand(0x28); // 4-bit mode, 2-line, 5x8 font
LCD_SendCommand(0x0C); // Display ON, Cursor OFF
LCD_SendCommand(0x06); // Auto Increment Cursor
LCD_SendCommand(0x01); // Clear display
HAL_Delay(2);
}
// Send a command to the LCD
void LCD_SendCommand(uint8_t command) {
HAL_GPIO_WritePin(LCD_PORT, LCD_RS_PIN, GPIO_PIN_RESET); // RS = 0 for command
HAL_GPIO_WritePin(LCD_PORT, LCD_E_PIN, GPIO_PIN_RESET); // E = 0
// Send high nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_PIN, (command & 0x10) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_PIN, (command & 0x20) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_PIN, (command & 0x40) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_PIN, (command & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
LCD_PulseEnable();
// Send low nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_PIN, (command & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_PIN, (command & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_PIN, (command & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_PIN, (command & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET);
LCD_PulseEnable();
}
// Send data to the LCD
void LCD_SendData(uint8_t data) {
HAL_GPIO_WritePin(LCD_PORT, LCD_RS_PIN, GPIO_PIN_SET); // RS = 1 for data
HAL_GPIO_WritePin(LCD_PORT, LCD_E_PIN, GPIO_PIN_RESET); // E = 0
// Send high nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_PIN, (data & 0x10) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_PIN, (data & 0x20) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_PIN, (data & 0x40) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_PIN, (data & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
LCD_PulseEnable();
// Send low nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_PIN, (data & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_PIN, (data & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_PIN, (data & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_PIN, (data & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET);
LCD_PulseEnable();
}
// Pulse the Enable pin to send data/command
void LCD_PulseEnable(void) {
HAL_GPIO_WritePin(LCD_PORT, LCD_E_PIN, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_PIN, GPIO_PIN_RESET);
HAL_Delay(1);
}
// Send a string to the LCD
void LCD_SendString(char *str) {
while (*str) {
LCD_SendData(*str++);
}
}
// Set the cursor position
void LCD_SetCursor(uint8_t row, uint8_t col) {
uint8_t address;
if (row == 0) {
address = 0x80 + col;
} else {
address = 0xC0 + col;
}
LCD_SendCommand(address);
}
// Function to initialize the LCD
/*void LCD_Init(void)
{
HAL_Delay(50); // Wait for LCD to power up
LCD_SendCommand(0x33); // Initialize LCD
HAL_Delay(5);
LCD_SendCommand(0x32); // Initialize LCD
HAL_Delay(5);
LCD_SendCommand(0x28); // 2 lines, 5x7 matrix
HAL_Delay(5);
LCD_SendCommand(0x0C); // Display on, cursor off
HAL_Delay(5);
LCD_SendCommand(0x01); // Clear display
HAL_Delay(5);
LCD_SendCommand(0x06); // Increment cursor
HAL_Delay(5);
}
// Function to send a command to the LCD
void LCD_SendCommand(uint8_t cmd)
{
uint8_t data_u, data_l;
uint8_t data_t[4];
data_u = (cmd & 0xF0); // Upper 4 bits of command
data_l = ((cmd << 4) & 0xF0); // Lower 4 bits of command
data_t[0] = data_u | 0x0C; // Enable high, RS low
data_t[1] = data_u | 0x08; // Enable low, RS low
data_t[2] = data_l | 0x0C; // Enable high, RS low
data_t[3] = data_l | 0x08; // Enable low, RS low
HAL_I2C_Master_Transmit(&hi2c1, 0x4E, data_t, 4, 100); // Send command
}
// Function to send data to the LCD
void LCD_SendData(uint8_t data)
{
uint8_t data_u, data_l;
uint8_t data_t[4];
data_u = (data & 0xF0); // Upper 4 bits of data
data_l = ((data << 4) & 0xF0); // Lower 4 bits of data
data_t[0] = data_u | 0x0D; // Enable high, RS high
data_t[1] = data_u | 0x09; // Enable low, RS high
data_t[2] = data_l | 0x0D; // Enable high, RS high
data_t[3] = data_l | 0x09; // Enable low, RS high
HAL_I2C_Master_Transmit(&hi2c1, 0x4E, data_t, 4, 100); // Send data
}
// Function to send a string to the LCD
void LCD_SendString(char *str)
{
while (*str) // Loop through each character
{
LCD_SendData(*str++); // Send character to LCD
}
}
// Function to display a message on the LCD
void DisplayOnLCD(char *message)
{
LCD_SendCommand(0x01); // Clear the LCD display
HAL_Delay(5); // Wait for clear command to complete
LCD_SendString(message); // Display the message on the LCD
}*/
void LCD_Init(void)
{
// Configure the LCD to 4-bit mode
LCD_SendCommand(0x33); // 4-bit mode
LCD_SendCommand(0x32); // 4-bit mode
LCD_SendCommand(0x28); // 4-bit mode, 2 lines, 5x8 font
LCD_SendCommand(0x0C); // Display on, cursor off, blink off
LCD_SendCommand(0x06); // Increment cursor
LCD_SendCommand(0x01); // Clear display
}
void LCD_SendCommand(uint8_t command)
{
// Send the command to the LCD
HAL_GPIO_WritePin(LCD_PORT, LCD_RS_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_RW_Pin, GPIO_PIN_RESET);
// Send the high nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_Pin, (command & 0x10) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_Pin, (command & 0x20) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_Pin, (command & 0x40) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_Pin, (command & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_RESET);
// Send the low nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_Pin, (command & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_Pin, (command & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_Pin, (command & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_Pin, (command & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_RESET);
}
void LCD_SendData(uint8_t data)
{
// Send the data to the LCD
HAL_GPIO_WritePin(LCD_PORT, LCD_RS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LCD_PORT, LCD_RW_Pin, GPIO_PIN_RESET);
// Send the high nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_Pin, (data & 0x10) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_Pin, (data & 0x20) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_Pin, (data & 0x40) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_Pin, (data & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_RESET);
// Send the low nibble
HAL_GPIO_WritePin(LCD_PORT, LCD_D4_Pin, (data & 0x01) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D5_Pin, (data & 0x02) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D6_Pin, (data & 0x04) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_D7_Pin, (data & 0x08) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(LCD_PORT, LCD_E_Pin, GPIO_PIN_RESET);
}
void LCD_SendString(char *str)
{
while(*str)
{
LCD_SendData(*str);
str++;
}
}
void LCD_SetCursor(uint8_t row, uint8_t col) {
uint8_t address;
if (row == 0) {
address = 0x80 + col;
} else {
address = 0xC0 + col;
}
LCD_SendCommand(address);
}
// Function to initialize HX711 (Load Cell)
void HX711_Init(void)
{
// Configure DT (Data) pin as input
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HX711_DT_PIN; // Select DT pin
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // Set as input
GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up/pull-down
HAL_GPIO_Init(HX711_DT_GPIO_PORT, &GPIO_InitStruct); // Initialize DT pin
// Configure SCK (Clock) pin as output
GPIO_InitStruct.Pin = HX711_SCK_PIN; // Select SCK pin
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Set as output
GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-up/pull-down
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Low speed
HAL_GPIO_Init(HX711_SCK_GPIO_PORT, &GPIO_InitStruct); // Initialize SCK pin
// Initialize SCK pin to low
HAL_GPIO_WritePin(HX711_SCK_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_RESET);
}
// Function to read data from HX711 (Load Cell)
int32_t HX711_Read(void)
{
int32_t data = 0;
uint8_t i;
// Wait for DT to go low (data is ready)
while (HAL_GPIO_ReadPin(HX711_DT_GPIO_PORT, HX711_DT_PIN) == GPIO_PIN_SET);
// Read 24 bits of data
for (i = 0; i < 24; i++)
{
HAL_GPIO_WritePin(HX711_SCK_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_SET); // Clock high
data <<= 1; // Shift data left
HAL_GPIO_WritePin(HX711_SCK_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_RESET); // Clock low
if (HAL_GPIO_ReadPin(HX711_DT_GPIO_PORT, HX711_DT_PIN) == GPIO_PIN_SET) // Read DT pin
{
data++; // Set bit if DT is high
}
}
// Send an additional clock pulse to set the gain
HAL_GPIO_WritePin(HX711_SCK_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(HX711_SCK_GPIO_PORT, HX711_SCK_PIN, GPIO_PIN_RESET);
// Convert the 24-bit signed value to a 32-bit signed value
if (data & 0x800000) // Check if the 24th bit is set (negative value)
{
data |= 0xFF000000; // Sign extension for 32-bit signed value
}
data /= 420;
return data;
}
// Function to handle errors
void Error_Handler(void)
{
// Add error handling code here
}
Loading
st-nucleo-c031c6
st-nucleo-c031c6
REED SWITCH
ENGINE SWITCH
ON
OFF