monorepo
This commit is contained in:
224
P8_SETR1/Core/Src/hd44780.c
Executable file
224
P8_SETR1/Core/Src/hd44780.c
Executable file
@@ -0,0 +1,224 @@
|
||||
|
||||
#include "hd44780.h"
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#define LCD_PORT7 D7_LCD_GPIO_Port
|
||||
#define LCD_PORT4 D4_LCD_GPIO_Port
|
||||
#define LCD_PORT56 D6_LCD_GPIO_Port //pines D5 y D6 en el mismpo puerto, GPIOB
|
||||
|
||||
#define RS_PORT RS_LCD_GPIO_Port
|
||||
#define CLOCK_PORT E_LCD_GPIO_Port
|
||||
|
||||
#define LCD_RS RS_LCD_Pin
|
||||
#define LCD_CLOCK E_LCD_Pin
|
||||
#define LCD_4 D4_LCD_Pin
|
||||
#define LCD_5 D5_LCD_Pin
|
||||
#define LCD_6 D6_LCD_Pin
|
||||
#define LCD_7 D7_LCD_Pin
|
||||
|
||||
|
||||
|
||||
// Various displays exist, don't make assumptions
|
||||
uint8_t lcd_chars = 0;
|
||||
uint8_t lcd_lines = 0;
|
||||
uint8_t *lcd_line_addresses = 0;
|
||||
// "Private" globals
|
||||
uint8_t _lcd_char = 0;
|
||||
uint8_t _lcd_line = 0;
|
||||
|
||||
|
||||
|
||||
void lcd_clock(void)
|
||||
{
|
||||
// Pulse clock
|
||||
HAL_GPIO_WritePin(CLOCK_PORT, LCD_CLOCK, 1);
|
||||
|
||||
osDelay(1);
|
||||
HAL_GPIO_WritePin(CLOCK_PORT, LCD_CLOCK, 0);
|
||||
osDelay(1);
|
||||
}
|
||||
|
||||
void lcd_reset(void)
|
||||
{
|
||||
// Resets display from any state to 4-bit mode, first nibble.
|
||||
|
||||
// Set everything low first
|
||||
HAL_GPIO_WritePin(RS_PORT, LCD_RS, 0);
|
||||
|
||||
HAL_GPIO_WritePin(LCD_PORT7, LCD_7, 0);
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 0);
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 0);
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_6, 0);
|
||||
HAL_GPIO_WritePin(CLOCK_PORT, LCD_CLOCK, 0);
|
||||
|
||||
// Reset strategy below based on Wikipedia description, should recover
|
||||
// from any setting
|
||||
|
||||
// Write 0b0011 three times
|
||||
// (Everyday Practical Electronics says 3 times, Wikipedia says 2 times,
|
||||
// 3 seems to work better).
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 1);
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 1);
|
||||
lcd_clock();
|
||||
lcd_clock();
|
||||
lcd_clock();
|
||||
// LCD now guaranteed to be in 8-bit state
|
||||
// Now write 0b0010 (set to 4-bit mode, ready for first nibble)
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 0);
|
||||
lcd_clock();
|
||||
|
||||
HAL_GPIO_WritePin(Led_LCD_GPIO_Port, Led_LCD_Pin, 1);
|
||||
}
|
||||
|
||||
/* TODO This function should achieve the same as the lcd_write below, however
|
||||
* it appears to be a little problematic.
|
||||
* Rather than the LCD_4 and LCD_RS defines, direct integers have to be used
|
||||
* for proper masks to be calculated.
|
||||
* Aside from this, setting the RS bit seems to go wrong.
|
||||
*/
|
||||
|
||||
void lcd_write(uint8_t byte, uint8_t rs)
|
||||
{
|
||||
// Writes a byte to the display (rs must be either 0 or 1)
|
||||
//rs=0 comando;; rs=1 dato
|
||||
// Write second nibble and set RS
|
||||
|
||||
if((byte >> 4 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 0);
|
||||
|
||||
if((byte >> 5 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 0);
|
||||
|
||||
if((byte >> 6 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_6, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_6, 0);
|
||||
|
||||
if((byte >> 7 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT7, LCD_7, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT7, LCD_7, 0);
|
||||
|
||||
if(rs)
|
||||
HAL_GPIO_WritePin(RS_PORT, LCD_RS, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(RS_PORT, LCD_RS, 0);
|
||||
|
||||
lcd_clock();
|
||||
|
||||
// Write first nibble
|
||||
|
||||
if(byte & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT4, LCD_4, 0);
|
||||
|
||||
if((byte >> 1 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_5, 0);
|
||||
|
||||
if((byte >> 2 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_6, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT56, LCD_6, 0);
|
||||
|
||||
if((byte >> 3 ) & 1)
|
||||
HAL_GPIO_WritePin(LCD_PORT7, LCD_7, 1);
|
||||
else
|
||||
HAL_GPIO_WritePin(LCD_PORT7, LCD_7, 0);
|
||||
|
||||
lcd_clock();
|
||||
}
|
||||
|
||||
void lcd_clear(void)
|
||||
{
|
||||
// Clears display, resets cursor
|
||||
lcd_write(0b00000001, 0);
|
||||
_lcd_char = 0;
|
||||
_lcd_line = 0;
|
||||
}
|
||||
|
||||
void lcd_display_settings(uint8_t on, uint8_t underline, uint8_t blink)
|
||||
{
|
||||
// "Display On/Off & Cursor" command. All parameters must be either 0 or 1
|
||||
|
||||
lcd_write(0b00001000 | (on << 2) | (underline << 1) | blink, 0);
|
||||
}
|
||||
|
||||
void lcd_display_address(uint8_t address)
|
||||
{
|
||||
lcd_write(0b10000000 | address, 0);
|
||||
}
|
||||
|
||||
void lcd_cgram_address(uint8_t address)
|
||||
{
|
||||
lcd_write(0b01000000 | address, 0);
|
||||
}
|
||||
|
||||
void lcd_print(char string[])
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0; string[i] != 0; i++) {
|
||||
// If we know the display properties and a newline character is
|
||||
// present, print the rest of the string on the new line.
|
||||
if(lcd_lines && string[i] == '\n') {
|
||||
if(_lcd_line < lcd_lines) {
|
||||
lcd_display_address(lcd_line_addresses[_lcd_line++]);
|
||||
_lcd_char = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If we know the display properties and have reached the end of
|
||||
// line, print the rest on the next line
|
||||
if(lcd_chars)
|
||||
if((_lcd_char == lcd_chars) && (_lcd_line < lcd_lines)) {
|
||||
lcd_display_address(lcd_line_addresses[_lcd_line++]);
|
||||
_lcd_char = 0;
|
||||
}
|
||||
lcd_write(string[i], 1);
|
||||
if(lcd_chars) _lcd_char++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeIntegerToLCD(int integer)
|
||||
{
|
||||
// Break down the original number into the thousands, hundreds, tens,
|
||||
// and ones places and then immediately write that value to the LCD
|
||||
unsigned char thousands = integer / 1000;
|
||||
lcd_write( thousands + 0x30,1);
|
||||
|
||||
unsigned char hundreds = (integer - thousands*1000) / 100;
|
||||
lcd_write( hundreds + 0x30,1);
|
||||
|
||||
unsigned char tens = (integer - thousands*1000 - hundreds*100 ) / 10;
|
||||
lcd_write( tens + 0x30,1);
|
||||
|
||||
unsigned char ones = (integer - thousands*1000 - hundreds*100 - tens*10);
|
||||
lcd_write( ones + 0x30,1);
|
||||
}
|
||||
|
||||
void moveToXY(unsigned char row, unsigned char column)
|
||||
{
|
||||
// Determine the new position
|
||||
int position = (row * 16) + column;
|
||||
|
||||
// Send the correct commands to the command register of the LCD
|
||||
if(position < 16)
|
||||
lcd_write( 0x80 | position,0);
|
||||
else if(position >= 16 && position < 32)
|
||||
lcd_write( 0x80 | (position % 16 + 0x40),0);
|
||||
else if(position >= 41 && position < 60)
|
||||
lcd_write( 0x80 | (position % 40 + 0x14),0);
|
||||
else if(position >= 20 && position < 40)
|
||||
lcd_write( 0x80 | (position % 60 + 0x54),0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user