如何将数字的最后一位转换为字符并在LCD上显示?
How to Convert the last digit of a number to a char and display it on LCD?
我最近买了一个STM8单片机,它有内置功能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 语言,因为我现在正在编写的是纯驱动程序。
你离 "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))
您需要将数字存储在缓冲区中以获得从左到右的顺序。在微控制器上,您可能希望在 .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;
}
请注意,此代码始终保持项目 buf[5]
不变,并在那里留下一个零空终止符。
在标准 C 中完成带有测试的代码。显然为您的自定义 LCD 例程删除 puts
。
#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!='[=12=]'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='[=12=]') // 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!='[=13=]'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='[=13=]') // in case there is only one zero character
break;
}
puts(p); // use whatever string printing routine you got
}
我最近买了一个STM8单片机,它有内置功能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 语言,因为我现在正在编写的是纯驱动程序。
你离 "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))
您需要将数字存储在缓冲区中以获得从左到右的顺序。在微控制器上,您可能希望在 .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;
}
请注意,此代码始终保持项目 buf[5]
不变,并在那里留下一个零空终止符。
在标准 C 中完成带有测试的代码。显然为您的自定义 LCD 例程删除 puts
。
#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!='[=12=]'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='[=12=]') // 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!='[=13=]'; p++)
{
if(*p!='0' || // stop looking at first non zero or
p[1]=='[=13=]') // in case there is only one zero character
break;
}
puts(p); // use whatever string printing routine you got
}