/***********************************************************************/
/* */
/* FILE :control_AD9851_16.c */
/* DATE :Mon, Dec 12, 2005 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :Other */
/* */
/* This file is generated by Renesas Project Generator (Ver.4.0). */
/* */
/***********************************************************************/
#include "sfr_r815.h"
//**********************************************************************
//for AD9851
#define RESET p3_4
#define D7 p3_3
#define W_CLK p1_0
#define FQ_UD p1_1
#define high 1
#define low 0
//************************************************************************
void set_timerX(void);
void set_terminals(void); //port設定
// for LCD display
#define E p1_3
#define R_W p1_2
#define RS p4_5
signed char pos_former = 0;
unsigned char j=0;
unsigned char str[10]="";
//************************************************************************
//for AD9851
void set_FastCLK(void);
void reset_DDS(void);
void send_data(void);
float DDS_data;
unsigned long data;
signed long freq = 1000000;
signed long former_freq = 0;
signed long ex_freq = 1;
signed long disp_freq=0;
signed long offset_temp=455000;
unsigned int i;
unsigned char index = 0;
//*************************************************************************
//for LCD display
void initialize_LCD(void);
void lcd_cmd(void);
void lcd_data(unsigned char);
void busy_check(void);
void lcd_write_str(unsigned char* );
void lcd_clr(void);
void my_sprintf(unsigned long );
void set_comma(unsigned long );
void locate(unsigned char ,unsigned char);
//*************************************************************************
//for Push_SW
#define up p4_7
#define down p4_6
void up_sw_pushed(void);
void down_sw_pushed(void);
//***************************************************************************
//for rotary encoder
#define A p3_5
#define B p3_7
signed char dir[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,-1,1,0 }; /* 回転方向テーブル */
unsigned char result[11]="";
//****************************************************************************
//multi関係
unsigned char multi_pos = 3;
char multi_rev_flag=0;
unsigned char change_multi=0;
unsigned char config_offset=0;
const char str_multi[7][8]
= {"x1Hz ","x10Hz ","x100Hz ","x1KHz ","x10KHz ","x100KHz","x1MHz " };
const signed long multi[7] = {1,10,100,1000,10000,100000,1000000};
//unsigned reverse_flag=0;
//*****************************************************************************
//function 関係
const char str_function[4][11]
= {"SG mode ","mem_call ","offset set","2tone? " };
signed char function=0;
unsigned char release=0;
unsigned char function_select = 1;
//#define function function_array.b0
//******************************************************************************
//for memory
unsigned long memory[10]={7000000,4560000,7890000,0}; //memoryは10個にする。初期値
unsigned long offset[10]={0};
signed char mem_pos=0;
char str_mem_pos[2]="";
//******************************************************************************
//for simulate
//void get_rot_int(void);
// シミュレート手順
// get_rot_int()を宣言
// main関数内に、記述
// #pragma interrupt を 除外
// busy_checkを 除外
//*******************************************************************************
//offset default is minus
unsigned char offset_plus =0;
void main()
{
drr0=drr1=drr2=drr3=1; //駆動能力 high
set_FastCLK();
set_terminals();
p1=0x00;
set_timerX();
initialize_LCD();
set_terminals();
if(!down) //function switch
{
offset_plus=1; //offset direction default is minus offset_plus=0;
locate (1,2);
lcd_write_str("offset is +");
while(!down);
}
if(!up) //桁取りswitch & メモリー選択switch
{
dir[13]=+1; //逆dialに設定
dir[14]=-1;
locate(1,2);
lcd_write_str("set to reverse dial");
while(!up);
}
lcd_clr();
lcd_write_str("SG ");
locate(1,8);
set_comma(freq );
lcd_write_str(result);
lcd_write_str(" Hz");
//桁数移動の初期化
multi_pos = 3;
set_terminals();
locate(2,1);
lcd_write_str( str_multi[multi_pos] );
set_terminals();
reset_DDS();
set_terminals();
DDS_data=28.6334085*freq;//DDS_data=設定値 28.6334082
data=(unsigned long)DDS_data; //data=DDS_dataを32ビット整数値に変換したもの
send_data();
asm("FSET I"); //割り込み許可
txs = 1; //タイマXカウント制御開始ビットのセット
// get_rot_int();
while(1)
{
if(!up)
{
asm("FCLR I");
up_sw_pushed();
asm("FSET I");
}
if(!down)
{
asm("FCLR I");
down_sw_pushed();
asm("FSET I");
}
}
}
#pragma interrupt /B get_rot_int(vect=22)
void get_rot_int()
{
index = ( pos_former<<2 )+ (A<<1) + B;
pos_former = (A<<1) + B; //今の状態を記憶 Aを上位、Bを下位とする
if( function_select==1)
{
function +=dir[index];
if(function>3)function=3;
if(function<0)function=0;
set_terminals();
locate(2,9);
lcd_write_str( str_function[function] );
}
else
{
if( function==0 ) //SG mode
{
freq += multi[multi_pos] * dir[index];
set_terminals();
DDS_data=28.6334085*freq; //DDS_data=設定値 28.6334082
data=(unsigned long)DDS_data; //data=DDS_dataを32ビット整数値に変換したもの
send_data();
if( (ex_freq - freq ) != 0 )
{
set_terminals();
locate(1,8);
set_comma(freq ); //10MHzで、0.633mS費やす
lcd_write_str(result);
ex_freq = freq;
}
}
if( function==1 ) //set memory
{
mem_pos +=dir[index];
if( mem_pos >= 9 )mem_pos=9;
if( mem_pos <= 0 )mem_pos=0;
str_mem_pos[0] = mem_pos+0x30;
set_terminals();
locate(1,4);
lcd_write_str(str_mem_pos);
set_terminals();
locate(1,8);
set_comma(memory[mem_pos] ); //10MHzで、0.633mS費やす
lcd_write_str(result);
lcd_write_str(" Hz");
}
if( (function==2) && (change_multi==1) && (config_offset==0) ) //Config VFO mode
{
freq += multi[multi_pos] * dir[index];
if(freq <0)freq=0;
if(offset_plus==0) disp_freq= freq + offset_temp;
else disp_freq= freq - offset_temp;
set_terminals();
DDS_data=28.6334085*freq; //DDS_data=設定値 28.6334082
data=(unsigned long)DDS_data; //data=DDS_dataを32ビット整数値に変換したもの
send_data();
if( (ex_freq - freq ) != 0 )
{
set_terminals();
locate(1,8);
set_comma( disp_freq ); //10MHzで、0.633mS費やす
lcd_write_str(result);
ex_freq = freq;
}
}
if( config_offset==1 )
{
offset_temp += multi[multi_pos] * dir[index];
set_comma( offset_temp ); //10MHzで、0.633mS費やす
set_terminals();
locate(1,8);
lcd_write_str(result);
}
}
}
void up_sw_pushed() // select multi
{
for(i=0;i<20000;i++); //チャタリング防止用
if( up ) return;
for(i=0;i<20000;i++); //チャタリング防止用
if( up ) return;
if(change_multi == 0)
{
set_terminals();
locate(2,9);
lcd_write_str(" ") ;
}
if( (function==0 ) || ( change_multi==1) )
{
if(multi_pos ==6) multi_rev_flag = 1;
if(multi_pos ==0) multi_rev_flag = 0;
if(multi_rev_flag) multi_pos--;
else multi_pos++;
set_terminals();
locate(2,1);
lcd_write_str( str_multi[multi_pos] );
if( function ==2 )
{
if(offset_plus==0) lcd_write_str("-");
else lcd_write_str("+");
}
}
while(!up);
}
void down_sw_pushed() //down_SWで、functionを決定する
{
for(i=0;i<20000;i++); //チャタリング防止用
if( down ) return;
for(i=0;i<20000;i++); //チャタリング防止用
if( down ) return;
if(function_select==1)function_select=0;
if( (function==0) && (release==1) )
{
release=0;
change_multi=0;
function_select=1;
freq=memory[0];
while(!down);
return;
}
if( (function==0) && (release==0) )
{
release=1;
freq=memory[0];
set_terminals();
lcd_clr(); //SGモード表示
locate(1,1);
lcd_write_str("SG ");
set_comma(freq ); //10MHzで、0.633mS費やす
locate(1,8);
lcd_write_str(result);
lcd_write_str(" Hz");
locate(2,1);
lcd_write_str( str_multi[multi_pos] );
while(!down);
return;
}
if( (function==1) && (release==1) )
{
release=0;
function_select=0;
function=0;
freq=memory[mem_pos];
set_terminals();
lcd_clr();
locate(1,1);
lcd_write_str("SG ");
set_comma(freq ); //10MHzで、0.633mS費やす
locate(1,8);
lcd_write_str(result);
lcd_write_str(" Hz");
locate(2,1);
lcd_write_str( str_multi[multi_pos] );
while(!down);
return;
}
if( (function==1) && (release==0) )
{
release=1;
str_mem_pos[0] = mem_pos+0x30;
set_comma(freq ); //10MHzで、0.633mS費やす
set_terminals();
lcd_clr();
locate(1,1);
lcd_write_str("Mem");
locate(1,4);
lcd_write_str(str_mem_pos);
locate(1,8);
lcd_write_str(result);
lcd_write_str(" Hz");
locate(2,1);
lcd_write_str( str_multi[multi_pos] );
while(!down);
return;
}
if( (function==2) && (change_multi==1) && (release==1) )
{
change_multi = 0; //config VFO mode 解除
release = 0;
function_select=1;
memory[mem_pos]=freq;
offset[mem_pos]=offset_temp;
function=0;
set_terminals();
lcd_clr();
locate(1,8);
set_comma(freq ); //10MHzで、0.633mS費やす
lcd_write_str(result);
lcd_write_str(" Hz");
locate(1,1);
lcd_write_str("SG ");
while(!down);
return;
}
if( (function==2) && (change_multi==1) && (release==0) )
{
config_offset=0;
release=1;
freq = offset_temp;
lcd_clr(); //VFOモード表示
str_mem_pos[0] = mem_pos+0x30;
set_terminals();
locate(1,1);
lcd_write_str(str_mem_pos);
locate(1,3);
lcd_write_str("VFO");
set_terminals();
locate(2,8);
set_comma( offset_temp );
lcd_write_str(result);
lcd_write_str(" Hz");
locate(2,7);
if(offset_plus==0) lcd_write_str("-");
else lcd_write_str("+");
set_comma(disp_freq); //ここ、何とかならんか?
locate(1,8);
lcd_write_str(result);
lcd_write_str(" Hz");
while(!down);
return;
}
if( (function==2) && (change_multi==0) && (config_offset==0) ) //offset config
{
config_offset=1;
change_multi=1;
former_freq=freq;
set_terminals();
locate(1,1);
lcd_write_str("ofs?");
freq = offset_temp;
set_comma(offset_temp);
locate(1,8);
lcd_write_str(result);
lcd_write_str(" Hz");
while(!down);
return;
}
}
void set_FastCLK(void)
{
prc0=1;
hra00=1;
cm06=0;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
hra01=1;
ocd2=1;
prc0=0;
}
//for AD9851
void set_terminals()
{
//出力に設定
pd1=0xFF;
pd3_3=pd3_4=pd4_5=1;
pd3_5=pd3_7=0; //for rotary encoder
//入力に設定 (ハードで、Pull_Upされている)
//pd4_6=pd4_7=0; 不要なり
}
void reset_DDS()
{
RESET=high; //RESET
for(i=0;i<13000;i++);
RESET=low;
W_CLK=high; //serial設定
W_CLK=low;
FQ_UD=high;
FQ_UD=low;
}
void send_data()
{
for(i=0;i<32;i++)
{
if(data & 0x01) D7=high;
else D7=low;
W_CLK=high;
W_CLK=low;
data=data >>1;
}
D7=high; //クロック6倍モード指定
W_CLK=high;
W_CLK=low;
D7=low; //logic 0
W_CLK=high;
W_CLK=low;
D7=low; //power down=no
W_CLK=high;
W_CLK=low;
for(i=0;i<5;i++) //位相制御 位相=0;
{
D7=low;
W_CLK=high;
W_CLK=low;
}
FQ_UD=high;
FQ_UD=low;
}
//for LCD
void initialize_LCD()
{
for(i=0;i<13000;i++); //21mS
p1=0x30; //DB7-4 0011
R_W=0;
RS=0;
E=1;
asm("nop"); //need 0.4uS OK? simulate 0.5uS OK
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
for(i=0;i<6300;i++); //10.2mS
p1=0x30; //DB7-4 0011
R_W=0;
RS=0;
E=1;
asm("nop"); //need 0.4uS OK? simulate 0.5uS OK
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
for(i=0;i<200;i++); //over 200uS
p1=0x30; //DB7-4 0011
R_W=0;
RS=0;
E=1;
asm("nop"); //need 0.4uS OK? simulate 0.5uS OK
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0; //set 8bit interface
busy_check();
p1=0x20; //DB7-4 0010
lcd_cmd(); //set interface to 4-bit
busy_check();
p1=0x20; //2lines 5x7 character Function set
lcd_cmd();
p1=0x80;
lcd_cmd();
busy_check();
p1=0x00; //Display off
lcd_cmd();
p1=0x80;
lcd_cmd();
busy_check();
p1=0x00; //clear Display
lcd_cmd();
p1=0x10;
lcd_cmd();
busy_check();
p1=0x00; //Entry mode set
lcd_cmd();
p1=0x60; //DB7-4=0110
lcd_cmd();
busy_check();
p1=0x00; //Display ON
lcd_cmd();
p1=0xC0; //DB7-4=1110 cursol off no blink
// p1=0xE0; //corsor on
lcd_cmd();
busy_check(); //cmdは、busy_checkして終わる事
}
void lcd_clr()
{
busy_check();
p1=0x00; //clear Display
lcd_cmd();
p1=0x10;
lcd_cmd();
busy_check();
}
void lcd_cmd()
{
R_W=0;
RS=0;
E=1;
asm("nop"); //need 0.4uS OK? simulate 0.5uS OK
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
}
void busy_check()
{
unsigned char test_bit=0;
pd1=0x0F; //port1 DB7-4 direction = read
check:
R_W=1; //read
RS=0;
E=1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
test_bit=p1; //上位ビットの取り込み
R_W=1; //read
RS=0;
E=1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
//p1=下位ビットは、取り込み だけで、使わない
test_bit=test_bit>>7;
if( test_bit ) goto check;
pd1=0xff; //p1 DB7-4 direction = write
}
void lcd_data( unsigned char c)
{
p1 = c; //上位送信
R_W=0;
RS=1;
E=1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
p1=(c<<4); //下位送信
R_W=0;
RS=1;
E=1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
E=0;
busy_check(); //check busy_check
}
void lcd_write_str(unsigned char* c)
{
pd1=0xff; //p1 DB7-4 direction = write
while(*c !=0x00)
{
lcd_data(*c);
c++;
}
}
void my_sprintf(unsigned long x)
{
char z_flag=1; //このフラグがゼロ以降は、空白に変わらないで数字のゼロを表示
//ここで、reverseされた 文字列が、出来上がる
for(i=0;i<10;i++)
{
*(str + i) = (x % 10) + 0x30;
x = x /10;
}
//ここで、上位のゼロを、空白に変える
for(i=0;i<10;i++)
{
if( *(str + 9 - i) != 0x30) z_flag=0;
if( (z_flag) && *(str + 9 - i) ==0x30 ) *(str + 9 -i) =0x20;
}
}
void set_comma(unsigned long x) //simulate=417uS
{
my_sprintf(x);
j=0;
for (i=0;i<10;i++)
{
*(result + 9 - j) = *(str + i);
if( ( (i % 3) == 2 ) && ( i !=0 ) && ( *(str + i+1) != 0x20) )
{
j++;
*(result + 9 - j) = '.';
}
j++;
}
}
void locate(unsigned char gyou ,unsigned char retsu)
{
char reserv_p1; // Eの為に、p1の下位の値が、狂う!
reserv_p1 = p1 = 0x80 + (gyou - 1)*0x40 + retsu-1 ;
lcd_cmd();
p1 = reserv_p1<<4;
lcd_cmd();
busy_check(); //必ずbusy_checkして終わる
}
void set_timerX()
{
//f8
txck0 = 1;
txmr = 0;
tx = 44;
prex = 44;
ilvl0_txic = 1;
ir_txic = 0;
}