mirror of
https://github.com/sergeyyarkov/pdsp188x.git
synced 2026-10-11 10:28:54 +03:00
avr
This commit is contained in:
commit
762518416b
27
README.md
Normal file
27
README.md
Normal 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
47
config_avr.h
Normal 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
97
pdsp188x.c
Normal 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
57
pdsp188x.h
Normal 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
41
port/avr/avr.c
Normal 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
9
port/avr/avr.h
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user