/*======================================*/
/* インクルード */
/*======================================*/
#include "sfr_r838a.h" /* R8C/38A SFRの定義ファイル */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include "printf_lib.h" /* printf使用ライブラリ */
//#include "hd44780.h"
/*======================================*/
/* シンボル定義 */
/*======================================*/
#define LCD_DB p3
#define LCD_DB7 p3_3
#define LCD_DB6 p3_2
#define LCD_DB5 p3_1
#define LCD_DB4 p3_0
#define LCD_STB p3_4
#define LCD_RS p3_5
#define LCD_LGT p3_6
#define PWRKEY p3_7
#define KEY_INTERVAL 3 //キーパッド サンプリング間隔[ms]
#define AUTOLIGHTOFF 10000 //バックライトオフまでの時間(ms) 1000*10→10秒
#define AUTOPOWEROFF 90000 //オートパワーオフまでの時間(ms) 1000*60*1.5→1.5分
#define SPACE ' ' //空白
//#define PI pi //円周率
#define PI (atan(1.0) * 4.0) //円周率
#define NAPIER (exp(1)) //ネイピア数
//#define ERRORMESSAGE
/* キー・ID定義 */
#define KEYID_BKLGT 0x72
#define KEYID_71 0x71
#define KEYID_MODE 0x70
#define KEYID_RIGHT 0x34 //右 →
#define KEYID_LEFT 0x31 //左 ←
#define KEYID_UP 0x33 //上 ↑
#define KEYID_DOWN 0x32 //下 ↓
#define KEYID_SELECT 0x30 //中央(決定)
#define KEYID_NUM0 0x20
#define KEYID_NUMPOINT 0x01
#define KEYID_NUM1 0x22
#define KEYID_NUM2 0x03
#define KEYID_NUM3 0x02
#define KEYID_NUM4 0x24
#define KEYID_NUM5 0x05
#define KEYID_NUM6 0x04
#define KEYID_NUM7 0x26
#define KEYID_NUM8 0x07
#define KEYID_NUM9 0x06
#define KEYID_NUMDEL 0x17
#define KEYID_NUMAC 0x16
#define KEYID_NUMEQUAL 0x10
#define KEYID_NUMPLUS 0x13
#define KEYID_NUMMINUS 0x12
#define KEYID_NUMX 0x15
#define KEYID_NUMSLASH 0x14
#define KEYID_NUM11 0x11
#define KEYID_NUM00 0x00
#define KEYID_INV 0x50 //正負
#define KEYID_NEG 0x47 //逆数
#define KEYID_SQUARE 0x51 //二乗
#define KEYID_SQROOT 0x52 //平方根
#define KEYID_POWER 0x53 //累乗(xのy乗)
#define KEYID_ANGLEUNIT 0x35 //角度の単位 度数法・弧度法 モード変更(ラーージーーーアーーーーーン!ディィィーーーーグリーーー!)
#define ANGLEUNIT_DEG 0 //度数法なら0
#define ANGLEUNIT_RAD 1 //弧度法なら1
#define KEYID_SIN 0x40 //サイン
#define KEYID_COS 0x37 //コサイン
#define KEYID_TAN 0x36 //タンジェント
#define KEYID_PI 0x65 //円周率を挿入
#define KEYID_NAPIER 0x66 //ネイピア数を挿入(未実装)
#define KEYID_LOG10 0x57 //log10
#define KEYID_LN 0x56 //loge(ネイピア数)
#define MODEID_PWROFF 00 //電源OFF
#define MODEID_IFX 01 //(InFiX mode).....中間記法
#define MODEID_RPN 02 //(Reverse Polish Notation mode).....逆ポーランド記法
#define MODEID_LOGICAL 03 //論理演算モード(2進数、8進数、10進数、16進数)
#define MODEID_CHMOD 0xff //モードチェンジ用画面表示
#define MODEID_DEFAULT 02 //初期状態
#define CHMOD_SCROLLY_0 Lcd_line_print(2,MsgChmod2);Lcd_line_print(3,MsgChmod3);Lcd_line_print(4,MsgChmod4);
#define CHMOD_SCROLLY_1 Lcd_line_print(2,MsgChmod3);Lcd_line_print(3,MsgChmod4);Lcd_line_print(4,MsgChmod5);
#define CHMOD_SCROLLY_2 Lcd_line_print(2,MsgChmod4);Lcd_line_print(3,MsgChmod5);Lcd_line_print(4,MsgChmod6);
#define CHMOD_SCROLLY_3 Lcd_line_print(2,MsgChmod5);Lcd_line_print(3,MsgChmod6);Lcd_line_print(4,MsgChmod7);
#define CHMOD_SCROLLY_4 Lcd_line_print(2,MsgChmod6);Lcd_line_print(3,MsgChmod7);Lcd_line_print(4,MsgChmod8);
#define CHMOD_SCROLLY_MAX 4
#define CHMOD_SCROLLY_MIN 0
#define CHMOD_SCROLLY_PRINTLCD switch(scrollY){case 0: CHMOD_SCROLLY_0 break; case 1: CHMOD_SCROLLY_1 break; case 2: CHMOD_SCROLLY_2 break; case 3: CHMOD_SCROLLY_3 break; case 4: CHMOD_SCROLLY_4 break; default: scrollY=0; cursorY = 2; CHMOD_SCROLLY_0 break;}
/*======================================*/
/* プロトタイプ宣言 */
/*======================================*/
void init( void );
void timer( unsigned long timer_set );
unsigned char dipsw_get( void );
unsigned char chmod(void);
void mode_rpn(void);
void mode_infix(void);
void mode_logical(void);
void Lcd_init(void); //LCD初期化
void Lcd_output(char *str); //
void Lcd_clear(void);
void Lcd_black(void);
void Lcd_cmd(char cmd);
void Lcd_data(char asci);
void Lcd_out(char code, char flag);
void Lcd_locate(char x, char y); //カーソルの位置指定
void Lcd_cursol(char c_mode); //カーソルの表示を変更
void Lcd_line_print(char y,char *str); //LCDに出力。行数指定有り
void Lowspeed_Lcd_line_print(char y,unsigned long w,char *str); //LCDに出力。行数指定有り。タイプライターっぽく遅延しながら表示
void Lcd_Itostring(char y, int digit, unsigned long data, char *buffer, char z);
void Lcd_line_print_cgram(char y);
void Lcd_backlight(char z);
char Lcd_backlight_stat(void);
void Delay(long usec);
void Delay_ms(unsigned long msec);
//void Itostring(int digit, unsigned long data, char *buffer);
//void Ltostring(int digit, unsigned long long data, char *buffer);
void Ltostring_int(int digit, unsigned long long data, char *buffer);
void Ltostring_decimal(int digit, unsigned long long data, char *buffer);
void Keypad_read(void);
void Poweroff(void);
unsigned char Check_key_bit(unsigned char keyid,const char *buffer);
void stackin(char in,char digits,char position,char *stack);
void myftoa(char *string, double f, int figure);
double myatof(const char *string);
unsigned long long POW(int a, int b);
void mode_infomation(void);
double DegtoRad(double degree);
double RadtoDeg(double radian);
double mysin(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
double mycos(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
double mytan(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
double myasin(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
double myacos(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
double myatan(double Angle , char AngleUnit); //Angle:角度 AngleUnit:角度の単位(ANGLEUNIT_DEG,ANGLEUNIT_RAD)
void error_handing(void);
/*======================================*/
/* グローバル変数の宣言 */
/*======================================*/
unsigned long cnt0; /* timer関数用 */
unsigned char cnt1; /* main内で使用 */
char cnt2;
char cnt3;
unsigned char pwrhold = 0;
char backlight_stat = 0;
char key0 = 0;
char keystat[8] = {0,0,0,0,0,0,0,0};
char keynow[8] = {0,0,0,0,0,0,0,0};
char keypast[8] = {0,0,0,0,0,0,0,0};
char keypast0[8] = {0,0,0,0,0,0,0,0};
char keypast1[8] = {0,0,0,0,0,0,0,0};
//char keypast2[8] = {0,0,0,0,0,0,0,0};
//char keypast3[8] = {0,0,0,0,0,0,0,0};
//char keypast4[8] = {0,0,0,0,0,0,0,0};
char keypast5[8] = {0,0,0,0,0,0,0,0};
char key0to1[8] = {0,0,0,0,0,0,0,0};
char key1to0[8] = {0,0,0,0,0,0,0,0};
unsigned long delayms = 0;
char Is_InfomationMode = 0;
char angleunitmode = ANGLEUNIT_DEG;
/************************************************************************/
/* メインプログラム */
/************************************************************************/
void main( void )
{
unsigned char mode = MODEID_DEFAULT;
/* マイコン機能の初期化 */
init(); /* 初期化 */
asm(" fset I "); /* 全体の割り込み許可 */
while(1){
Lcd_init();
Lcd_clear();
Lcd_cursol(4);
Lcd_clear();
switch(mode){
case MODEID_PWROFF: //電源OFF
Poweroff();
break;
case MODEID_IFX: //中間記法(普通の数式)モード
mode_infix(); //中間記法(InFiX mode)
mode = MODEID_CHMOD;
break;
case MODEID_RPN: //RPN(逆ポーランド記法)モード
mode_rpn();
mode = MODEID_CHMOD;
break;
case MODEID_LOGICAL:
mode_logical();
mode = MODEID_CHMOD;
break;
case MODEID_CHMOD:
default:
mode = chmod(); //モード変更画面
break;
}
}
}//←←←←←←←メイン関数終了
unsigned char chmod(void){ //チェンジモード モードIDを返します
char cursorX,cursorY,scrollY,i;
char MsgChmod1[21] = " *** ChangeMODE 0-2 ";
char MsgChmod2[21] = "0.PWR OFF ";
char MsgChmod3[21] = "1.InFiX MODE ";
char MsgChmod4[21] = "2.RPN MODE ";
char MsgChmod5[21] = "3.Logical operation ";
char MsgChmod6[21] = "4.Undefined ... ";
char MsgChmod7[21] = "5.Undefined ... ";
char MsgChmod8[21] = "6.Undefined ... ";
Lcd_line_print(1,MsgChmod1);
cursorX = 1;cursorY = 2;scrollY = 0;
CHMOD_SCROLLY_PRINTLCD
Lcd_locate(cursorX,cursorY);
printf("/*** Change MODE ***/\n");
while(1)
{
Delay_ms(1);
for(i=0;i<=7;i++)
{
key0to1[i] = keystat[i] & ~keypast5[i];
keypast5[i] = keystat[i];
}
if(Check_key_bit(KEYID_RIGHT,key0to1))
{
cursorX++;
Lcd_locate(cursorX,cursorY);
}
if(Check_key_bit(KEYID_LEFT,key0to1))
{
cursorX--;
Lcd_locate(cursorX,cursorY);
}
if(Check_key_bit(KEYID_DOWN,key0to1))
{
cursorY++;
Lcd_locate(cursorX,cursorY);
}
if(Check_key_bit(KEYID_UP,key0to1))
{
cursorY--;
Lcd_locate(cursorX,cursorY);
}
if(Check_key_bit(KEYID_SELECT,key0to1)){
switch(cursorY + scrollY){
case 2:
return MODEID_PWROFF;
break;
case 3:
return MODEID_IFX;
break;
case 4:
return MODEID_RPN;
break;
case 5:
return MODEID_LOGICAL;
return 3;
break;
case 6:
return 4;
break;
}
}
if(Check_key_bit(KEYID_NUM0,key0to1)){
return MODEID_PWROFF;
}
if(Check_key_bit(KEYID_NUM1,key0to1)){
return MODEID_IFX;
}
if(Check_key_bit(KEYID_NUM2,key0to1)){
return MODEID_RPN;
}
if(Check_key_bit(KEYID_NUM3,key0to1)){
return MODEID_LOGICAL;
}
if(cursorY > 4)
{
scrollY++;
cursorY = 4;
CHMOD_SCROLLY_PRINTLCD
Lcd_locate(cursorX,cursorY);
}
if(cursorY < 2)
{
scrollY--;
cursorY = 2;
CHMOD_SCROLLY_PRINTLCD
Lcd_locate(cursorX,cursorY);
}
if(cursorX > 20) {cursorX = 1;Lcd_locate(cursorX,cursorY);}
if(cursorX < 1) {cursorX = 20;Lcd_locate(cursorX,cursorY);}
}
return MODEID_CHMOD;
} //←←←←←←←chmod関数終了
void mode_infix(void){ //Infixモード(中間記法)
printf("/*** Infix MODE ***/\n"); return;
} //←←←←←←←mode_infix関数終了
void mode_rpn(void){ //RPNモード(逆ポーランド記法)
unsigned char i = 0;
char demical = 0;
char MsgPrint1[25] = "\0";
char MsgPrint2[25] = "\0";
char MsgPrint3[25] = "\0";
char MsgPrint4[25] = "\0";
char KeyStack1[21];
char KeyStack2[21];
char KeyStack3[21];
char KeyStack4[21];
char KeyStack5[21];
char KeyStack6[21];
double Stack[7] = {0,0,0,0,0,0,0};
char Is_nextStackShift = 0;
char cursor = 0;
char cursormode = 4;
char RefreshLCD = 1;
char cursorpast = cursor;
for(i=0;i<=20;i++)
{
KeyStack1[i] = SPACE;
KeyStack2[i] = SPACE;
KeyStack3[i] = SPACE;
KeyStack4[i] = SPACE;
KeyStack5[i] = SPACE;
KeyStack6[i] = SPACE;
}
KeyStack1[20] = '\0';
KeyStack2[20] = '\0';
KeyStack3[20] = '\0';
KeyStack4[20] = '\0';
KeyStack5[20] = '\0';
KeyStack6[20] = '\0';
printf("/*** RPN MODE ***/\n");
while(1)
{ //printf("While Head\n");
Delay_ms(1);
for(i=0;i<=7;i++)
{
key0to1[i] = keystat[i] & ~keypast5[i];
keypast5[i] = keystat[i];
}
{
if(cursor > 19) cursor = 0;
if(Check_key_bit(KEYID_MODE,key0to1)) //モードキーが押された時の処理
{
while(Check_key_bit(KEYID_MODE,keystat)); //モードキーが離されるまで待つ
return; //main()関数に戻る
}
if(Check_key_bit(0x74,key0to1)) //テスト用のキー。あとで変更する
{
cursormode++;
if(cursormode >= 5) cursormode = 1;
Lcd_cursol(cursormode);
}
if(Check_key_bit(0x73,key0to1)) //テスト用のキー。あとで変更する
{
cursormode++;
if(cursormode >= 5) cursormode = 1;
Lcd_cursol(cursormode);
}
if(Check_key_bit(KEYID_LEFT,key0to1)) //方向キー ←
{
if(cursor) cursor--;
while(Check_key_bit(KEYID_LEFT,keystat))
{
if(Check_key_bit(KEYID_NUM0,key0to1)) cursor = 0;
if(Check_key_bit(KEYID_NUM1,key0to1)) cursor--;
if(Check_key_bit(KEYID_NUM2,key0to1)) cursor -= 2;
if(Check_key_bit(KEYID_NUM3,key0to1)) cursor -= 3;
if(Check_key_bit(KEYID_NUM4,key0to1)) cursor -= 4;
if(Check_key_bit(KEYID_NUM5,key0to1)) cursor -= 5;
if(Check_key_bit(KEYID_NUM6,key0to1)) cursor -= 6;
if(Check_key_bit(KEYID_NUM7,key0to1)) cursor -= 7;
if(Check_key_bit(KEYID_NUM8,key0to1)) cursor -= 8;
if(Check_key_bit(KEYID_NUM9,key0to1)) cursor -= 9;
if(cursor > 19) cursor = 0;
if(cursorpast != cursor) Lcd_locate(cursor+1,4);
cursorpast = cursor;
for(i=0;i<=7;i++)
{
key0to1[i] = keystat[i] & ~keypast5[i];
keypast5[i] = keystat[i];
}
}
}
if(Check_key_bit(KEYID_RIGHT,key0to1)) //方向キー →
{
if(cursor<=19) cursor++;
while(Check_key_bit(KEYID_RIGHT,keystat))
{
if(Check_key_bit(KEYID_NUM0,key0to1)) cursor = 19;
if(Check_key_bit(KEYID_NUM1,key0to1)) cursor++;
if(Check_key_bit(KEYID_NUM2,key0to1)) cursor += 2;
if(Check_key_bit(KEYID_NUM3,key0to1)) cursor += 3;
if(Check_key_bit(KEYID_NUM4,key0to1)) cursor += 4;
if(Check_key_bit(KEYID_NUM5,key0to1)) cursor += 5;
if(Check_key_bit(KEYID_NUM6,key0to1)) cursor += 6;
if(Check_key_bit(KEYID_NUM7,key0to1)) cursor += 7;
if(Check_key_bit(KEYID_NUM8,key0to1)) cursor += 8;
if(Check_key_bit(KEYID_NUM9,key0to1)) cursor += 9;
if(cursor > 19) cursor = 0;
if(cursorpast != cursor) Lcd_locate(cursor+1,4);
cursorpast = cursor;
for(i=0;i<=7;i++)
{
key0to1[i] = keystat[i] & ~keypast5[i];
keypast5[i] = keystat[i];
}
}
}
if(Check_key_bit(KEYID_NUMAC,key0to1)) //AC押した時
{
Is_nextStackShift = 0;
Lcd_clear();
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
KeyStack2[i] = SPACE;
KeyStack3[i] = SPACE;
KeyStack4[i] = SPACE;
}
for(i=0;i<=6;i++)
{
Stack[i] = 0;
}
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMDEL,key0to1)) //DEL押した時
{
if(cursor) cursor--; //cursorが"0"以外なら実行
if(cursor <= 19) stackin(0x7f,19,cursor,KeyStack1); //0x7f…アスキーコードで「DEL」をあらわす
Is_nextStackShift = 0;
RefreshLCD = 1;
i = 0;
while(Check_key_bit(KEYID_NUMDEL,keystat))
{
i++;
Delay_ms(10);
if(Check_key_bit(KEYID_NUMAC,keystat))
{
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
cursor = 0;
break;
}
if(i >= 150)
{
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
cursor = 0;
break;
}
}
i = 0;
}
if(Check_key_bit(KEYID_NUMPOINT,key0to1)) //小数点キー押した時
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('.',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM0,key0to1)) //数字キー 0
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('0',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM1,key0to1)) //数字キー 1
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('1',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM2,key0to1)) //数字キー 2
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('2',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM3,key0to1)) //数字キー 3
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('3',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM4,key0to1)) //数字キー 4
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('4',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM5,key0to1)) //数字キー 5
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('5',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM6,key0to1)) //数字キー 6
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('6',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM7,key0to1)) //数字キー 7
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('7',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM8,key0to1)) //数字キー 8
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('8',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUM9,key0to1)) //数字キー 9
{
if(Is_nextStackShift)
{
Is_nextStackShift = 0;
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
Stack[2] = Stack[1];
cursor = 0;
//Lcd_clear();
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
}
stackin('9',19,cursor,KeyStack1);
++cursor;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMEQUAL,key0to1)) //イコール= キー
{
Stack[6] = Stack[5];
Stack[5] = Stack[4];
Stack[4] = Stack[3];
Stack[3] = Stack[2];
if(Is_nextStackShift)
{
Stack[2] = Stack[1];
}else{
Stack[2] = myatof(KeyStack1);
}
Stack[1] = 0;
cursor = 0;
for(i=0;i<=19;i++)
{
KeyStack1[i] = SPACE;
}
Is_nextStackShift = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMPLUS,key0to1)) //プラス + 押した時
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] += Stack[2];
myftoa(KeyStack1,Stack[1],0);
Stack[2] = Stack[3];
Stack[3] = Stack[4];
Stack[4] = Stack[5];
Stack[5] = Stack[6];
Is_nextStackShift = 1;
Stack[6] = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMMINUS,key0to1)) //マイナス - 押した時
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = Stack[2] - Stack[1];
myftoa(KeyStack1,Stack[1],0);
Stack[2] = Stack[3];
Stack[3] = Stack[4];
Stack[4] = Stack[5];
Stack[5] = Stack[6];
Is_nextStackShift = 1;
Stack[6] = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMX,key0to1)) //かける× 押した時
{
printf("Check key X(KAKEZAN)\n"); if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] *= Stack[2];
myftoa(KeyStack1,Stack[1],0);
Stack[2] = Stack[3];
Stack[3] = Stack[4];
Stack[4] = Stack[5];
Stack[5] = Stack[6];
Is_nextStackShift = 1;
Stack[6] = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_NUMSLASH,key0to1)) //割る÷ 押した時
{
printf("Check key WARIZAN\n"); if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = Stack[2] / Stack[1];
myftoa(KeyStack1,Stack[1],0);
Stack[2] = Stack[3];
Stack[3] = Stack[4];
Stack[4] = Stack[5];
Stack[5] = Stack[6];
Is_nextStackShift = 1;
Stack[6] = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_INV,key0to1)) // 逆数
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = 1 / Stack[1];
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_NEG,key0to1)) // 正負変換
{
if(KeyStack1[0]==SPACE)
{
RefreshLCD = 1;
KeyStack1[0] = '-';
cursor = 1;
}else
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = 0 - Stack[1];
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
}
if(Check_key_bit(KEYID_SQUARE,key0to1)) // 二乗
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = Stack[1] * Stack[1];
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_SQROOT,key0to1)) // 平方根
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack
[1] = sqrt(Stack
[1]); myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_POWER,key0to1)) //累乗(xのy乗) Stack2^Stack1
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack
[1] = pow(Stack
[2],Stack
[1]); myftoa(KeyStack1,Stack[1],0);
Stack[2] = Stack[3];
Stack[3] = Stack[4];
Stack[4] = Stack[5];
Stack[5] = Stack[6];
Is_nextStackShift = 1;
Stack[6] = 0;
RefreshLCD = 1;
}
if(Check_key_bit(KEYID_LOG10,key0to1)) //常用対数 log10
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack
[1] = log10(Stack
[1]); myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_LN,key0to1)) //自然対数 log e (ネイピア数
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack
[1] = log(Stack
[1]); myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_SIN,key0to1)) //正弦サイン
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = mysin(Stack[1],angleunitmode);
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_COS,key0to1)) //コサイン
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = mycos(Stack[1],angleunitmode);
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_TAN,key0to1)) //タンジェント
{
if(~Is_nextStackShift)
{
Stack[1] = myatof(KeyStack1);
}
Stack[1] = mytan(Stack[1],angleunitmode);
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_PI,key0to1)) //円周率キー
{
Stack[1] = PI;
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
if(Check_key_bit(KEYID_NAPIER,key0to1)) //ネイピア数キー
{
Stack[1] = NAPIER;
myftoa(KeyStack1,Stack[1],0);
RefreshLCD = 1;
Is_nextStackShift = 1;
}
}
//printf("cursor: %d\n",cursor);
if(RefreshLCD == 1)
{
myftoa(KeyStack2,Stack[2],0);
myftoa(KeyStack3,Stack[3],0);
myftoa(KeyStack4,Stack[4],0);
Lcd_cursol(1);
Lcd_line_print(1,KeyStack4);
Lcd_line_print(2,KeyStack3);
Lcd_line_print(3,KeyStack2);
Lcd_line_print(4,KeyStack1);
RefreshLCD = 0;
Lcd_locate(cursor+1,4);
Lcd_cursol(cursormode);/*
printf("\nStack1 : %g\n",Stack[1]);
printf("\nStack2 : %g\n",Stack[2]);
printf("\nStack3 : %g\n",Stack[3]);
printf("\nStack4 : %g\n",Stack[4]);
printf("\nStack5 : %g\n",Stack[5]);
printf("\nStack6 : %g\n",Stack[6]);*/
printf("KeyStack1 : %s\n",KeyStack1
); printf("KeyStack2 : %s\n",KeyStack2
); printf("KeyStack3 : %s\n",KeyStack3
); printf("KeyStack4 : %s\n",KeyStack4
); }
if(errno) //エラー時の処理
{
error_handing();
RefreshLCD = 0;
}
if(cursorpast != cursor) Lcd_locate(cursor+1,4);
cursorpast = cursor;
}
} //←←←←←←←mode_rpn関数終了
void mode_logical(void)
{
} //←←←←←←←mode_logical関数終了
/************************************************************************/
/* R8C/38A スペシャルファンクションレジスタ(SFR)の初期化 */
/************************************************************************/
void init( void )
{
int i;
/* クロックをXINクロック(20MHz)に変更 */
prc0 = 1; /* プロテクト解除 */
cm13 = 1; /* P4_6,P4_7をXIN-XOUT端子にする*/
cm05 = 0; /* XINクロック発振 */
for(i=0; i<50; i++ ); /* 安定するまで少し待つ(約10ms) */
ocd2 = 0; /* システムクロックをXINにする */
prc0 = 0; /* プロテクトON */
/* ポートの入出力設定 0:入力 1:出力 76543210 */
prc2 = 1; /* PD0のプロテクト解除 */
pd0 = 0x00; /* */
pd1 = 0xd0; /* 5:RXD0 4:TXD0 3-0:DIP SW 1101 0000 */
p2 = 0xc0;
pd2 = 0xfe; /* */
pd3 = 0xff; /*LCD 0-DB4~3-DB7 4-Enable 5-RS 6-BkLGT*/
p3 = 0x00;
p4 = 0x00; /* P4_5のLED:初期は消灯 */
pd4 = 0xb8; /* 7:XOUT 6:XIN 5:LED 2:VREF */
pd5 = 0x00; /* キーマトリックス・入力 プルアップON */
pu12 = 1;pu13 = 1;
pd6 = 0xff; /* キーマトリックス・出力 */
drr14 = 1; drr15 = 1;
pd7 = 0x00; /* 電池電圧検出用とか */
pd8 = 0xff; /* */
pd9 = 0x00; /* 0-5 IN */
//p9 = 0x38;
pur0 = 0x04; /* P1_3~P1_0のプルアップON */
vlt22 = 1; /* P9_0~P9_5 入力スレッショルド→0.35×VCCにセット */
vlt23 = 0; /* */
/* タイマRBの設定 */
/* 割り込み周期 = 1 / 20[MHz] * (TRBPRE+1) * (TRBPR+1)
= 1 / (20*10^6) * 200 * 100
= 0.001[s] = 1[ms]
*/
trbmr = 0x00; /* 動作モード、分周比設定 */
trbpre = 200-1; /* プリスケーラレジスタ */
trbpr = 100-1; /* プライマリレジスタ */
trbic = 0x06; /* 割り込み優先レベル設定 */
trbcr = 0x01; /* カウント開始 */
/* タイマRD リセット同期PWMモードの設定*/
/* PWM周期 = 1 / 20[MHz] * カウントソース * (TRDGRA0+1)
= 1 / (20*10^6) * 8 * 40000
= 0.016[s] = 16[ms]
*/
trdpsr0 = 0x08; /* TRDIOB0,C0,D0端子設定 */
trdpsr1 = 0x05; /* TRDIOA1,B1,C1,D1端子設定 */
trdmr = 0xf0; /* バッファレジスタ設定 */
trdfcr = 0x01; /* リセット同期PWMモードに設定 */
trdcr0 = 0x23; /* ソースカウントの選択:f8 */
trdgra0 = trdgrc0 ; /* 周期 */
trdgrb0 = trdgrd0 = 0; /* P2_2端子のON幅設定 */
trdgra1 = trdgrc1 = 0; /* P2_4端子のON幅設定 */
trdgrb1 = trdgrd1 ; /* P2_5端子のON幅設定 */
trdoer1 = 0xcd; /* 出力端子の選択 */
trdstr = 0x0d; /* TRD0カウント開始 */
//Delay_ms(2);
p4 = 0x20; /* P4_5のLED:初期は点灯 */
init_uart0_printf( SPEED_9600 );
"\n/* START Function Calcrator Alpha Ver. */\n"
"/* Made by kuriuzu */ \n"
"/* This is UART Debug Console */\n"
);
}
/************************************************************************/
/* タイマRB 割り込み処理 */
/************************************************************************/
#pragma interrupt intTRB(vect=24)
void intTRB( void )
{
delayms++;
cnt0++;
cnt1++;
cnt2++;
if(cnt2 == KEY_INTERVAL){
cnt2 = 0;
Keypad_read();
}
}
/************************************************************************/
/* タイマ本体 */
/* 引数 タイマ値 1=1ms */
/************************************************************************/
void timer( unsigned long timer_set )
{
delayms = 0;
while( delayms < timer_set );
}
/************************************************************************/
/* ディップスイッチ値読み込み */
/* 戻り値 スイッチ値 0~15 */
/************************************************************************/
unsigned char dipsw_get( void )
{
unsigned char sw;
sw = p1 & 0x0f; /* P1_3~P1_0読み込み */
return sw;
}
//----- ディレイ関数 msec単位 -----
void Delay_ms(unsigned long msec) //!注意!最大-1[ms]の誤差が出ます。!注意!
{
delayms = 0;
while(delayms < msec)
{
_asm(
"fset I;"
"wait;"
"nop;"
"nop;"
"nop;"
"nop;"
);
}
}
//----- ディレイ関数 1usec単位 -----
void Delay(long usec)
{
usec = (usec * 20000) / 45000;
while(usec--){}
}
//----------------------------------------------------
// 液晶表示器制御ライブラリ
//----------------------------------------------------
//----- LCD初期化関数 -----
void Lcd_init()
{
Delay(20000); //20msec wait
Lcd_out(0x03, 1); //8bit mode set
Delay(5000); //5msec wait
Lcd_out(0x03, 1); //8bit mode set
Delay(1000);
Lcd_out(0x03, 1); //8bit mode set
Delay(1000);
Lcd_out(0x02, 1); //4bit mode set
Delay(1000);
Lcd_cmd(0x2C); //DL=0 4bit mode
Lcd_cmd(0x08); //display off C=D=B=0
Lcd_cmd(0x0E); //display on D=B=1 C=0
Lcd_cmd(0x06); //entry I/D=1 S=0
Lcd_cmd(0x01); //all clear
}
//----- データ出力サブ関数 -----
void Lcd_out(char code, char flag)
{
LCD_DB = (LCD_DB & 0xf0) | (code & 0x0f);
//出力データ下位4ビットを出力
if (flag == 0) //表示データかコマンドか
LCD_RS = 1; //表示データの場合RS=1
else
LCD_RS = 0; //コマンドデータの場合RS=0
asm("NOP"); //NOP スキュー確保
LCD_STB = 1; //STB ON
asm("NOP");
asm("NOP"); //パルス幅確保230nsec以上
asm("NOP");
asm("NOP");
LCD_STB = 0; //STB OFF
}
//----- 1文字表示関数 -----
void Lcd_data(char asci)
{
Lcd_out(asci>>4, 0); //上位4ビット出力
Lcd_out(asci, 0); //下位4ビット出力
Delay(50); //50μsec待ち
}
//----- コマンド出力関数 -----
void Lcd_cmd(char cmd)
{
Lcd_out(cmd>>4, 1); //上位4ビット出力
Lcd_out(cmd, 1); //下位4ビット出力
if((cmd == 0x01) || (cmd == 0x02))
Delay(2000); //2msec待ち
else
Delay(50); //50usec待ち
}
//----- 全消去関数 -----
void Lcd_clear()
{
Lcd_cmd(0x01); //初期化コマンド出力
}
//----- 文字列出力関数 -----
void Lcd_output(char *str)
{
while(*str != 0x00) //文字列の終わり判定
{
Lcd_data(*str); //文字列1文字出力
str++; //ポインタ+1
}
}
//----- カーソル位置に移動 -----
void Lcd_locate(char x, char y)
{
char i;
if (y == 1){
Lcd_cmd(0x02);
x--;
while ( x ){
Lcd_cmd(0x14);
x--;
}
}else if (y == 2){
Lcd_cmd(0x02);
x--;
for (i=1;i<=40;i++){
Lcd_cmd(0x14);
}
while ( x ){
Lcd_cmd(0x14);
x--;
}
}else if (y == 3){
Lcd_cmd(0x02);
x--;
for (i=1;i<=20;i++){
Lcd_cmd(0x14);
}
while ( x ){
Lcd_cmd(0x14);
x--;
}
}else if (y == 4){
Lcd_cmd(0x02);
x--;
for (i=1;i<=60;i++){
Lcd_cmd(0x14);
}
while ( x ){
Lcd_cmd(0x14);
x--;
}
}
}
//----- カーソル表示制御 -----
void Lcd_cursol(char c_mode)
{
switch ( c_mode){
case 1: // 1.カーソルOFF、ブリンクOFF
Lcd_cmd(0x0c);
break;
case 2: // 2.カーソルOFF、ブリンクON
Lcd_cmd(0x0d);
break;
case 3: // 3.カーソルON、ブリンクOFF
Lcd_cmd(0x0e);
break;
case 4: