#include #include #include #include "i2cmsu.h" #define DATA_EEMEM_PROTECT_DISABLE 0x0100 #define XT_OSC 0x0001 #define DISABLE_DEBUG 0x0800 #define CP0 0x1010 #define CP1 0x2020 /* CP0,CP1 code protect off*/ /* other bits zero which means WDT disabled Low Voltage prm disabled, brownout disabled power up timer enabled */ __CONFIG((CP1 | CP0) | DATA_EEMEM_PROTECT_DISABLE | XT_OSC | DISABLE_DEBUG); #define bitset(var,bitno) ((var) |= (1 << (bitno))) #define bitclr(var,bitno) ((var) &= ~(1 << (bitno))) #define bittst(var,bitno) (var & (1 << (bitno))) /* generates a sinewave using a 64 step or 16 step table */ /* Uses timer2 */ #define DAC 0x58 /* I2C DAC 01011000 */ #include "sinegen.h" /* the outer legs of the 10K pot should be hooked up between +5 and 0 */ /* the middle leg (wiper) connected to AN0 */ /* return 8 bit char from Recieve port */ char getch () { unsigned char c; /* while (!RCIF) */ while (!bittst(PIR1,5)); /* check RCIF bit */ c = RCREG; return(c); } /* send 8 bit char to Recieve port */ void putch (c) char c; { /* wait until transmit reg empty */ /* while (!TXIF) */ while (!bittst(PIR1,4)); /* check RCIF bit */ TXREG = c; } void pcrlf () { putch(0x0a); putch(0x0d); } int update_dac(unsigned char val) { i2c_WriteTo(DAC); i2c_PutByte(0x00); i2c_PutByte(val); i2c_Stop(); } char dac_value; char dac_flag; char pr_flag; #define MIN_PERIOD 25 #define MAX_PERIOD 100 // i2c clock freq = Fosc/4(SSPAD+1) // 100000(SSPPAD+1) = 3686400/4 // SSPAD = 8.2, use 8, will be close to 100 Khz /* assumes right justification, only returns most 7 bits, limits value between min_period and max_period */ update_period(){ unsigned char rval1,rval2; /* read ADC result, use as period, start new conversion */ rval2 = ADRESL >> 3; /* lose lower 3 bits */ rval2 = rval2 & 0x1f; /* mask upper 3 bits */ rval1 = ADRESH & 0x3; /* mask upper 6 bits */ rval1 = rval1 << 5; rval1 = rval1 | rval2; if (rval1 < MIN_PERIOD) rval1 = MIN_PERIOD; if (rval1 > MAX_PERIOD) rval1 = MAX_PERIOD; PR2 = rval1; /* set timer2 period register */ /* start new conversion */ bitset(ADCON0, 2); /* start conversion */ } unsigned char sineptr; unsigned char tabmax; void interrupt timer2_isr(void) { sineptr++; if (sineptr == tabmax){ sineptr = 0; pr_flag = 1; } dac_flag = 1; bitclr(PIR1,1); // TMR2IF = 0; clear timer interrupt flag } main(void) { char inchar; /* configure A/D inputs of PORT A to be all digital inputs */ ADCON1 = 0x8E; /* Port A analog input, right justification of result */ TRISA = 0xFF; /* all bits input */ /* setup Async communication */ bitclr(TXSTA, 6); /* 8-bit transmit */ bitset(TXSTA, 5); /* transmit enable*/ bitclr(TXSTA, 4); /* async mode */ bitset(TXSTA, 2); /* high speed mode */ #if 1 SPBRG = 95; /* 9600 in high baud rate mode, crystal = 14.7456 Mhz */ #endif bitset(TRISC, 7); /* serial port enable */ bitset(TRISC, 6); /* serial port enable */ bitset(RCSTA, 7); /* serial port enable */ bitclr(RCSTA, 6); /* 8-bit reception */ /* set baud rate */ bitset(RCSTA, 4); /* enable recieve */ ADCON0 = 0x80; /* sampling freq = Fsoc/32, channel 0 */ bitset(ADCON0,0); /* turn on ADC*/ printf("ADC is configured!!!"); pcrlf(); /* enable I2C */ SSPCON = 0x28; //Master mode //SSPADD = 8; // close to 100 Khz rate on i2c bus for 3.6864 Mhz //SSPADD = 1; // over 400Khz for 3.6864 Mhz SSPADD = 8; // about 400Khz for 14.7456 Mhz, verified to work //bitset(SSPSTAT,7); //disable slew rate control for 100 Khz bitset(SSPCON,5); //SSPEN = 1; bitset(SSPCON,4); //CKP = 1; bitset(TRISC,3); bitset(TRISC,4); // SDA, SCL pins are inputs pr_flag = 0; dac_flag = 0; sineptr = 0; tabmax = 16; printf("Enter '1' for 64 entry table, anything else chooses 16 "); inchar=getch(); pcrlf(); if (inchar == '1') tabmax = 64; /* start first conversion. At end of each cycle, do new conversion */ bitset(ADCON0, 2); /* start conversion */ while (bittst(ADCON0,2)); /* wait for end of conversion */ printf("First conversion "); pcrlf(); PR2 = MAX_PERIOD; if (tabmax == 16) update_dac(sine16tab[sineptr]); else update_dac(sine64tab[sineptr]); /* configure timer 2*/ /* post scale of 3 */ bitclr(T2CON, 6); bitclr(T2CON, 5); bitset(T2CON, 4); bitclr(T2CON, 3); /* pre scale of 4 */ bitclr(T2CON, 1); bitset(T2CON, 0); /* start timer 2 */ bitset(T2CON, 2); printf("Entered Loop "); pcrlf(); // enable interrupts bitclr(PIR1,1); // TMR2IF = 0; clear timer interrupt flag bitset(PIE1, 1) ; // enable timer2 interrupt TMR1IE = 1; bitset(INTCON,6); /* enable peripheral interrupts, PEIE */ bitset(INTCON,7); /* enable global interrupts, GIE */ for(;;) { if(dac_flag) { if (tabmax == 16) update_dac(sine16tab[sineptr]); else update_dac(sine64tab[sineptr]); dac_flag = 0; if (pr_flag) { update_period(); pr_flag = 0; } /* now write to DAC */ } } }