Самый распространённый и наглядный способ вывода информации из микроконтроллера — это ЖК-экран, самый популярный это WH1602 и подобные экраны компании Winstar. Все они построены на одном контроллере HD44780, и отличаются лишь количеством строк и символов в строке, а также типом подсветки.
Подключим этот контроллер к STM32. Я подключаю его так:
1 – GND
2 – 5В
3 – GND
4 – PA0
5 – GND
6 – PA1
11 – PA4
12 – PA5
13 – PA6
14 – PA7
Используем 4-проводной режим, а ещё нам не нужно читать из экрана — поэтому заземляем вывод R/W, будем только писать в него. Таким образом, канал связи с экраном сокращается всего до 6 линий GPIO.
А вот и код:
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stdio.h"
#define LCM_OUT_SET GPIOA->BSRRL
#define LCM_OUT_RST GPIOA->BSRRH
#define LCM_PIN_RS GPIO_Pin_0 /* PB0 */
#define LCM_PIN_EN GPIO_Pin_1 /* PB1 */
#define LCM_PIN_D4 GPIO_Pin_4 /* PB4 */
#define LCM_PIN_D5 GPIO_Pin_5 /* PB5 */
#define LCM_PIN_D6 GPIO_Pin_6 /* PB6 */
#define LCM_PIN_D7 GPIO_Pin_7 /* PB7 */
#define LCM_PIN_MASK (LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4)
GPIO_InitTypeDef GPIO_InitStructure;
void delay(__IO uint32_t nCount)
{
volatile uint32_t del = nCount * 1000;
while(del--);
}
void PulseLCD()
{
LCM_OUT_SET = LCM_PIN_EN; delay(20);
LCM_OUT_RST = LCM_PIN_EN; delay(20);
}
void SendByte(char byte, int IsData)
{
LCM_OUT_RST = LCM_PIN_MASK;
LCM_OUT_SET = byte & 0xF0;
if (IsData) LCM_OUT_SET = LCM_PIN_RS;
else LCM_OUT_RST = LCM_PIN_RS;
PulseLCD();
LCM_OUT_RST = LCM_PIN_MASK;
LCM_OUT_SET = (byte & 0x0F) << 4; if (IsData) LCM_OUT_SET = LCM_PIN_RS; else LCM_OUT_RST = LCM_PIN_RS; PulseLCD(); } void SendCmd(char cmd) { SendByte(cmd, 0); } void SendChar(char chr) { SendByte(chr, 1); } void LCD_setPos(char Row, char Col) { SendCmd(0x80 | ( (Row % 2) ? 0x40 : 0 ) | Col + (Row > 1) * 20);
}
void LCD_clear()
{
SendCmd(0x01);
SendCmd(0x02);
}
void LCD_hide()
{
SendCmd(0x08);
}
void LCD_show()
{
SendCmd(0x0C);
}
void LCD_init(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCM_PIN_MASK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
LCM_OUT_SET = LCM_PIN_MASK;
delay(50);
LCM_OUT_SET = LCM_PIN_D5;
PulseLCD();
SendCmd(0x28);
LCD_hide();
SendCmd(0x06);
}
void LCD_printStr(char *text)
{
while (*text != 0) SendChar(*text++);
}
int main(void)
{
LCD_init();
LCD_clear();
LCD_hide();
LCD_setPos(0, 0);
LCD_printStr("Embedded development");
LCD_setPos(1, 3);
LCD_printStr("catethysis.ru");
LCD_setPos(2, 0);
LCD_printStr("electronics, STM32,");
LCD_setPos(3, 0);
LCD_printStr("blogging & freelance");
LCD_show();
while(1);
}
Результат:
Свежие комментарии