我在hitech C中编写16f84a pic以驱动hd44780 lcd。到目前为止,我已经初始化了lcd,可以将单个字符和字符串写入lcd。现在我需要做这样的事情:
var = 250;
lcd_write_string
(“MyVar有值:”+ var);
所以lcd应该显示“MyVar有价值:250”
首先,我应该如何连接var和string? 第二,变量var包含一个8位二进制数(十进制0-255)。如果var = 23;必须将8位数字拆分为2以表示ascii中的2和3,然后由lcd显示。我怎样才能做到这一点?我似乎必须进行10次转换或if树分割所有2位数字然后显示在lcd中。有更简单的方法吗?
谢谢!
答案 0 :(得分:4)
为什么不使用printf("%d", var)
?
var = 250;
char *static_msg = "MyVar has value:";
char msg[sizeof(static_msg) + 4];
sprintf(msg, "%s %d", static_msg, var);
lcd_write_string(msg);
答案 1 :(得分:1)
假设您的工具集不包含标准C库,或者您想自己弄清楚如何执行此操作,我将采用以下方法:
声明LCD可以显示的字符数的缓冲区。将固定字符串写入该缓冲区的开头。确定你的变量有多少个字符宽(我在这里留下了一些数学,但我觉得这是一个合理的练习)。使用该长度和固定字符串的长度,找出缓冲区中您的数字的位数。使用与以前相同的数学结构,将数字逐个写入该空间。有一种C语言的技巧(标准所要求的)可以让你通过表达式'0' + digit
找出十进制数字的字符值。希望你看到它是如何工作的。最后,终止缓冲区但是你的lcd_write_string
函数需要,并在缓冲区上调用它。
正如其他受访者所指出的,这基本上实现了标准库printf
系列函数的一小部分。我认为有必要弄清楚实现,即使你可以(并且应该!)在生产代码中使用库。
由于这有点像家庭作业,我还没有进一步阐述。如果您需要特定点的帮助,我会寻找问题的更新。
答案 2 :(得分:0)
如果C编译器附带标准C库函数,则sprintf
可以类似于printf
使用,以生成字符串。
sprintf
可用于生成格式化字符串(如char*
),可能会将其发送到lcd_write_string
函数。
答案 3 :(得分:0)
sprintf()的问题是你在调用sprintf()之前不知道需要分配多少字节。我通常使用以下ksprintf()作为替代。
typedef struct __kstring_t {
size_t l, m;
char *s;
} kstring_t;
int ksprintf(kstring_t *s, const char *fmt, ...)
{
va_list ap;
int l;
va_start(ap, fmt);
l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); // not working with glibc 2.0
va_end(ap);
if (l + 1 > s->m - s->l) {
s->m = s->l + l + 2;
kroundup32(s->m);
s->s = (char*)realloc(s->s, s->m);
va_start(ap, fmt);
l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap);
}
va_end(ap);
s->l += l;
return l;
}
使用它:
kstring_t *str = calloc(1, sizeof(kstring_t));
ksprintf(str, "%s, %d\n", aString, aInteger);
ksprintf(str, "a second line: %s\n", aString2);
free(str->s); free(s);
ksprintf()不能与glibc 2.0一起使用,因为vsnprintf不返回字符串中的字节数。您需要在分配中重复加倍内存。 Linux手册页“man snprintf”也举了一个例子。在你的系统上,你应该检查你的vsnprintf()的行为,它是C99,而不是C90。
答案 4 :(得分:0)
另一种方法是使用lcd_write_string作为函数指针并执行此操作:
printf(lcd_write_string,"MyVar has value: %d",var)
如果lcd_write_string声明为
,则在CCS Pic C编译器上可以正常工作void lcd_write_string (char c);