#include "P24FJ64GA004.h" // Prototyping unsigned int I2c_Read(void); void Bk1088_Write(unsigned int,unsigned int); unsigned int Bk1088_Read(unsigned int); void Set_Freq(unsigned int,unsigned int); //config _CONFIG2(0xF9FC); _CONFIG1(0x3F7F); unsigned int coldata[3]; unsigned int lcdstate; unsigned int AM_FREQ[] = {594,693,810,954,1134,1242,1422}; unsigned int FM_FREQ[] = {7710,8000,8130,8250}; unsigned int HW_RegAM[]= { 0x02,0x0281, 0x03,0x0004, 0x04,0x60C0, // REG4 /interrupt enable 0x05,0x1FDD, // 0x06,0x0930, 0x07,0x2901, 0x08,0xAC8C, 0x09,0x1093, 0x0a,0x402D, 0x0b,0x004B, 0x0c,0x0000, 0x0d,0x0000, 0x0e,0x0000, 0x0f,0x0000, 0x10,0x7B11,//16 0x11,0x0C00, 0x12,0x4000, 0x13,0x4344, 0x14,0x878E,//20 0x15,0x7812, 0x16,0x4000, 0x17,0x0B55,//23 0x18,0x341C,//24 0x1a,0x0001, 0x1b,0x48D4, 0x1c,0x0000, 0x1d,0x0200, 0x1e,0x80AA,//30 0x1f,0x0000,//31 0x20,0x0EF7, 0x21,0x0600, 0x22,0x0000, 0x23,0xF438,//35 0x24,0x0880, 0x25,0x8c06, // 0x26,0x8400, 0x27,0x0000, 0x28,0x4400,//40 0xff,0xffff, }; unsigned int HW_RegFM[]= { 0x02,0x0281, 0x03,0x0000, 0x04,0x60C0, //REG4 0x05,0x37DA, //REG5 0x06,0x086E, 0x07,0x0901, 0x08,0x9C90, 0x09,0x17A0, 0x0a,0x402B,//10 0x0b,0x0040, 0x0c,0x0000, 0x0d,0x0000, 0x0e,0x0000, 0x0f,0x0000,//15 0x10,0x7B11, 0x11,0x0800, 0x12,0x4000, 0x13,0x4144, 0x14,0x829A,//20 0x15,0x7812, 0x16,0x43BB, 0x17,0x0B41, 0x18,0x143C, // 0x19,0x000E,//25 0x1a,0x0000, 0x1b,0x48D4, 0x1c,0x0000, 0x1d,0x0200, 0x1e,0x80AA,//30 0x1f,0x0000, 0x20,0x0EF7, 0x21,0x0600, 0x22,0x0000, 0x23,0x7000,//35 0x24,0x0880, 0x25,0x8D83, 0x26,0x8000, 0x27,0x0000, 0x28,0x4400, 0xff,0xffff }; unsigned int HW_Reg[]= { 0x02,0x0281, //Power Configration ※bit0 = Power ON 0x03,0x8122, //*Channel 0x04,0x1180, //*Systen Configuration1 0x05,0x3f0f, //*5   System Configuration2 ※バンドとチャンネル間隔 0x06,0x01ef, //*5   System Configuration2 ※バンドとチャンネル間隔 76MHz+Ch*10 0x07,0x2900, //Test1 ※AM/FMの切り替えはここらしい 0x08,0xac90, //Test2 ※AFC関係? 0x09,0x1093, //Status1 ※AFC/SNRリード 0x0a,0x402d, 0x0b,0x004b, 0x0c,0x0000, //RDS1 0x0d,0x0000, //RDS2 0x0e,0x0000, //RDS3 0x0f,0x0000,//15  RDS4 0x10,0x7B11, //Boot Confirutation1 ※リザーブ機能? 0x11,0x0c00, //Boot Confirutation2 ※リザーブ機能? 0x12,0x4000, //Boot Confirutation3 ※リザーブ機能? 0x13,0x4344, //Boot Confirutation4 ※リザーブ機能(リセット値と違う) 0x14,0x878e,//20  Boot Confirutation5 ※ミュート設定らしい 0x15,0x7812, //Boot Confirutation6 ※リザーブ機能(リセット値と違う) 0x16,0x4000, //Boot Confirutation7 ※リザーブ機能(リセット値と違う) 0x17,0x0b55, //Boot Confirutation8 ※リザーブ機能(リセット値と違う) 0x18,0x341c, //Boot Confirutation9 ※リザーブ機能(リセット値と違う) 0x1a,0x0001, //Boot Confirutation11 ※リザーブ機能? 0x1b,0x48D4, //Analog Configuration1 ※リザーブ機能? 0x1c,0x0000, //Analog Configuration2 ※Clock Divider 0x1d,0x0200, //Analog Configuration3 ※Clock Divider control 0x1e,0x80AA,//30  ※以下(0x1E〜0x28)はテスト用レジスタで設定不要らしい 0x1f,0x0000, 0x20,0x0EF7, 0x21,0x0600, 0x22,0x0000, 0x23,0xf483,//35 0x24,0x0880, 0x25,0x8c06, 0x26,0x8400, 0x27,0x0000, 0x28,0x4400, 0xff,0xffff }; //main loop int main(void) { unsigned int i,j; lcdstate =0; //Setup clock OSCCON = 0x11C0; // FRCPLL CLKDIV = 0x0030; // 1MIPS SETTING //IO PORT SETTING AD1PCFG = 0xffff; // Analog input disable TRISA = 0x000f; // All output (Will be changed) TRISB = 0x0000; // All output TRISC = 0x0000; // All output PORTC = 0xffff; // INITIALIZE coldata[0] = 0;coldata[1] = 0;coldata[2] = 0; // タイマ1の設定  PR1 = 300; T1CON = 0b1000000000110000; IEC0bits.T1IE = 1; // タイマ1割り込み許可 Set_Num(0000); // 4桁で周波数を指定 Set_Band(1); // バンド指定 0=AM / 1=SW / 2=FM Wait_Time(100); Bk1088_Init(); while(1){ for (i=0;i<7;i++) { Set_Freq(0,AM_FREQ[i]); // AM選局 Wait_LongTime(1000); } for (i=0;i<4;i++) { Set_Freq(2,FM_FREQ[i]); // AM選局 Wait_LongTime(1000); } }; } //************* SUB ROUTINES ********* // BK1088 initialize void Bk1088_Init(void) { int i; i=0;HW_Reg[80]=0xff; while (HW_Reg[i] !=0xff) { Bk1088_Write(HW_Reg[i],HW_Reg[i+1]); i+=2; } i=0; while (HW_RegAM[i] !=0xff) { Bk1088_Write(HW_RegAM[i],HW_RegAM[i+1]); i+=2; } } //Display Set void Set_Freq(unsigned int band,unsigned int freq) { if (band ==0) { //AM mode MW522-1710KHz Bk1088_Write(0x05,0x1FDD); Bk1088_Write(0x07,0x2901); //AM mode Bk1088_Write(0x05,0x1FDD); Bk1088_Write(0x07,0x2901); //AM mode Bk1088_Write(0x0003,((freq-522)/9)); Bk1088_Write(0x0003,((freq-522)/9) | 0x8000); Set_Num(freq); // 4桁で周波数を指定 } if (band ==1) { //SW mode SW2.3-21.85MHz Bk1088_Write(0x05,0x1e5D); Bk1088_Write(0x07,0x2901); //AM mode Bk1088_Write(0x05,0x1e5D); Bk1088_Write(0x07,0x2901); //AM mode Bk1088_Write(0x0003,((freq-522)/9)); Bk1088_Write(0x0003,((freq-522)/9) | 0x8000); Set_Num(freq); // 4桁で周波数を指定 } if (band ==2) { //FM mode 76-91MHz Bk1088_Write(0x05,0x375d); Bk1088_Write(0x07,0x0901); //FM mode Bk1088_Write(0x05,0x375d); Bk1088_Write(0x07,0x0901); //FM mode Bk1088_Write(0x0003,(freq-7600)/10); Bk1088_Write(0x0003,((freq-7600)/10) | 0x8000); Set_Num(freq/10); // 4桁で周波数を指定 } Set_Band(band); // バンド指定 0=AM / 1=SW / 2=FM } // BK1088 Register access // Reg write void Bk1088_Write(unsigned int ad,unsigned int dt) { I2c_Start(); // start bit I2c_Write(0x0080); // Device ID I2c_Write(ad << 1); // Register address I2c_Write(dt>>8); // Register data H I2c_Write(dt & 0xff); // Register data L PORTCbits.RC8 = 1; // DATA =H Wait_Time(1); I2c_Stop(); // Stop bit } // Reg Read unsigned int Bk1088_Read(unsigned int ad) { unsigned int dtH,dtL; I2c_Start(); // start bit I2c_Write(0x0080); // Device ID I2c_Write((ad << 1) | 0x01); // Register address + Read flag dtH = I2c_Read(); // Register data read H I2c_Ack(); // ACK output dtL = I2c_Read(); // Register data read L I2c_Nack(); // NACK output I2c_Stop(); // Stop bit return ((dtH <<8) + dtL); } // software I2C RC8=DATA, RC9=CLK // I2C Start void I2c_Start(void){ TRISC = 0x0000; // All output Wait_Time(1); PORTCbits.RC8 = 0; // DATA =L Wait_Time(1); PORTCbits.RC9 = 0; // DATA& CLK = L Wait_Time(1); } // I2C Stop void I2c_Stop(void){ TRISC = 0x0000; // All output Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H Wait_Time(1000); } // I2C 8bit write and ACK void I2c_Write(unsigned int dt){ unsigned int i,wk; wk =dt; TRISC = 0x0000; // All output Wait_Time(1); for (i=0;i<8;i++) { PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); if((wk & 0x80)==0){PORTCbits.RC8 = 0;}else{PORTCbits.RC8 =1;} // data bit output wk <<=1; Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H Wait_Time(1); PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); } TRISC = 0x0100; // RC8 = input Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H Wait_Time(1); PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); TRISC = 0x0000; // RC8 = output } // I2C 8bit read unsigned int I2c_Read(void){ unsigned int i,wk; wk =0; TRISC = 0x0100; // DATA input for (i=0;i<8;i++) { wk <<=1; PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H if(PORTCbits.RC8 == 1){wk |= 1;} // data bit input Wait_Time(1); PORTCbits.RC9 = 0; // CLK = L } return(wk); } void I2c_Ack(void) { TRISC = 0x0000; // DATA output PORTCbits.RC8 = 0; // ACK output Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H Wait_Time(1); PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); } void I2c_Nack(void) { TRISC = 0x0000; // DATA output PORTCbits.RC8 = 1; // NACK output Wait_Time(1); PORTCbits.RC9 = 1; // CLK = H Wait_Time(1); PORTCbits.RC9 = 0; // CLK = L Wait_Time(1); } // NUMERIC SET 4桁の数字を一気にバッファにセットする void Set_Num(unsigned int num){ coldata[0] &= 0x0000;coldata[1] &= 0x0001;coldata[2] = 0xe000; Set_1digit(3,num/1000); Set_1digit(2,(num%1000)/100); Set_1digit(1,(num%100)/10); Set_1digit(0,num%10); } // BAND SET SW/AM/FM MHz/KHz/少数点 インジケータをセットする void Set_Band(unsigned int band){ if (band ==0) { coldata[2] &= 0x1ffe; coldata[0] &= 0x0924; coldata[0] |= 0x2001; // AM KHz 小数点以下なし coldata[1] &= 0x1ffe; } if (band ==1) { coldata[2] &= 0x1ffe; coldata[0] &= 0x0924;; coldata[0] |= 0x8010; // SW MHz 小数点以下2桁 coldata[1] |= 0x0001; } if (band ==2) { coldata[2] &= 0x1ffe; coldata[0] &= 0x0924; coldata[0] |= 0x0408; // FM MHz 小数点以下1桁 coldata[1] |= 0x0001; } } // NUMERIC SET 1桁の数字をセットするルーチン void Set_1digit(unsigned int col,unsigned int num){ unsigned int wk1,wk2,wk3; wk1 = 0;wk2=0;wk3=0; switch (num) { // 0-9す数字に合わせてセグメントデータを設定 case 0: wk3 =0x07;wk2=0x05;wk1=2;break; case 1: wk3 =0x01;wk2=0x01;wk1=0;break; case 2: wk3 =0x03;wk2=0x06;wk1=2;break; case 3: wk3 =0x03;wk2=0x03;wk1=2;break; case 4: wk3 =0x05;wk2=0x03;wk1=0;break; case 5: wk3 =0x06;wk2=0x03;wk1=2;break; case 6: wk3 =0x06;wk2=0x07;wk1=2;break; case 7: wk3 =0x03;wk2=0x01;wk1=0;break; case 8: wk3 =0x07;wk2=0x07;wk1=2;break; case 9: wk3 =0x07;wk2=0x03;wk1=2;break; deafult: break; } coldata[0]=coldata[0] | (wk1 << (col*3+1)); coldata[1]=coldata[1] | (wk2 << (col*3+1)); coldata[2]=coldata[2] | (wk3 << (col*3+1)); } // SEGMENT CONTROL ここでLCDを制御 void __attribute__((interrupt, auto_psv)) _T1Interrupt(void) { unsigned int wk; wk = coldata[lcdstate/2]; if ((lcdstate%2)==0) { PORTB = wk ^ 0xffff; // オンするセグメントを0Vにする PORTA = 0xffff; switch (lcdstate/2) { // Col選択 選択したColだけ1をドライブ(3V) case 0 : // それ以外はフロート(1.5V) TRISA = 0xfffe;break; case 1 : TRISA = 0xfffd;break; case 2 : TRISA = 0xfeff;break; default :break; } }else{ PORTB = wk; // オンするセグメントを3Vにする PORTA = 0x0000; // 選択したColを0Vに。それ以外は1.5Vのまま } lcdstate++; if (lcdstate>5) { lcdstate =0; } IFS0bits.T1IF = 0;// 割り込みフラグクリア } // WAIT LOOP 適当なウェイトルーチン void Wait_Time(unsigned int t) { int t0,t1; for (t0=0;t0