DE | EN | CN

ESE模块12 LCD

使用mySTM32 light与文本LCD一起Text-LCD Add-On in der 3V Ausführung。小型显示屏通常可以在嵌入式系统中找到。例如,可以区分文本和图形显示器。这个练习演示了如何使用16个字符每行两行的文本显示器Quasistandard。由于其广泛的应用,这种类型的显示器几乎可以被称为准标准。无论如何,与LED的闪烁代码相比,文本输出作为用户界面更具性能和用户友好性。

要开发一个微控制器解决方案,其中一个模拟值在文本显示器上可视化。

解决方案要求:

  • 带有HD44780显示控制器或兼容显示器的文本显示
  • 以4位模式显示,节省引脚
  • 在第一行中用数字方式显示模拟值
  • 在第二行中以条形方式显示模拟值

SRS LCD

如果有一个类图已打开,请在该图的上下文菜单(鼠标右键)中选择菜单项“上”。 如果该项目已关闭,请重新打开SiSy UML项目。

这次的准备工作与以往的程序有些不同。为了减少编写必要源代码的工作量,我们将使用SiSy Online-LibStore中的特殊板载软件包,而不是加载STM32F0的通用驱动软件包。由于显示器的连接需要多个引脚,并且这些引脚在目标系统中的排列可能差异很大,因此库模块是通用的。开发人员通常需要自己实现显示器具体引脚的映射,通过重写相应的引脚操作。如果已知板子及其引脚配置,则可以加载预先配置好的引脚适配器模块。我们将为mySTM32 Board light执行这项操作。

进行以下准备工作:

  • 创建一个新的类图
  • 目标语言ARM C ++
  • 目标平台STM32F042 mySTM32板灯HAL
  • 为PEC的应用模板下载应用程序(XMC,STM32,AVR)
  • 从SiSy LibStore下载STM32板灯的板封装
  • (可选)分配模板stm32F042_48Mhz

注意:对于本练习,请从SiSy LibStore下载驱动程序包“ Bard Package mySTM32 Board light”。

如果仔细研究该任务,可以发现先前的练习中已经满足了一些要求。

  • 从LibStore加载软件包
  • 读取模拟值
  • 将数值格式化为文本

我们可以基于此进行。这个任务类似于通过UART输出值的任务。但这次,我们不是将输出发送到PC,而是发送到显示器。让我们看看PecTextLcd16x2库模块。

通过Operation操作写write(“ …”)的输出文本。通过操作(Operation) setPos(X,Y)输出位置,再通过clear()清除显示。 对于这个任务就足够了。

如果我们将面向对象的原理应用于此任务,则会产生以下系统组件:


可以将这些系统模块放在一起,以构成以下应用程序体系结构:

该设计图可以翻译成以下文本:

  • 控制器Controller有传感器Sensor显示器Display
  • 传感器Sensor是带有8位ADC分辨率adcResolution8bitPecAdcChannel
  • 显示器Display是带背光功能lcd_useBacklightPecTextLcd16x2

在实现过程中必须分配特定的引脚,通道和其他硬件配置。需要仔细查看文本LCD附加组件,查看技术说明technische Beschreibung会很有帮助。

从电路图(请参阅第5页,技术说明myAVR LCD附件)可以看到扩展连接上的前8个引脚(A0至A7)被附件占用,这些不再可用于其他任务。传感器就需连接到另一个引脚。 我们可以从参考卡Referenzkarte 上找到下一个可能的模拟输入。

注意:已知板的特殊驱动程序包= LibStore板包

实现应包括上述设计中描述的元素。 此外我们仍必须分配控制器的专用资源。 对于显示器,我们使用textLcdSTMlight板包中的配置。ADC和引脚PinB0 相互连接。下文详细介绍正确配置文本显示器的步骤。

完成类模型,与下图匹配。 清楚地排列元素。

先做一下测试,在第一行和第二行给出了两个简单的欢迎文本,测试完后再删除。 在Controller类的onStart()操作中写下以下代码:

Controller::onStart():void
// boot sequence after start SysTick
display.setPos(1,1);
display.write("Hallo mySTM32.de");
display.setPos(1,2);
display.write("================");
waitMs(2000);
display.clear();

这段代码是针对显示器的引导序列,代码解释:

1. display.setPos(1,1);: 设置显示器光标位置为第1行第1列。
2. display.write(“Hallo mySTM32.de”);: 在光标位置写入字符串 “Hallo mySTM32.de”,显示在第1行。
3. display.setPos(1,2);: 设置显示器光标位置为第2行第1列。
4. display.write(“================”);: 在光标位置写入一串等号,用于分隔线,显示在第2行。
5. waitMs(2000);: 等待2000毫秒(2秒),让信息停留在屏幕上。
6. display.clear();: 清除显示器上的所有内容。

这段代码的作用是在显示器上显示 “Hallo mySTM32.de” 这个信息,持续显示2秒钟,然后清除屏幕上的内容。我们现在创建,传输和测试一下。 任务的实际解决方案发生在控制器类的onWork()操作中。 对于复杂的解决方案,我们可以使用注释帮助理清思路。

Controller::onWork():void
// continuous event from the Mainloop
   来自mainloop的连续事件
// lese Analogwert ein 读取模拟值
// formatiere die Textausgabe 格式化文本输出 
// Textausgabe Analogwert in der ersten Zeile
   第一行文字输出模拟值
// Balken als Anzeige in der zweiten Zeile 第二行显示条形
// WIEDERHOLE VON 0 BIS 16  从0到16重复
//   WENN WERT<MAX/16 DANN Ausgbae "*"
//   SONST                 Ausgabe " " 
//   给眼睛阅读显示内容的时间

现在可以编写实际的源代码。将以下代码添加到Controller类的onWork()操作中:

Controller::onWork():void
// continuous event from the Mainloop ---------------
 
uint8_t value; // 读模拟值
value=sensor.getValue();
 
String txt; // 格式化文本输出 ------------------------
txt.format("Value=%d  ",value);
// 第一行文字输出模拟值 --------
display.home();
display.write(txt);
// 第二行显示条形图 -----------
display.setPos(1,2);
for (uint8_t i=0; i<16; i++ )
{
	if (i<=value/16) display.write("*");
	else             display.write(" ");
}
 
waitMs(100);// 给眼睛留出阅读显示屏的时间 ---------

这段代码是在主循环中执行的连续事件处理部分。代码解析:

1. uint8_t value; 读模拟值: 声明一个名为 value 的8位无符号整数变量,用于存储从传感器读取的模拟值。
2. value=sensor.getValue();: 调用 sensor 对象的 getValue() 方法,将获取到的模拟值存储在 value 变量中。
3. String txt;
格式化文本输出: 声明一个名为 txt 的字符串对象,用于存储格式化后的文本输出。
4. txt.format(“Value=%d ”,value);: 使用格式化字符串将模拟值格式化为字符串,并存储在 txt 中,格式为 “Value=模拟值 “。
5. display.home(); display.write(txt);: 将光标移动到显示器的起始位置,然后将格式化后的文本 txt 写入显示器的第一行。
6. display.setPos(1,2);: 将显示器的光标位置设置为第二行的第一个字符。
7. for (uint8_t i=0; i < 16; i++ ): 使用循环从0到15遍,共16次,表示显示16个字符的长度。
8. if (i ⇐ value/16) display.write(“*”);: 如果当前循环计数小于等于模拟值除以16的结果,即模拟值的一部分被16整除的次数,就在显示器上打印一个星号(*),表示一个条形图的部分。
9. else display.write(” ”);: 否则,在显示器上打印一个空格,表示条形图的间隔。
10. waitMs(100);: 等待100毫秒,以给眼睛足够的时间读取显示屏上的内容。

现在可以创建,传输和测试应用程序。

翻译程序。将可执行程序传送到控制器的程序存储器中。

  • 1. 创建(编译和链接)
  • 2. 烧录
  • 3. 连接…

变体

更改应用程序,在显示屏上显示10位模拟值(0..1023)。 创建程序,将解决方案转移到微控制器并测试应用程序。

更改Controller类的OnWork()操作的源代码,如下所示:

Controller::onWork():void
// continuous event from the Mainloop ---------------
// 读模拟值
uint16_t value;
value=sensor.getValue();
// 格式化文本输出 ------------------------
String txt;
txt.format("Value=%d  ",value);
// 第一行文字输出模拟值 --------
display.home();
display.write(txt);
// 第二行显示条形图 -----------
display.setPos(1,2);
for (uint16_t i=0; i<16; i++ )
{
	if (i<=value/64) display.write("*");
	else             display.write(" ");
}
// 给眼睛留出阅读显示屏的时间 ---------
waitMs(100);

这段代码是在主循环中执行的连续事件处理部分。

1. uint16_t value;: 声明一个名为 `value` 的16位无符号整数变量,用于存储从传感器读取的模拟值。
2. value=sensor.getValue();: 调用 `sensor` 对象的 `getValue()` 方法,将获取到的模拟值存储在 `value` 变量中。
3. String txt;: 声明一个名为 `txt` 的字符串对象,用于存储格式化后的文本输出。
4. txt.format(“Value=%d ”,value);: 使用格式化字符串将模拟值格式化为字符串,并存储在 `txt` 中,格式为 “Value=模拟值 “。
5. display.home(); display.write(txt);: 将光标移动到显示器的起始位置,然后将格式化后的文本 `txt` 写入显示器的第一行。
6. display.setPos(1,2);: 将显示器的光标位置设置为第二行的第一个字符。
7. for (uint16_t i=0; i < 16; i++ ): 使用循环从0到15遍历,共16次,表示显示16个字符的长度。
8. if (i ⇐ value/64) display.write(“*”);: 如果当前循环计数小于等于模拟值除以64的结果,即模拟值的一部分被64整除的次数,就在显示器上打印一个星号(*),表示一个条形图的部分。
9. else display.write(” ”);: 否则,在显示器上打印一个空格,表示条形图的间隔。
10. waitMs(100);: 等待100毫秒,以给眼睛足够的时间读取显示屏上的内容。

这段代码的作用是在显示器上以文本和条形图的形式显示模拟值,其中条形图的长度与模拟值的一部分除以64得到的值有关,用于实时监测传感器的输出。
创建程序,将解决方案转移到微控制器并测试应用程序。
比较两种解决方案。

视频总结

  • 1. 创建并打开类图
  • 2. 选择PEC应用程序的图模板
  • 3. 从SiSy Online LibStore加载正确的板驱动程序包
  • 4. 在资源管理器中搜索所需的块并将其拖动到图中
  • 5. 聚合类
  • 6. 在操作中创建必要的源代码
  • 7. 在类图中创建并刻录ARM应用程序

oder die schnelle Version ohne Sprachkommentare

练习 10

使用AlarmLED扩展应用程序。对于低于100(闪烁)的传感器值,AlarmLED应该快速闪烁。如果值超过100,则LED指示灯熄灭。

将B4引脚用于AlarmLED。同时在显示屏上输出信息“ OK”或“ ALARM”。

继续:

Suchbegriffe