This commit is contained in:
Sergey Yarkov 2026-08-14 19:26:32 +03:00
commit 762518416b
6 changed files with 278 additions and 0 deletions

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# PDSP188x Dot Matrix Display Interfacing Library
This library provides an interfacing API for displaying characters and numbers.
## Example Usage
1. Clone the repository and configure the port numbers inside the `config_{arch}.h` file.
2. Pass the interface implementation into the initialization function:
```c
#include "main.h"
#include "pdsp188x/port/avr/avr.h"
int main(void) {
uint16_t counter = 0;
PDSP188x_Init(&PDSP188x_AVR_Driver);
PDSP188x_SetBrightness(PDSP188x_BRIGHTNESS_LEVEL_100);
while (1) {
PDSP188x_Clear();
PDSP188x_SendStr("C=");
PDSP188x_SendInt16(counter++);
_delay_ms(500);
}
}
```

47
config_avr.h Normal file
View File

@ -0,0 +1,47 @@
#if !defined(PDSP188x_CONFIG_AVR_H_)
# define PDSP188x_CONFIG_AVR_H_
# include <avr/io.h>
# include <util/delay.h>
# define DATA_PORT PORTB
# define DATA_DIR DDRB
/**
* Control using 595 shift register
*/
# define LATCH _BV(PB4)
# define DATA _BV(PB5)
# define CLK _BV(PB7)
/**
* Writes data into display when WR=0. Note CE=0 to enable write cycle.
*/
# define WR _BV(PB0)
/**
* Accesses Flash RAM. Address inputs A0–A2 select digit address
* while data bit D0 sets (D0=1) or resets (D0=0) Flash bit, A3 and A4 ignored
*/
# define FL _BV(PB1)
/**
* Initializes display; clears Character RAM (20H), Flash RAM (00H), control word (00H), and resets
* internal counters. UDC Address Register and UDC RAM unaffected.
*/
# define RST _BV(PB6)
# define ADDR_PORT PORTC
# define ADDR_DIR DDRC
/**
* A0–A2 select specific digits
* A3 and A4 access parts of memory together with Flash pin
*/
# define A0 _BV(PC3)
# define A1 _BV(PC4)
# define A2 _BV(PC5)
# define A3 _BV(PC6)
# define A4 _BV(PC7)
#endif

97
pdsp188x.c Normal file
View File

@ -0,0 +1,97 @@
#include "pdsp188x.h"
static const PDSP188x_DriverInterface_t *driver = {NULL};
static void SetDataLine(uint8_t pin_mask) { driver->set_pins(PDSP188x_DATA_LINE_MASK, pin_mask, 1); }
static void ClearDataLine(uint8_t pin_mask) { driver->set_pins(PDSP188x_DATA_LINE_MASK, pin_mask, 0); }
static void SetAddrLine(uint8_t pin_mask) { driver->set_pins(PDSP188x_ADDR_LINE_MASK, pin_mask, 1); }
static void ClearAddrLine(uint8_t pin_mask) { driver->set_pins(PDSP188x_ADDR_LINE_MASK, pin_mask, 0); }
#define MemSelectCharRAM() SetAddrLine(A3 | A4)
#define MemSelectControlWord() SetAddrLine(A4)
#define MemSelectNone() ClearAddrLine(A3 | A4)
#define SetAddrNone() ClearAddrLine(A0 | A1 | A2 | A3 | A4)
#define FlashCycle() \
do { \
ClearDataLine(WR); \
_delay_us(1); \
SetDataLine(WR); \
_delay_us(1); \
} while (0)
uint8_t pos = 0;
void PDSP188x_Init(const PDSP188x_DriverInterface_t *driver_strategy) {
if (driver_strategy != NULL) {
driver = driver_strategy;
if (driver->init != NULL) {
driver->init();
}
}
}
void PDSP188x_SetBrightness(uint8_t level) {
if (driver == NULL || driver->send_byte == NULL) return;
MemSelectNone();
SetAddrLine(A4);
driver->send_byte(level);
FlashCycle();
_delay_us(5);
}
void PDSP188x_SendChar(char c, uint8_t digit) {
if (driver == NULL || driver->send_byte == NULL) return;
driver->send_byte(c);
_delay_us(1);
MemSelectCharRAM();
/* digit set */
if (digit & 0x01) SetAddrLine(A0);
if (digit & 0x02) SetAddrLine(A1);
if (digit & 0x04) SetAddrLine(A2);
_delay_us(1);
FlashCycle();
SetAddrNone();
_delay_us(1);
}
void PDSP188x_Clear(void) {
for (uint8_t i = 0; i <= 7; i++) {
PDSP188x_SendChar(0x20, i);
}
pos = 0;
}
void PDSP188x_SendStr(char *str) {
char c;
while ((c = *str) != '\0') {
if (pos > 7) {
pos = 0;
return;
}
PDSP188x_SendChar(*str++, pos++);
}
}
void PDSP188x_BlinkEn(uint8_t control) {
uint8_t control_command = control ? 0x10 : 0;
SetAddrNone();
MemSelectControlWord();
SetDataLine(FL);
driver->send_byte(control_command);
FlashCycle();
}
void PDSP188x_SendInt16(int16_t n) {
char str[12] = {'\0'};
itoa(n, str, 10);
PDSP188x_SendStr(str);
}

57
pdsp188x.h Normal file
View File

@ -0,0 +1,57 @@
#if !defined(_PDSP188x_H_)
# define _PDSP188x_H_
# include <avr/io.h>
# include <stdlib.h>
# include <util/delay.h>
# ifdef __AVR__
# include "config_avr.h"
# else
# define WR (1 << 0)
# define FL (1 << 1)
# define LATCH (1 << 2)
# define RST (1 << 3)
# define DATA (1 << 4)
# define CLK (1 << 5)
# define A0 (1 << 0)
# define A1 (1 << 1)
# define A2 (1 << 2)
# define A3 (1 << 3)
# define A4 (1 << 4)
# endif
# define PDSP188x_DATA_LINE_MASK 0x01
# define PDSP188x_ADDR_LINE_MASK 0x02
typedef struct {
void (*init)(void);
void (*reset)(void);
void (*send_byte)(uint8_t byte);
void (*write_char)(char c, uint8_t pos);
void (*set_pins)(uint8_t set_mask, uint8_t pin, uint8_t state);
} PDSP188x_DriverInterface_t;
# define PDSP188x_BRIGHTNESS_LEVEL_100 0x00
# define PDSP188x_BRIGHTNESS_LEVEL_80 0x01
# define PDSP188x_BRIGHTNESS_LEVEL_53 0x02
# define PDSP188x_BRIGHTNESS_LEVEL_40 0x03
# define PDSP188x_BRIGHTNESS_LEVEL_27 0x04
# define PDSP188x_BRIGHTNESS_LEVEL_20 0x05
# define PDSP188x_BRIGHTNESS_LEVEL_13 0x06
# define PDSP188x_BRIGHTNESS_LEVEL_0 0x07
void PDSP188x_Init(const PDSP188x_DriverInterface_t *driver);
void PDSP188x_SendChar(char c, uint8_t digit);
void PDSP188x_SendStr(char *str);
void PDSP188x_SendInt16(int16_t n);
void PDSP188x_SetBrightness(uint8_t level);
void PDSP188x_BlinkEn(uint8_t control);
void PDSP188x_Clear(void);
#endif

41
port/avr/avr.c Normal file
View File

@ -0,0 +1,41 @@
#include "avr.h"
#include "../../config_avr.h"
static void SetPins(uint8_t mask, uint8_t pin_mask, uint8_t state) {
if (state && mask == PDSP188x_DATA_LINE_MASK) DATA_PORT |= pin_mask;
if (state && mask == PDSP188x_ADDR_LINE_MASK) ADDR_PORT |= pin_mask;
if (!state && mask == PDSP188x_DATA_LINE_MASK) DATA_PORT &= ~pin_mask;
if (!state && mask == PDSP188x_ADDR_LINE_MASK) ADDR_PORT &= ~pin_mask;
}
static void Init(void) {
DATA_DIR |= WR | FL | CLK | DATA | LATCH | RST;
ADDR_DIR |= A0 | A1 | A2 | A3 | A4;
DATA_PORT |= FL | RST;
SPCR |= _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
_delay_ms(10);
/* reset */
DATA_PORT |= _BV(WR) | _BV(FL);
DATA_PORT &= ~_BV(RST);
_delay_us(1);
DATA_PORT |= _BV(RST);
_delay_ms(1);
DATA_PORT |= WR;
}
static void SendByte(uint8_t byte) {
SPDR = byte;
loop_until_bit_is_set(SPSR, SPIF);
_delay_us(5);
DATA_PORT |= LATCH;
_delay_us(5);
DATA_PORT &= ~LATCH;
_delay_us(5);
}
const PDSP188x_DriverInterface_t PDSP188x_AVR_Driver = {.init = Init, .send_byte = SendByte, .set_pins = SetPins};

9
port/avr/avr.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef PDSP188x_AVR_H_
#define PDSP188x_AVR_H_
#include "../../pdsp188x.h"
#include "util/delay.h"
extern const PDSP188x_DriverInterface_t PDSP188x_AVR_Driver;
#endif