Převzaté z http://mcu.cz/comment.php?comment.news.2181 a upravené.
#include "stm32f10x.h" // LCD_RW je pripojen na GND = zapis #define LCD_PORT GPIOC #define LCD_RS GPIO_Pin_10 #define LCD_E GPIO_Pin_11 #define LCD_D4 GPIO_Pin_0 #define LCD_D5 GPIO_Pin_1 #define LCD_D6 GPIO_Pin_2 #define LCD_D7 GPIO_Pin_3 /** * LCD (HD44780) ovládané 4-bity. * * Jakub Trmota (trmotjak) */ /** * Inicializace LCD. */ void LcdInitialize() { // Inicalizace PINu GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = LCD_RS | LCD_E | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LCD_PORT, &GPIO_InitStructure); // Inicializace LCD (dle specifikace nastaveni na 4-bitovou komunikaci) GPIO_ResetBits(LCD_PORT, LCD_RS | LCD_E); LcdDelayUs(20000); // wait more than 15 ms LcdSend4Bits(48); // 0011(0000) LcdDelayUs(6000); // wait more than 4.1 ms GPIO_ResetBits(LCD_PORT, LCD_E); LcdSend4Bits(48); // 0011(0000) LcdDelayUs(200); // wait more than 100 us GPIO_ResetBits(LCD_PORT, LCD_E); LcdSend4Bits(48); // 0011(0000) GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(20); // Nyni by mel byt LCD v 8-bitovem modu a definitivne ho prepneme do 4-bitoveho modu LcdSend4Bits(32); // 0010(0000) GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(100); // Prikaz 0 0 1 DL N F * * (DL = bitu komunikace 1 = 8bitu, 0 = 4bity; N = pocet radek 1 = 2 radky, 0 = 1 radka; F = Font 1=5x10bodu, 0=5x8 bodu) LcdSendCommand(40); // 00101000 LcdDelayUs(100); // Display off LcdSendCommand(8); // 00001000 LcdDelayUs(100); // Display clear LcdSendCommand(1); // 00000001 LcdDelayUs(2000); // wait 1,64 ms // Zvedej sam adresu a posunuj kurzor, ktery neukazuj LcdSendCommand(12); // 00001100 LcdDelayUs(100); } /** * Odesla prikaz do LCD. * @param cmd prikaz */ void LcdSendCommand(uint8_t cmd) { LcdSend4Bits(cmd); GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(50); LcdSend4Bits(cmd << 4); GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(50); } /** * Odesle 4-bitovy prikaz do LCD. * @param bits prikaz */ void LcdSend4Bits(uint8_t bits) { uint16_t portData; bits = bits >> 4; portData = GPIO_ReadOutputData(LCD_PORT); portData = portData & 0xFFF0; portData = portData | (uint16_t) bits; GPIO_Write(LCD_PORT, portData); GPIO_SetBits(LCD_PORT, LCD_E); LcdDelayUs(200); } /** * Odesle znak do LCD. * @param cmd znak */ void LcdSendChar(char cmd) { GPIO_SetBits(LCD_PORT, LCD_RS); LcdSend4Bits(cmd); GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(50); LcdSend4Bits(cmd << 4); GPIO_ResetBits(LCD_PORT, LCD_E); LcdDelayUs(50); GPIO_ResetBits(LCD_PORT, LCD_RS); LcdDelayUs(50); } /** * Vymaze LCD. */ void LcdClear(void) { LcdSendCommand(1); // 00000001 LcdDelayUs(2000); // wait 1,64 ms } /** * Nastavi kurzor na pocatecni pozici. */ void LcdCursorHome(void) { LcdSendCommand(2); // 00000010 LcdDelayUs(2000); // wait 1,64 ms } /** * Nastavi kurzor na pozici. * @param col sloupec (1 - 20) * @param row radek (1 nebo 2) */ void LcdSetCursor(int col, int row) { LcdSendCommand(0x80 + ((((row - 1) * 40) + (col - 1)) & 0x7F)); LcdDelayUs(2000); } /** * Napise retezec na LCD. * @param str retezec */ void LcdPrint(char *str) { uint8_t i = 0; if (!str) { return; } while(str[i] != '\0') { LcdSendChar(str[i++]); } } /** * Napise string z flash pameti na LCD. * @param str retezec */ void LcdPrintFlash(const char *str) { uint8_t i = 0; if (!str) { return; } while(str[i] != '\0') { LcdSendChar(str[i++]); } } /** * Funkce cekani v us (priblizne). * @param us us na cekani */ void LcdDelayUs(__IO uint32_t us) { us = us * ((SystemCoreClock / 3) / 1000000); for (; us != 0; us--); }Nahoru