Skip to content

Instantly share code, notes, and snippets.

@NotFounds
Last active May 16, 2016 12:44
Show Gist options
  • Save NotFounds/ae9558bc41a99465f60a32ee283029a5 to your computer and use it in GitHub Desktop.
Save NotFounds/ae9558bc41a99465f60a32ee283029a5 to your computer and use it in GitHub Desktop.
実験で使うH8マイコン用の簡易printf関数
/*
The MIT License (MIT)
Copyright (c) 2016 NotFounds
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDED_PRINTF
#define INCLUDED_PRINTF
/* 使い方 */
/*
#include "h8_printf.h"
通常のprintfと同じように使う
例:
h8_printf("Hello World!");
h8_printf("Hello World!%c", 'a');
h8_printf("%5d", -100);
char *str = "HelloWorld!";
h8_printf("%s", str);
*/
#include "dev_lcd.h"
#include <stdarg.h>
#define Length 16 // 一行に表示可能な文字数
// format: 書式指定文字列(%c, %d, %sに対応。また、エスケープ文字は改行コードのみ対応)
// return: 出力した文字数。2行表示した場合、Length + 2行目の文字数。
int h8_printf(const char *format, ...);
int h8_printf(const char *format, ...)
{
char text[Length * 2] = ""; // 表示する文字列
char tmp[Length] = ""; // 整数->文字列変換用
va_list args; // 可変長配列
va_start(args, format);
int isFirstLine = 1; // 一行目かどうか
int i, j, d, sign, flen, len;
char c, *s, *t;
for (i = 0, j = 0; j < Length * 2 - 1; i++, j++)
{
if ((text[j] = format[i]) == 0) break; // null文字なら終了
if (j >= Length - 1 && isFirstLine) // 文字列が長い時自動で改行
{
text[j + 1] = 0;
LCDDisplay(text, isFirstLine); // 一行目の表示
isFirstLine = 0; // 二行目の設定
}
if (format[i] == '%') // 書式指定文字の場合
{
flen = -1; // 整数を桁数指定で表示するために必要
if ('0' <= format[i+1] && format[i+1] <= '9') flen = format[++i] - '0';
switch(format[++i])
{
// 文字を表示
case 'c':
c = va_arg(args, int);
text[j] = c;
break;
// 整数を表示
case 'd':
d = va_arg(args, int);
sign = d < 0; // 符号を調べる
d *= d < 0 ? -1 : 1; // dの符号を変える
t = tmp;
len = 0;
do { // 数値->文字列変換(この時点では逆になる)
*t++ = d % 10 + '0';
d /= 10;
len++;
} while (d > 0);
if (sign) *t++ = '-'; // 負の時符号をつける
*t-- = 0;
while (t >= tmp && j < Length) {
if (flen > len++) text[j++] = '0'; // 0詰め
else text[j++] = *t--;
}
if (t >= tmp && isFirstLine) {
text[j + 1] = 0;
LCDDisplay(text, isFirstLine);
isFirstLine = 0;
}
while (t >= tmp && j < Length * 2 - 1)
{
if (flen > len++) text[j++] = '0'; // 0詰め
else text[j++] = *t--;
}
j--;
break;
// 文字列の表示
case 's':
s = va_arg(args, char *);
while (*s != 0 && j < Length) text[j++] = *s++;
if (*s != 0 && isFirstLine) {
text[j + 1] = 0;
LCDDisplay(text, isFirstLine);
isFirstLine = 0;
}
while (*s != 0 && j < Length * 2 - 1) text[j++] = *s++;
j--;
break;
}
}
else if (format[i] == '\n' && isFirstLine) // 改行コードがあった時の処理
{
text[j] = 0;
LCDDisplay(text, isFirstLine);
j = Length - 1;
isFirstLine = 0;
}
}
text[j] = 0; // null文字の設定
LCDDisplay(text+((1^isFirstLine) * 16), isFirstLine);
va_end(args);
return j; // 出力した文字数を返す
}
#endif
@NotFounds
Copy link
Author

  • 整数の桁数指定に対応(~9)桁まで
  • 実機(H8_3069f, LANボード, LCD:セイコー電子工業M1672)で動作確認済み
  • 高速な動作には適さないことを確認((毎秒書式指定すると重くなる
  • デバッグや演算・状態表示等に用いるには十分

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment