/* * File: si570-vfo-encoder.c * Author: Ramiro Aceves, EA4NZ * * Created on 20 de diciembre de 2013, 8:51 */ #include #include #include #include #include #pragma config FOSC = HS #pragma config PLLEN = ON //#pragma config CPUDIV = CLKDIV4 #pragma config CPUDIV = NOCLKDIV #pragma config USBDIV = OFF #pragma config WDTEN = OFF #pragma config MCLRE = ON #pragma config IESO = OFF #pragma config HFOFST = OFF #pragma config XINST = OFF #pragma config LVP = OFF #define MAX_FDCO_FREQ 5670.0 #define MIN_FDCO_FREQ 4850.0 #define FXTAL 114.242835695880 //#define FXTAL 114.327438 float FRECUENCIA=50.0; float DELTA=0.25; void write_si570_regs (float RFREQ, unsigned char HS_DIV, unsigned char N1); void prog_si570 (float FOUT); void interrupt pulsaboton(void){ Delay1KTCYx(40 ); if (RABIE && RABIF && PORTBbits.RB7==1 && PORTBbits.RB5==0){ FRECUENCIA=FRECUENCIA+DELTA; prog_si570 (FRECUENCIA); char x=PORTBbits.RB7; RABIF=0; return; } if (RABIE && RABIF && PORTBbits.RB7==0 && PORTBbits.RB5==0){ FRECUENCIA=FRECUENCIA-DELTA; prog_si570 (FRECUENCIA); char x=PORTBbits.RB7; RABIF=0; return; } char x=PORTBbits.RB7; RABIF=0; return; } void main (void) { TRISC=0b00000000; /*RC0-RC7 salidas*/ TRISB=0b11110000;/*RB6=SCL, RB4=SDA, RB7=RB5=INPUTs*/ WPUB= 0b10100000;/*RB7, RB5, WEAK PULLUP ENABLED*/ WDTCON=0x00;/*DESHABILITAR WATCHDOG*/ INTCON2=0b11110101; //INTCON2=0b01110101; /habilita los pullup ANSELH=0x00; PORTC=0b00000000;/*reset del puerto C*/ RABIE=1; IOCB7=1; //IOCB5=1; prog_si570 (FRECUENCIA); GIE=1; while(1){ Delay10KTCYx(255); } } void write_si570_regs (float RFREQ, unsigned char HS_DIV, unsigned char N1) { unsigned char Si570_REG_7; unsigned char Si570_REG_8; unsigned char Si570_REG_9; unsigned char Si570_REG_10; unsigned char Si570_REG_11; unsigned char Si570_REG_12; unsigned char Si570_REG_135; unsigned char Si570_REG_137; unsigned int entera_de_RFREQ; float decimal_de_RFREQ; unsigned long resto; unsigned char sync_mode; unsigned char slew; unsigned char add1; unsigned char w; unsigned char data; unsigned char status; Si570_REG_7=((HS_DIV-4) << 5) | ((N1-1) >> 2); entera_de_RFREQ = floor(RFREQ); Si570_REG_8= (((N1-1) << 6 ) | (entera_de_RFREQ >> 4)); decimal_de_RFREQ=RFREQ-entera_de_RFREQ; resto=floor(decimal_de_RFREQ *268435456); Si570_REG_9=((entera_de_RFREQ << 4) | (resto >> 24)); Si570_REG_10=(resto >> 16); Si570_REG_11=(resto >> 8); Si570_REG_12=(resto); sync_mode=MASTER; slew=SLEW_OFF; add1=0xAA; //Si-570 address 0x55*2 OpenI2C(sync_mode, slew); SSPADD=0x1D; //100kHz SCL clock @ 12 MHz IdleI2C(); //read 137 register for DCO freezze StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C((unsigned char) 137 ); IdleI2C(); RestartI2C(); IdleI2C(); WriteI2C( add1 | 0x01 ); IdleI2C(); Si570_REG_137=ReadI2C(); IdleI2C(); NotAckI2C(); IdleI2C(); StopI2C(); Si570_REG_137=(Si570_REG_137 | 0x10); //set bit 4 of 137 reg to freezze DCO IdleI2C(); //write 137 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char)137 ); IdleI2C(); WriteI2C(Si570_REG_137); IdleI2C(); StopI2C(); IdleI2C(); //write 7 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 7 ); IdleI2C(); WriteI2C(Si570_REG_7); IdleI2C(); StopI2C(); IdleI2C(); //write 8 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 8 ); IdleI2C(); WriteI2C(Si570_REG_8); IdleI2C(); StopI2C(); IdleI2C(); //write 9 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 9 ); IdleI2C(); WriteI2C(Si570_REG_9); IdleI2C(); StopI2C(); IdleI2C(); //write 10 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 10 ); IdleI2C(); WriteI2C(Si570_REG_10); IdleI2C(); StopI2C(); IdleI2C(); //write 11 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 11 ); IdleI2C(); WriteI2C(Si570_REG_11); IdleI2C(); StopI2C(); IdleI2C(); //write 12 register StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char) 12); IdleI2C(); WriteI2C(Si570_REG_12); IdleI2C(); StopI2C(); IdleI2C(); //read 137 register for DCO unfreezze StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char)137 ); IdleI2C(); RestartI2C(); IdleI2C(); WriteI2C( add1 | 0x01 ); IdleI2C(); Si570_REG_137=ReadI2C(); IdleI2C(); NotAckI2C(); IdleI2C(); StopI2C(); Si570_REG_137=(Si570_REG_137 & 0xEF); //clear bit 4 of 137 reg to freezze DCO IdleI2C(); StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char)137 ); IdleI2C(); WriteI2C(Si570_REG_137); IdleI2C(); StopI2C(); IdleI2C(); StartI2C(); IdleI2C(); WriteI2C( add1 | 0x00 ); IdleI2C(); WriteI2C( (unsigned char)135 ); // set bit 6 of 135 register for NewFreq to be applied IdleI2C(); WriteI2C( (unsigned char) 0x40 ); IdleI2C(); StopI2C(); return; } unsigned char check_and_prog(unsigned char HS_DIV,unsigned char N1, float FOUT) { float RFREQ; float FDCO; FDCO=FOUT * HS_DIV*N1; if ( (FDCO <= MAX_FDCO_FREQ) && (FDCO >= MIN_FDCO_FREQ) ) { RFREQ=(FDCO)/FXTAL; write_si570_regs (RFREQ, HS_DIV, N1); return 0; } return 1; } void prog_si570 (float FOUT) { unsigned char HS_DIV[6]={11,9,7,6,5,4}; unsigned char N1; unsigned char i; N1=1; for (i=0;i<=5;i++) { if(check_and_prog(HS_DIV[i],N1,FOUT)==0) return; } for (N1=2;N1<=128;N1=N1+2) { for (i=0;i<=5;i++) { if(check_and_prog(HS_DIV[i],N1,FOUT)==0) return; } } return; }