Hugely refactor the display
This commit is contained in:
parent
5ad6fb8412
commit
65caaa0a50
|
@ -0,0 +1,155 @@
|
|||
#include <stdlib.h>
|
||||
#include <display.h>
|
||||
#include <util/delay.h>
|
||||
#include <base.h>
|
||||
|
||||
/*
|
||||
struct CHAR {
|
||||
char c;
|
||||
uint8_t bits;
|
||||
};
|
||||
|
||||
struct CHAR CHARSET[96] = {
|
||||
{ .c = ' ', .bits = 0x20 },
|
||||
{ .c = '!', .bits = 0x21 },
|
||||
{ .c = '"', .bits = 0x22 },
|
||||
{ .c = '#', .bits = 0x23 },
|
||||
{ .c = '$', .bits = 0x24 },
|
||||
{ .c = '%', .bits = 0x25 },
|
||||
{ .c = '&', .bits = 0x26 },
|
||||
{ .c = ''', .bits = 0x27 },
|
||||
{ .c = '(', .bits = 0x28 },
|
||||
{ .c = ')', .bits = 0x29 },
|
||||
{ .c = '*', .bits = 0x2a },
|
||||
{ .c = '+', .bits = 0x2b },
|
||||
{ .c = ',', .bits = 0x2c },
|
||||
{ .c = '-', .bits = 0x2d },
|
||||
{ .c = '.', .bits = 0x2e },
|
||||
{ .c = '/', .bits = 0x2f },
|
||||
{ .c = '0', .bits = 0x30 },
|
||||
{ .c = '1', .bits = 0x31 },
|
||||
{ .c = '2', .bits = 0x32 },
|
||||
{ .c = '3', .bits = 0x33 },
|
||||
{ .c = '4', .bits = 0x34 },
|
||||
{ .c = '5', .bits = 0x35 },
|
||||
{ .c = '6', .bits = 0x36 },
|
||||
{ .c = '7', .bits = 0x37 },
|
||||
{ .c = '8', .bits = 0x38 },
|
||||
{ .c = '9', .bits = 0x39 },
|
||||
{ .c = ':', .bits = 0x3a },
|
||||
{ .c = ';', .bits = 0x3b },
|
||||
{ .c = '<', .bits = 0x3c },
|
||||
{ .c = '=', .bits = 0x3d },
|
||||
{ .c = '>', .bits = 0x3e },
|
||||
{ .c = '?', .bits = 0x3f },
|
||||
{ .c = '@', .bits = 0x40 },
|
||||
{ .c = 'A', .bits = 0x41 },
|
||||
{ .c = 'B', .bits = 0x42 },
|
||||
{ .c = 'C', .bits = 0x43 },
|
||||
{ .c = 'D', .bits = 0x44 },
|
||||
{ .c = 'E', .bits = 0x45 },
|
||||
{ .c = 'F', .bits = 0x46 },
|
||||
{ .c = 'G', .bits = 0x47 },
|
||||
{ .c = 'H', .bits = 0x48 },
|
||||
{ .c = 'I', .bits = 0x49 },
|
||||
{ .c = 'J', .bits = 0x4a },
|
||||
{ .c = 'K', .bits = 0x4b },
|
||||
{ .c = 'L', .bits = 0x4c },
|
||||
{ .c = 'M', .bits = 0x4d },
|
||||
{ .c = 'N', .bits = 0x4e },
|
||||
{ .c = 'O', .bits = 0x4f },
|
||||
{ .c = 'P', .bits = 0x50 },
|
||||
{ .c = 'Q', .bits = 0x51 },
|
||||
{ .c = 'R', .bits = 0x52 },
|
||||
{ .c = 'S', .bits = 0x53 },
|
||||
{ .c = 'T', .bits = 0x54 },
|
||||
{ .c = 'U', .bits = 0x55 },
|
||||
{ .c = 'V', .bits = 0x56 },
|
||||
{ .c = 'W', .bits = 0x57 },
|
||||
{ .c = 'X', .bits = 0x58 },
|
||||
{ .c = 'Y', .bits = 0x59 },
|
||||
{ .c = 'Z', .bits = 0x5a },
|
||||
{ .c = '[', .bits = 0x5b },
|
||||
{ .c = ' ', .bits = 0x5c },
|
||||
{ .c = ']', .bits = 0x5d },
|
||||
{ .c = '^', .bits = 0x5e },
|
||||
{ .c = '_', .bits = 0x5f },
|
||||
{ .c = '`', .bits = 0x60 },
|
||||
{ .c = 'a', .bits = 0x61 },
|
||||
{ .c = 'b', .bits = 0x62 },
|
||||
{ .c = 'c', .bits = 0x63 },
|
||||
{ .c = 'd', .bits = 0x64 },
|
||||
{ .c = 'e', .bits = 0x65 },
|
||||
{ .c = 'f', .bits = 0x66 },
|
||||
{ .c = 'g', .bits = 0x67 },
|
||||
{ .c = 'h', .bits = 0x68 },
|
||||
{ .c = 'i', .bits = 0x69 },
|
||||
{ .c = 'j', .bits = 0x6a },
|
||||
{ .c = 'k', .bits = 0x6b },
|
||||
{ .c = 'l', .bits = 0x6c },
|
||||
{ .c = 'm', .bits = 0x6d },
|
||||
{ .c = 'n', .bits = 0x6e },
|
||||
{ .c = 'o', .bits = 0x6f },
|
||||
{ .c = 'p', .bits = 0 },
|
||||
{ .c = 'q', .bits = 0 },
|
||||
{ .c = 'r', .bits = 0 },
|
||||
{ .c = 's', .bits = 0 },
|
||||
{ .c = 't', .bits = 0 },
|
||||
{ .c = 'u', .bits = 0 },
|
||||
{ .c = 'v', .bits = 0 },
|
||||
{ .c = 'w', .bits = 0 },
|
||||
{ .c = 'x', .bits = 0 },
|
||||
{ .c = 'y', .bits = 0 },
|
||||
{ .c = 'z', .bits = 0 },
|
||||
{ .c = ' ', .bits = 0 },
|
||||
{ .c = ' ', .bits = 0 },
|
||||
{ .c = ' ', .bits = 0 },
|
||||
{ .c = ' ', .bits = 0 },
|
||||
{ .c = ' ', .bits = 0 },
|
||||
};
|
||||
*/
|
||||
|
||||
void display_strobe_line(gpio_t *line) {
|
||||
set_line(line);
|
||||
_delay_us(100);
|
||||
clear_line(line);
|
||||
_delay_us(100);
|
||||
}
|
||||
|
||||
void write_instruction(display_t *disp, uint8_t bitcode) {
|
||||
clear_line(&disp->register_select);
|
||||
sr_send_msb(&disp->reg, bitcode);
|
||||
_delay_ms(1);
|
||||
display_strobe_line(&disp->enable);
|
||||
}
|
||||
|
||||
void write_char(display_t *disp, uint8_t bitcode) {
|
||||
set_line(&disp->register_select);
|
||||
sr_send_msb(&disp->reg, bitcode);
|
||||
_delay_ms(1);
|
||||
display_strobe_line(&disp->enable);
|
||||
}
|
||||
|
||||
void display_init(display_t *disp) {
|
||||
sr_initialize(&disp->reg);
|
||||
set_line_direction(&disp->register_select, LINE_OUT);
|
||||
set_line_direction(&disp->enable, LINE_OUT);
|
||||
write_instruction(disp, 0b00111100);
|
||||
}
|
||||
|
||||
void display_clear(display_t *disp) {
|
||||
write_instruction(disp, 0x01);
|
||||
write_instruction(disp, 0x02);
|
||||
}
|
||||
|
||||
void display_enable(display_t *disp) {
|
||||
write_instruction(disp, 0x0e);
|
||||
}
|
||||
|
||||
void display_write_message(display_t *disp, const char *msg) {
|
||||
for (size_t i = 0; msg[i] != 0; i++) {
|
||||
write_char(disp, msg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/* This library covers a five-wire diagnostic display board.
|
||||
*
|
||||
* Hardware:
|
||||
* 74HC595 shift register
|
||||
* Adafruit HD44780 LCD
|
||||
*
|
||||
* Input pins:
|
||||
* SDI -- Serial data in. This leads to the 74HC595, pin 14 (A).
|
||||
* CLK -- Clock pulse. One bit will be shifted into the device on each rising
|
||||
* edge. This leads to the 74HC595, pin 11 (Shift Clock).
|
||||
* LS -- Latch pulse. All data in the shift register will be sent to the
|
||||
* output on a rising edge. This leads to the 74HC595, pin 12 (Latch Clock);
|
||||
* RS -- Register select. 0 to write an instruction to the display, 1 to write
|
||||
* data to the display.
|
||||
* E -- Enable. This tells the display to read the data. The display will get
|
||||
* the data on the shift register outputs, so be sure to send LS before
|
||||
* sending E.
|
||||
*
|
||||
* 74HC595 -> HD44780
|
||||
* Qa -> D0
|
||||
* Qb -> D1
|
||||
* Qc -> D2
|
||||
* Qd -> D3
|
||||
* Qe -> D4
|
||||
* Qf -> D5
|
||||
* Qg -> D6
|
||||
* Qh -> D7
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_H__
|
||||
#define __DISPLAY_H__
|
||||
|
||||
#include <shift_register.h>
|
||||
|
||||
typedef struct DISPLAY {
|
||||
shift_register_t reg;
|
||||
gpio_t register_select;
|
||||
gpio_t enable;
|
||||
} display_t;
|
||||
|
||||
void display_init(display_t *);
|
||||
|
||||
void display_clear(display_t *);
|
||||
|
||||
void display_enable(display_t *);
|
||||
|
||||
void display_write_message(display_t *, const char *);
|
||||
|
||||
#endif
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
name = "lcd";
|
||||
src = ./.;
|
||||
|
||||
includes = [ "base" "shift_register" "spi" ];
|
||||
includes = [ "base" "display" "shift_register" "spi" ];
|
||||
|
||||
MCU = "atmega32u4";
|
||||
CHIP_SELECT = "AVR_ATmega32u4";
|
||||
|
@ -117,9 +117,10 @@
|
|||
buildPhase = ''
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o base.o -c ${src}/base/base.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o spi.o -c ${src}/spi/spi.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o reg.o -c ${src}/shift_register/reg.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o reg.o -c ${src}/shift_register/shift_register.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o display.o -c ${src}/display/display.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} ${INCLUDE_DIRS} -o main.o -c ${src}/lcd/main.c
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o reg.o spi.o base.o
|
||||
${avr.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf main.o display.o reg.o spi.o base.o
|
||||
$OBJCOPY -O ihex main.elf main.hex
|
||||
'';
|
||||
installPhase = ''
|
||||
|
|
80
lcd/main.c
80
lcd/main.c
|
@ -2,76 +2,11 @@
|
|||
#include <util/delay.h>
|
||||
#include <base.h>
|
||||
#include <spi.h>
|
||||
#include <reg.h>
|
||||
|
||||
typedef struct HD44780 {
|
||||
shift_register_t reg;
|
||||
gpio_t register_select;
|
||||
gpio_t enable;
|
||||
} hd44780_t;
|
||||
|
||||
void strobe_line(gpio_t *line) {
|
||||
set_line(line);
|
||||
_delay_ms(1);
|
||||
clear_line(line);
|
||||
_delay_ms(1);
|
||||
}
|
||||
|
||||
void hd44780_init(hd44780_t *disp) {
|
||||
spi_initialize(disp);
|
||||
set_line_direction(&disp->register_select, LINE_OUT);
|
||||
set_line_direction(&disp->enable, LINE_OUT);
|
||||
send_msb(&disp->reg, 0b00111100);
|
||||
}
|
||||
|
||||
void hd44780_clear(hd44780_t *disp) {
|
||||
clear_line(&disp->register_select);
|
||||
send_msb(&disp->reg, 0b00000001);
|
||||
_delay_ms(1);
|
||||
strobe_line(&disp->enable);
|
||||
|
||||
send_msb(&disp->reg, 0b00000010);
|
||||
_delay_ms(1);
|
||||
strobe_line(&disp->enable);
|
||||
}
|
||||
|
||||
void hd44780_display(hd44780_t *disp) {
|
||||
clear_line(&disp->register_select);
|
||||
send_msb(&disp->reg, 0b00001110);
|
||||
_delay_ms(1);
|
||||
strobe_line(&disp->enable);
|
||||
}
|
||||
|
||||
void hd44780_write_char(hd44780_t *disp, uint8_t bitcode) {
|
||||
set_line(&disp->register_select);
|
||||
send_msb(&disp->reg, bitcode);
|
||||
strobe_line(&disp->enable);
|
||||
}
|
||||
|
||||
void hd44780_write(hd44780_t *disp) {
|
||||
set_line(&disp->register_select);
|
||||
|
||||
hd44780_write_char(disp, 0b01001000);
|
||||
hd44780_write_char(disp, 0b01000101);
|
||||
hd44780_write_char(disp, 0b01001100);
|
||||
hd44780_write_char(disp, 0b01001100);
|
||||
hd44780_write_char(disp, 0b01001111);
|
||||
hd44780_write_char(disp, 0b00101100);
|
||||
|
||||
hd44780_write_char(disp, 0b00100000);
|
||||
|
||||
hd44780_write_char(disp, 0b01001101);
|
||||
hd44780_write_char(disp, 0b01011001);
|
||||
|
||||
hd44780_write_char(disp, 0b00100000);
|
||||
|
||||
hd44780_write_char(disp, 0b01000010);
|
||||
hd44780_write_char(disp, 0b01000001);
|
||||
hd44780_write_char(disp, 0b01010100);
|
||||
}
|
||||
#include <shift_register.h>
|
||||
#include <display.h>
|
||||
|
||||
int main(void) {
|
||||
hd44780_t display = {
|
||||
display_t display = {
|
||||
.reg = {
|
||||
.output = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 5 },
|
||||
.latch_clock = { .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 6 },
|
||||
|
@ -85,13 +20,14 @@ int main(void) {
|
|||
set_line_direction(&light, LINE_OUT);
|
||||
clear_line(&light);
|
||||
|
||||
hd44780_init(&display);
|
||||
display_init(&display);
|
||||
|
||||
hd44780_clear(&display);
|
||||
display_clear(&display);
|
||||
_delay_ms(500);
|
||||
|
||||
hd44780_write(&display);
|
||||
hd44780_display(&display);
|
||||
const char msg[] = "Hello, my bat";
|
||||
display_write_message(&display, msg);
|
||||
display_enable(&display);
|
||||
|
||||
set_line(&light);
|
||||
|
||||
|
|
Loading…
Reference in New Issue