1

我最近买了一个 STM8 MCU,它有内置功能LCD_GLASS_DisplayString("STRING")

正如您在下面看到的那样,该函数的问题是我无法直接在其上显示整数:

void LCD_GLASS_DisplayString(uint8_t* ptr)
{
  uint8_t i = 0x01;

    LCD_GLASS_Clear();
  /* Send the string character by character on lCD */
  while ((*ptr != 0) & (i < 8))
  {
    /* Display one character on LCD */
    LCD_GLASS_WriteChar(ptr, FALSE, FALSE, i);

    /* Point on the next character */
    ptr++;

    /* Increment the character counter */
    i++;
  }
}

我怎样才能修改它以便我可以直接发送整数?另外,我不确定我可以使用任何库,所以纯 C 会有所帮助。

我在想这样的事情,但没有奏效:

void LCD_GLASS_DisplayINT(uint16_t integer)
{
  uint8_t i = 0x01;

    LCD_GLASS_Clear();
  /* Send the string character by character on lCD */
  while ((integer != 0) & (i < 8))
  {
    /* Display one number on LCD */
    LCD_GLASS_WriteChar("0" + integer%10, FALSE, FALSE, i);

    /* Point on the next number*/
    integer=integer/10;

    /* Increment the character counter */
    i++;
  }
}

关于如何使它工作的任何想法?在将整数发送到 LCD 之前,我需要创建一个函数来显示整数或将它们转换为字符串。代码是纯 C,因为我现在正在编程的是纯驱动程序。

4

2 回答 2

2

离你不远了"0" + integer%10——但是你需要把它当作一个角色——'0' + integer%10你需要传递LCD_GLASS_WriteChar一个指向这个角色的指针。

一种方法是:

char* digits = "0123456789";
LCD_GLASS_WriteChar(&digits[integer % 10], FALSE, FALSE, i);

此外,您的循环条件 -while ((integer != 0) & (i < 8))不应使用按位与 ( &),而应使用逻辑与 ( &&)。

while ((integer != 0) && (i < 8))
于 2021-08-20T11:17:15.677 回答
0

您需要将数字存储在缓冲区中以获得从左到右的顺序。在微控制器上,您可能希望分配该缓冲区以.bss使其不占用堆栈。使用static来实现这一点。对于 16 位数字,您最多有 5 位数字 + 空项,因此:

static char buf[5+1] = {0};

转换本质上是您编写的代码,除了您混淆了'0'"0"

for(uint8_t i=0; i<5; i++)
{
  buf[5-i-1] = val%10 + '0';
  val/=10;
}

请注意,此代码始终保持 itembuf[5]不变,并在那里留下零空终止符。

用标准 C 语言测试的完整代码。显然放弃puts您的自定义 LCD 例程。

#include <stdio.h>
#include <stdint.h>

void display_int (uint16_t val)
{
  static char buf[5+1] = {0};
  char* p;
  
  for(uint8_t i=0; i<5; i++)
  {
    buf[5-i-1] = val%10 + '0';
    val/=10;
  }
  
  // trim leading zeroes
  for(p=buf; *p!='\0'; p++)
  {
    if(*p!='0' ||    // stop looking at first non zero or 
       p[1]=='\0')   // in case there is only one zero character
      break;
  }
  
  puts(p); // use whatever string printing routine you got
}

int main (void)
{
  display_int(0);
  display_int(5);
  display_int(666);
  display_int(12345);
}

STM8 上的除法非常昂贵。如果不需要,我们可以通过不填满整个缓冲区来稍微优化代码。这为我们节省了几个DIV电话。优化版,速度更快但更难阅读:

void display_int (uint16_t val)
{
  static char buf[5+1] = {0};
  char* p;
  char* start;
  
  for(uint8_t i=0;;i++)
  {
    buf[5-i-1] = val%10 + '0';
    val/=10;
    if(val==0)
    {
      start = &buf[5-i-1];
      break;
    }
  }
  
  // trim leading zeroes
  for(p=start; *p!='\0'; p++)
  {
    if(*p!='0' ||    // stop looking at first non zero or 
       p[1]=='\0')   // in case there is only one zero character
      break;
  }
  puts(p); // use whatever string printing routine you got
}
于 2021-08-20T13:47:05.873 回答