Printf関数を自作する
出典: SpiralRay_Wiki
ココを参考にして、マイコンに接続したLCDにフォント表示をするためのprintf関数を自作する。
printf関数には、変数の内容などを表示するときに、複数の引数を取ることができる。
C言語での可変長引数の宣言は'...'で表現する。
つまり、
void printf(char * fmt, ...)
このようにする。
以下にprintf関数内の例を示す。
引数の設定以外は簡単なので、下のソースコードから把握してください。
stringsystem.c
#include <stdio.h>
#include "stringsystem.h"
void d_printf(char * fmt, ...) { //stdio.h内のprintfとの競合は避ける
char **arg = (char **) &fmt;
char c;
arg++;
while((c = *fmt++) != 0) {
if(c != '%')
d_putchar(c);
else {
char buf[64];
char *p;
c = *fmt++;
switch(c) {
case 'd':
if( 0 > *((int *) arg) ) {
d_putchar('-');
*((int *) arg) *= -1;
}
p = uint_to_str(buf, *((unsigned *) arg++), 10);
goto print_s;
case 'x':
d_printf("0x");
p = uint_to_str(buf, *((unsigned *) arg++), 16);
goto print_s;
case 's':
p = *arg++;
print_s:
d_printf(p);
break;
default:
d_putchar(c);
}
}
}
}
char * uint_to_str(char *buf, unsigned src, int base) {
char *p = buf;
char *p1, *p2;
do {
*p++ = "0123456789ABCDEF"[src%base];
} while(src /= base);
// Terminate BUF
*p = 0;
// Reverse BUF
for(p1=buf, p2=p-1; p1 < p2; p1++, p2--) {
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
return buf;
}
int nowx = 0;
int line = 0;
unsigned char stringdata[MAX_DISPCHARW][MAX_DISPCHARH];
void initstring(){
for(int y=0 ; y< MAX_DISPCHARH ; y++){
for(int x=0 ; x< MAX_DISPCHARW ; x++){
stringdata[x][y] = 32;
}
}
nowx = 0;
line = 0;
}
void newline(){
nowx = 0;
line = (line+1)%MAX_DISPCHARH;
for(int i=0 ; i<MAX_DISPCHARW ; i++ ){
stringdata[i][line]=32;
}
}
void checkmax_x(){
//横方向にはみ出なければその行でOK
if(nowx<MAX_DISPCHARW) return;
//改行処理
newline();
}
void d_putchar(char c){
//\n
if(c==0x0a){
newline();
return;
}
//\r
else if(c==13){
initstring();
return;
}
//" "TAB
else if(c==9){
if(MAX_DISPCHARW-SURPLUSTAB <= nowx){
newline();
}
else{
nowx += 4-(nowx%4);
}
return;
}
//それ以外
else checkmax_x();
stringdata[nowx][line] = c;
nowx++;
}
stringsystem.h
#define MAX_DISPCHARW 30 //文字数(横方向)の限界 #define MAX_DISPCHARH 20 //文字数(縦方向)の限界 //TABキーの時のスペース数決定(この場合は最大4文字) #define SURPLUSTAB MAX_DISPCHARW%4 extern int nowx; //現在選択されているx(横方向)の番号(左から012...MAX_DISPCHARWまで) extern int line; //現在選択されているy(縦方向)の番号(左から012...MAX_DISPCHARHまで) extern unsigned char stringdata[MAX_DISPCHARW][MAX_DISPCHARH]; //文字列の保存 void initstring(); //文字列を全てフォーマット。行、列ともに0に戻る void newline(); //改行処理 void checkmax_x(); //列(横方向)がはみ出ないかをチェック char * uint_to_str(char *buf, unsigned src, int base); void d_putchar(char c); void d_printf(char * fmt, ...);
ATmega644PとYHY024006A-PCBを使用した例を公開しておく。
回路図はあげてないのでプログラムから推測してください。(データビット以外はdefineで宣言してあるからわかりやすいかと)
(YHY024006A-PCBは16bitモードで動作させています)
パスワードはspiralray
lcd_with_atmega644p.rar
また、windowsでのコンソールでの例も挙げておく。
パスワードはspiralray
stringtest.rar
