c - 为什么这段代码会清除 SparkFun 16x2 SerLCD 上的屏幕
问题描述
我一直在玩SparkFun 的SparkFun 16x2 SerLCD LCD,并通过 Tiva C EK-TM4C123GXL 板控制它。我已经设法通过 SPI 通信连接 LCD,并编写代码在板上显示字符串。但是,我在编写可以为我清除屏幕的代码时遇到了麻烦,直到我在网上遇到以下代码:
#include <stdint.h>
#include <stdlib.h>
#include "inc/tm4c123gh6pm.h"
void spi_master_ini(void){ //Setup SPI
SYSCTL_RCGCSSI_R|=(1<<2);
//SYSCTL_RCGCGPIO_R |=(1<<1);
SYSCTL_RCGC2_R |=(1<<1);
GPIO_PORTB_AFSEL_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PCTL_R=0x22220000;
GPIO_PORTB_DEN_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PUR_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
SSI2_CR1_R=0;
SSI2_CC_R=0;
SSI2_CR1_R=64;
SSI2_CR0_R=0x7;
SSI2_CR1_R|=(1<<1);
}
void send_byte(char data){
SSI2_DR_R=data;
while((SSI2_SR_R&(1<<0))==0);
}
void send_str(char *buffer){
while(*buffer!=0){
send_byte(*buffer);
buffer++;
}
}
int main(){
spi_master_ini();
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
send_str("Testing");
}
特别是令我困惑的两行代码:
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
在阅读了HD44780U数据表后,我无法看到将这些 HEX 值发送到数据线除了打印“|”之外还有什么作用 和“-”到液晶显示器。然而,令我惊讶的是,当我运行代码时它可以工作并清除我的 LCD 屏幕。
解决方案
HD44780U 的数据表无关紧要 - 您不是直接与显示控制器交谈。在 SparkFun 16x2 SerLCD 上,SPI 与 ATmega328P 通信,后者又与显示控制器通信。
这简化了显示器接口,因为您只需要一个 SPI 或 I2C 链路,不需要显示控制器所需的 4/8 位数据总线和额外的控制线。
ATMega328P 上运行的软件独立于显示控制器解释和转换命令。https://github.com/sparkfun/OpenLCD上的源代码适用。
settings.h 有:
#define SPECIAL_SETTING '|' //124, 0x7C, the pipe character: The command to do special settings: baud, lines, width, backlight, splash, etc
然后在 OpenLCD.inovoid updateDisplay()
中有:
//Check to see if the incoming byte is special
if (incoming == SPECIAL_SETTING) //SPECIAL_SETTING is 127
{
currentMode = MODE_SETTING;
}
...
注意注释是错误的,它是 124 而不是 127(也许说明了这段代码的质量)。
然后后来:
else if (currentMode == MODE_SETTING)
{
currentMode = MODE_NORMAL; //In general, return to normal mode
...
//Clear screen and buffer
else if (incoming == 45) //- character
{
SerLCD.clear();
SerLCD.setCursor(0, 0);
clearFrameBuffer(); //Get rid of all characters in our buffer
}
...
然后clearFrameBuffer()
简单地用空格填充缓冲区,而不是使用 HD44780“清除显示”指令:
//Flushes all characters from the frame buffer
void clearFrameBuffer()
{
//Clear the frame buffer
characterCount = 0;
for (byte x = 0 ; x < (settingLCDwidth * settingLCDlines) ; x++)
currentFrame[x] = ' ';
}
大部分文档是针对 Arduino 的,但https://learn.sparkfun.com/tutorials/avr-based-serial-enabled-lcds-hookup-guide/firmware-overview上的命令表无论如何都是有效的。它是字符而不是整数代码,因此具有:
还有更多您可能会发现有用的命令。
推荐阅读
- hadoop - --fields-terminated-by 和--input-fields-terminated-by 有什么区别
- python - 如何将使用第三方包和 JSON 文件的 Python 脚本转换为独立的可执行文件?
- docker - 端口不可用:listen tcp 0.0.0.0/50070:bind:试图以访问权限禁止的方式访问套接字
- windows - gnuplot:如何获取包含非 ANSI 字符的文件列表?
- java - Android 文本到语音播放没有错误,但不产生任何声音
- haskell - Haskell IO:读取整个文本文件
- karate - appium 按键功能在空手道中不起作用 android 自动化
- arrays - python3:将整数值(2byte)转换为字节数组中的两个单独字节
- python - Django项目的依赖
- postgresql - Hasura 实时更新表格的功能