This project implements a Modbus RTU slave for an STM32 microcontroller. It communicates with a Modbus master device over a UART interface and displays data on an SSD1306 OLED display. Key features include:
- Modbus RTU Communication: Initialization, enabling, and handling read/write operations on holding registers.
- OLED Display Control: Manages an SSD1306 OLED display, displaying text and graphics based on holding register values.
- User Interface: Provides a user interface with three keys (Up, Down, Enter) and a buzzer, controllable via holding registers.
- EEPROM Storage: Stores and retrieves configuration data (baud rate, Modbus ID) in EEPROM, modifiable through Modbus holding registers.
- Holding Register Management: Defines holding registers for storing display text, key states, buzzer control, and configuration settings.
- Config Timer
- Config LCD
- Config EEPROM
- Key & Buzzer
- Display Initialization
- Main Loop
- Modbus Register Table
- Python GUI
- Roadmap
- Select the Timer: Timer 3 (TIM3) is used for Modbus timing.
- Configure the Timer Prescaler: Set to 71, resulting in a timer clock frequency of 1 MHz (assuming a system clock of 72 MHz).
- Set the Timer Period: Set to 50, corresponding to an interrupt interval of 50 microseconds (50 μs).
- Set the Timer Counter Mode: Set to
TIM_COUNTERMODE_UP
. - Initialize the Timer: Use
HAL_TIM_Base_Init
to initialize the timer. - Pass the Timer Handle to Modbus: Pass the configured timer handle (
htim3
) toModbusRtuInit
.
- Refer to freemodbus Porting Doc for more details about timing and microtechnics for porting the freemodbus to STM32.
- Configure I2C: Set up I2C in STM32CubeMX for SSD1306 display communication.
- Select Font Size: Choose a font size (e.g.,
Font_11x18
) from the provided font files. - Set Holding Register Addresses: Set addresses and size based on font size and maximum characters.
- Update Holding Registers: Update with the text to be displayed.
- Refresh Display: Call
ssd1306_UpdateScreen
to refresh the OLED display.
Refer to ssd1306-stm32HAL for more details.
To store settings on the microcontroller, we use the EEPROM emulation library written by NimaLTD. The structure for storing information is defined in rtudisplay.h
:
typedef struct {
USHORT Baudrate;
USHORT ModbusID;
} Storage_t;
Refer to EEPROM EMULATION Library for STM32 for more details.
Provides a simple user interface with three keys (Up, Down, Enter) and a buzzer. Key states are stored in holding registers, and the buzzer is controlled via holding registers:
- Key States: Set corresponding holding register to 1 when a key is pressed.
- Buzzer Control: Write specific values to the holding register at
Buzzer_ADDR
to control the buzzer:1
:buzzer_beep
(short beep)2
:BUZZER_ON
(continuous on)3
:BUZZER_OFF
(off)
The Rtudisplay_Init
function initializes various components:
- Initialize Holding Registers: Set
HRBuff
array to zeros. - Initialize EEPROM: Call
EE_Init
withEE_Setting
structure. - Read EEPROM Settings: Call
EE_Read
. - Set Default Values if Invalid:
- Baud rate default: 3 (9600)
- Modbus ID default: 2
- Copy Settings to Holding Registers:
Baud_ADDR
MbID_ADDR
- Set Baud Rate: Based on
EE_Setting.Baudrate
. - Initialize UART: Call
HAL_UART_Init
withhuart2
. - Initialize Modbus: Call
ModbusRtuInit
. - Initialize OLED Display: Call
ssd1306_Init
withhi2c1
.
The main program loop (while(1)
) performs the following:
- Handle Modbus Communication: Call
eMBPoll()
. - Update Display and Save Parameters: If Write on Holding Register function received and
HR_Write_Flag
is set. - Update Buzzer State: Based on holding register.
- Update Key States: Reflect in holding registers. This loop keeps the system responsive to Modbus, user input, and events requiring display or buzzer updates.
Address | Description |
---|---|
40001-----40011 | LCD Line 1 |
40012-----40022 | LCD Line 2 |
40023-----40033 | LCD Line 3 |
40034-----40036 | Reserved |
40037 | Modbus ID |
40038 | Baud Rate |
40039 | Save Settings |
40040 | Up Key |
40041 | Down Key |
40042 | Enter Key |
40043 | Buzzer |
This project offers a GUI for interacting with Modbus Dispaly RTU via Tkinter in Python, allowing users to configure communication, control a buzzer, and monitor keys and LEDs. Access the software here.
- The RS485 Directin Control pin declared at init function (Currently in Library\Modbus\rtu\mbrtu.c line 302,315 ) !!
- Support multi-size font for each line
- Add Changelog