/************************************************************** PIC18F PLL control PLL device : TC9256P (Toshiba Co.) 7.200MHz(Xtal) / 720(preset prescaler) = 10KHz(minimam step) PIC: PIC18F14K50 16MHz Internal Clock Oscillator 2010.01.15 origin www.henteko.org ***************************************************************/ #include #include #include #include #include "lcd.h" #pragma config FOSC = IRC #pragma config WDTEN = OFF #pragma config FCMEN = OFF #pragma config PWRTEN = ON #pragma config BOREN = OFF #pragma config BORV = 30 #pragma config LVP = OFF #pragma config MCLRE = OFF #define PLL_CLOCK LATCbits.LATC3 // TC9256P clock #define PLL_DATA LATAbits.LATA4 // TC9256P data #define PLL_LE LATAbits.LATA5 // TC9256P le #define STEP_LED LATCbits.LATC2 // frequency step #define EEPROM 0x0000 // EEPROM address #define MAX_FREQ 9000 // VCO max frequency #define MIN_FREQ 6500 // VCO min frequency unsigned char tmp[10]; // lcd output srting unsigned int pcd; // frequency unsigned int diff; // frequency step unsigned char renc_now, renc_old; // value of rotary encoder unsigned int mem; // memory channel unsigned char mode; // 1:memory mode 0:VFO mode /*************************************************************** ms step delay (This is doubtful. ^^;) ***************************************************************/ void delay_ms(unsigned int t) { for(; t > 0; t--) // 16MHz clock Delay1KTCYx(4); // 1ms: 0.001 / ((1 / (16000000 / 4)) * 1000) = 4 } /*************************************************************** TC9256P serial control (LSB first) ***************************************************************/ void pll_dataset(unsigned long data, unsigned int bt) { unsigned int i; unsigned int p; PLL_LE = 0; for(i = 0; i < bt ; i++) { p = (data >> i) & 0x00000001; if(p % 2) PLL_DATA = 1; else PLL_DATA = 0; Delay10TCYx(1); PLL_CLOCK = 0; Delay10TCYx(1); PLL_CLOCK = 1; Delay10TCYx(1); if(i == 2) PLL_LE = 1; } Delay10TCYx(1); PLL_LE = 0; Delay10TCYx(1); PLL_LE = 1; } /*************************************************************** EEPROM write ***************************************************************/ void eeprom_write(unsigned int adr, unsigned int data) { unsigned char i; for(i = 0; i < 2; i++) { Write_b_eep(EEPROM + adr * 2 + i, (unsigned char)((data >> i * 8) & 0x00ff)); Busy_eep(); } } /*************************************************************** EEPROM read ***************************************************************/ unsigned int eeprom_read(unsigned int adr) { unsigned int d; d = Read_b_eep(EEPROM + adr * 2 + 1); return (d << 8)+ Read_b_eep(EEPROM + adr * 2); } /*************************************************************** interrupt ***************************************************************/ #pragma interrupt isr #pragma code isrcode = 0x8 void isr_direct(void) { _asm goto isr _endasm } #pragma code void isr(void) { if(INTCONbits.RABIF) { if(PORTBbits.RB6 == 1){ if(PORTBbits.RB5 == 0) renc_now = 0; else renc_now = 1; } else { if(PORTBbits.RB5 == 1) renc_now = 2; else renc_now = 3; } if((renc_now + 3 + 1) % 3 == renc_old) { if(mode == 0) { if(pcd > MIN_FREQ) { pcd -= diff; } } else { if(mem > 0) mem -= 1; } } if((renc_now + 3 - 1) % 3 == renc_old) { if(mode == 0) { if(pcd < MAX_FREQ) { pcd += diff; } } else { if(mem < 20) mem += 1; } } renc_old = renc_now; if(mode == 1) { pcd = eeprom_read(mem); if(pcd > MAX_FREQ || pcd < MIN_FREQ) pcd = 8000; } INTCONbits.RABIF = 0; pll_dataset(0xd0 + ((unsigned long)pcd<<8) + ((unsigned long)0x9a<<24), 32); } } /*************************************************************** main ***************************************************************/ void main(void) { unsigned char sw0_state, sw1_state; unsigned int freq, ftmp; unsigned int tim; OSCCON = 0b01111111; TRISA = 0b00000000; // RA4,5 TC9256P serial control TRISB = 0b11110000; // RB4,7 sw input RB5,6 rotary encoder input TRISC = 0b00000000; // LCD and RC2 frequency step status led ADCON0bits.ADON = 0; // ad converter off ANSELHbits.ANS10 = 0; // RB4 digital input ANSELHbits.ANS11 = 0; // RB5 digital input INTCONbits.RABIE = 1; // PortA,B pin change interrupt enable INTCON2bits.RABPU = 0; // PortA,B pull-up enable INTCON2bits.RABIP = 0; // PortA,B interruput priority low WPUB = 0b11110000; // RB4-7 pull-up IOCBbits.IOCB5 = 1; // RB5 pin change interrupt enable IOCBbits.IOCB6 = 1; // RB6 pin change interrupt enable INTCONbits.GIE = 1; // general interrupt enable lcd_init(); lcd_cls(); mode = 0; mem = 0; pcd = 8000; diff = 1; STEP_LED = 0; pll_dataset(0xd0 + ((unsigned long)pcd<<8) + ((unsigned long)0x9a<<24), 32); while(1){ if(PORTBbits.RB4 == 0) { sw0_state = 1; delay_ms(10); tim++; } if(sw0_state && PORTBbits.RB4 == 1) { sw0_state = 0; tim = 0; if(mode == 0) { mode = 1; ftmp = pcd; pcd = eeprom_read(mem); if(pcd > MAX_FREQ || pcd < MIN_FREQ) pcd = 8000; } else { mode = 0; pcd = ftmp; } pll_dataset(0xd0 + ((unsigned long)pcd<<8) + ((unsigned long)0x9a<<24), 32); } if(tim > 10) { // RB4の長押し sw0_state = 0; tim = 0; if(mode == 0) { eeprom_write(mem, pcd); sprintf(tmp, "VFO->MEM"); } else { pcd = eeprom_read(mem); if(pcd > MAX_FREQ || pcd < MIN_FREQ) pcd = 8000; sprintf(tmp, "MEM->VFO"); mode = 0; } lcd_gotopos(0, 1); lcd_putstr(tmp); pll_dataset(0xd0 + ((unsigned long)pcd<<8) + ((unsigned long)0x9a<<24), 32); while(PORTBbits.RB4 == 0); } if(PORTBbits.RB7== 0) { sw1_state = 1; delay_ms(10); } if(sw1_state && PORTBbits.RB7 == 1) { sw1_state = 0; if(diff == 1) { diff = 10; STEP_LED = 1; } else { diff = 1; STEP_LED = 0; } } lcd_gotopos(0, 1); if(mode == 0) sprintf(tmp, "VFO M:%02d", mem); else sprintf(tmp, "MEM M:%02d", mem); lcd_putstr(tmp); freq = pcd * 0.01; sprintf(tmp, "%d.%02dMHz", freq, (int)(pcd - (freq * 100))); lcd_gotopos(0, 0); lcd_putstr(tmp); } }