3

我正在尝试使用 STM32F103C8T6 控制 HD44780 16X2 LCD(4 位通信)。我这样连接液晶显示器:

RS => PA0

EN => PA2

RW 接地

D7 => PB7

D6 => PB6

D5 => PB5

D4 => PB4

LCD 什么都不显示。问题可能出在哪里?有人知道这个问题吗?

这是我的代码:

#include "delay.h"
#include "stm32f10x.h" // Device header

void lcd_command(unsigned char command);
void lcd_init(void);
void lcdPosition(unsigned int row, unsigned int column);
void lcd_data(unsigned char data);

int main() {
  delay_init();
  RCC->APB2ENR |= 1 << 2; // Port A Enabled.
  RCC->APB2ENR |= 1 << 3; // Port B Enabled.

  GPIOA->CRL = 0x22222222; // A0 and A2 Output.
  GPIOB->CRL = 0x22222222; // B7,B6,B5,B4 Output.
  GPIOB->ODR = 0x00;       // Port B clear.

  delay_ms(20);
  lcd_command(0x30); // Datasheet says.
  delay_ms(5);
  lcd_command(0x30); // Datasheet says.
  delay_ms(1);
  lcd_command(0x30); // Datasheet says.
  delay_ms(1);
  lcd_init();
  lcdPosition(1, 1); // first row first column
  delay_ms(1);
  lcd_data('A'); // Letter A
  while (1)
    ;
}

void lcd_command(unsigned char command) {

  GPIOA->BRR |= 1 << 0; // RS reset.

  GPIOA->BSRR |= 1 << 2;   // E set.
  GPIOB->ODR = command;    // upper nibble
  delay_ms(2);             // delay
  GPIOA->BRR |= 1 << 2;    // E reset.
  GPIOB->BRR = 0x000000F0; // clear data bits
  delay_ms(2);             // delay

  command = command << 4; // lower nibble

  GPIOA->BSRR |= 1 << 2;   // E set.
  GPIOB->ODR = command;    // lower nibble
  delay_ms(2);             // delay
  GPIOA->BRR |= 1 << 2;    // E reset.
  GPIOB->BRR = 0x000000FF; // clear data bits
}
void lcd_init() {
  lcd_command(0x02); // Return
  delay_ms(2);       // delay
  lcd_command(0x28);
  set 4 - bit data, 2 - line, 5x7 font delay_ms(2); // delay
  lcd_command(0x0C);
  turn on display, cursor off.delay_ms(2); // delay
  lcd_command(0x01);                       // Clear.
  delay_ms(2);                             // delay
  lcd_command(0x06);
  move cursor right delay_ms(4); // delay
}
void lcdPosition(unsigned int row, unsigned int column) {
  if (row == 1) {
    column--;
    lcd_command(0x80 + column); // Define row

  } else if (row == 2) {
    column--;
    lcd_command(0xC0 + column); // Define column
  }
}

void lcd_data(unsigned char data) {
  GPIOA->BSRR |= 1 << 0; // RS reset.
  GPIOA->BSRR |= 1 << 2; // E set.
  GPIOB->ODR = data;
  upper nibble first delay_ms(4); // delay
  GPIOA->BRR |= 1 << 2;           // E reset.
  GPIOB->BRR = 0x000000F0;        // clear data bits
  delay_ms(4);                    // delay

  data = data << 4; // lower nibble

  GPIOA->BSRR |= 1 << 2;   // E set.
  GPIOB->ODR = data;       // lower nibble
  delay_ms(4);             // delay
  GPIOA->BRR |= 1 << 2;    // E reset.
  GPIOB->BRR = 0x000000FF; // clear data bits
}
4

2 回答 2

1

此外 PA0 和 PA2 不是 5V 容限引脚,通常 HD44780 是 5V 设备,如果它在 +5V 上运行,请参阅表 5 中的数据表。“中密度 STM32F103xx 引脚定义”,如果该引脚在 I/O 列中是 5V 容限级别应该用FT来表示!

于 2019-11-26T09:51:53.883 回答
0

请仔细阅读第 46 页数据表中的如何初始化 4 位接口,图 24。

简而言之:您lcd_command一个接一个地发送两个半字节,但前几个命令只需要发送一个半字节(因为显示控制器仍处于 8 位模式)。你需要有一个单独的函数来只发送一个半字节。

于 2019-10-01T11:04:00.947 回答