|
楼主 |
发表于 2013-7-7 02:20:52
|
显示全部楼层
the code, as it stands now:
- //16F684 controller for ebay AD9850 module
- //connection:
- //AN0: analog voltage input, selects output band;
- //AN1: analog voltage input, controls output frequency (when not in the scanning mode)
- //PORTA3: digital pull-up/down: up: scanning (default). down: user selectable output frequency (per AN1)
- //PORTA2: to AD9850 WCLK
- //PORTA4: to AD9850 FQ_UD
- //PORTA5: to AD9850 SDATA
- //history:
- //v1.0 / 6/25/2013: first run.
- //v1.1 / 6/26/2013: clean up the code, adding banner display
- //v1.2 / 6/29/2013: revised the band definitions
- //v1.3 / 7/5/2013: fixed lower limit for SW7; swapped BAND_ADC and FREQ_ADC pins for easier lay-out
- #include <htc.h> //we use picc
- #include <string.h> //we use strcpy
- #include "gpio.h"
- #include "config.h" //configuration words
- #include "delay.h" //we use software delay
- #include "ad9850.h" //we use ad9850
- #include "adc.h" //we use hardware adc
- #include "lcd_4bit.h" //we use the lcd module, in 4-bit mode
- #include "misc.h" //we use ultoa()
- //hardware configuration
- //scan switch
- #define SCAN_PORT PORTA
- #define SCAN_DDR TRISA
- #define SCAN_PIN (1<<3) //scan switch on gpio3. 1->output set frequency. 0-> scan
- #define IS_SCAN(pin) IO_GET(SCAN_PORT, pin) //return 1 if pin is high (in scanning mode), weak pull-up default to on
- //freq pot
- #define FREQ_ADC ADC_AN0 //frequency pot on adc_an0
- #define BAND_ADC ADC_AN3 //band adc on adc_an3
- #define FREQ_STEP 1023 //how many steps in a band
- #define FREQ_INC 20 //increments for freq in the sweep / scan mode
- //#define FREQ_DLY 20 //delays per step, not used
- #define N_BANDS 14 //number of bands
- //hardware configuration
- //global define
- typedef struct {
- unsigned char str[17]; //string to be displayed, for 16x2 lcd
- unsigned long fstart, fend; //starting and ending frequencies
- //unsigned char threshold; //band threshold
- unsigned char dly; //delay in each step, in ms
- } BAND_T;
- //global variable
- //frequency bands
- const BAND_T freq_bands[N_BANDS]={
- //Fstart, Fend, DLY, /*THRESHOLD*/.
- {"IF0:435 - 485Khz", 455000ul - 20000ul, 465000ul + 20000ul, 0}, //455K/465K IF scan, +/- 20Khz bandwidth. default output if BAND_ADC is grounded
- {"IF1:10.6-10.9Mhz", 10700000ul - 100000ul, 10700000ul + 100000ul, 0}, //FM if scan, +/- 100Khz bandwidth
- {"AF : 1 - 20Khz", 1, 20000, 10}, //audio frequencies
- {"RF-: 10 - 600Khz", 10000ul, 600000ul, 10}, //sub RF (LW band)
- {"LW :153 - 279Khz", 153000ul, 279000ul, 10}, //LW band
- {"AM :500 -1700Khz", 500000ul, 1700000ul, 10}, //am broadcast band
- {"SW1:1500-2300Khz", 1500000ul, 2300000ul, 10}, //1.5Mhz - 2.3Mhz,
- {"SW2:2100-3200Khz", 2100000ul, 3200000ul, 10}, //2.1Mhz - 3.2Mhz. 120m band
- {"SW3:3100-4600Khz", 3100000ul, 4600000ul, 10}, //3.1Mhz - 4.6Mhz. 90m and 75m bands
- {"SW4:4500-6700Khz", 4500000ul, 6700000ul, 10}, //4.5Mhz - 6.7Mhz. 60m and 49m bands
- {"SW5:6600-9600Khz", 6600000ul, 9600000ul, 10}, //6.6Mhz - 9.6Mhz. 41m and 31m (partial) bands
- {"SW6:9.3 -14.0Mhz", 9300000ul, 14000000ul, 10}, //9.3Mhz - 14.Mhz. 31m, 25m and 22m bands - may want to split this further
- {"SW7:13.0-20.0Mhz", 13000000ul, 20000000ul, 10}, //13.Mhz - 20.Mhz. 22m, 19m, 16m, 15m bands - may want to split this further
- {"RF :0.5 -20.0Mhz", 500000ul, 20000000ul, 10} //rf band, default if band pin is pulled high
- //{465000ul - 20000ul, 465000ul + 20000ul, 300}, //465K if scan, +/- 20Khz bandwidth
- };
- //lcd strings
- const unsigned char str0[]="AD9850 SigGen1.2";
- const unsigned char str1[]="f= Hz";
- unsigned char vRAM[17]; //display buffer
- unsigned long freq_prev=0; //previous frequency
- unsigned char band=0; //band to tune
- unsigned char mode=1; //mode. 0=output to a set frequency. 1=scan
- unsigned long freq; //output frequency
- unsigned long freq_step; //frequency step, major
- //unsigned long freq_minor; //frequency step, minor
- //read the band setting
- unsigned char adc_band(void) {
- unsigned char i;
- unsigned char tmp;
-
- tmp=adc_read(BAND_ADC)>>2; //read band, as unsigned char
- for (i=1; i<N_BANDS; i++)
- if (tmp < /*freq_bands[i].threshold*/((unsigned short) i<<8) / N_BANDS) return i-1;
- return N_BANDS-1; //default is 0
- }
- //read the frequency / step from a pot
- unsigned short adc_freq(void) {
- return adc_read(FREQ_ADC);
- //return 200; //for debugging purposes only
- }
- //output a frequency
- void out_freq(void) {
- static unsigned char band_prev=0xff; //previous band
- static unsigned char mode_prev=0xff; //previous mode.
- static unsigned short step_current=0; //current step, major
- //static unsigned short step_minor=0; //current step, minor
- static unsigned long freq_prev=0; //previous output frequency
-
- if (band ^ band_prev) { //has band changed?
- freq_step = (freq_bands[band].fend - freq_bands[band].fstart) >> 10; //calculat the frequency steps
- freq_prev = 0; //reset previous frequency
- band_prev = band; //update band_prev
- //update the display
- strcpy(vRAM, freq_bands[band].str);
- lcd_display(LCD_Line0, vRAM);
- }
-
- if (!mode) { //output a set frequency
- step_current = adc_freq(); //read the steps
- } else { //output a scan
- step_current=(step_current >= FREQ_STEP)?0:(step_current+FREQ_INC); //increment steps
- }
- //generate the next frequency
- freq = freq_bands[band].fstart + freq_step * step_current;
- if (freq ^ freq_prev) {
- ad9850_freq(freq); //output the frequency
- freq_prev = freq; //update freq_prev
- }
-
- delay_ms(freq_bands[band].dly); //waste some time
- }
- void mcu_init(void) { //initialize the mcu
- ANSEL = 0x00; //porta are digital io
- //ANSELH = 0x00; //all portB is digital io
- CMCON0 = 0x07; //analog comparators off
- IRCF2=1, IRCF1=1, IRCF0=0; //running at 4Mhz
-
- //enable weak pull-up
- //RAPU = 0; //enable weak pull-up on porta
- //WPUA = 0xff; //enable weak pull-up on all pins
- //scan pin as input
- //not necessary on 12f675 as gpio3 is only input capable
- IO_IN(SCAN_DDR, SCAN_PIN);
- //initialize frequency step
- freq_step = ((freq_bands[band].fend - freq_bands[band].fstart) >> 10); //calculat the frequency steps
- }
- //main program
- int main(void) {
- //unsigned short i;
- //unsigned long freq;
- //static unsigned short count=0;
- mcu_init(); //initialize the mcu
- adc_init(); //reset the adc module
- lcd_init(); //reset the lcd
- strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM); //display the signon message
- delay_ms(1000); //wait for a short while to display the sign-on message
- //strcpy(vRAM, str1); //prepare line1
- //ultoa_s(&vRAM[2], freq, 10); //convert freq, with ','
- //lcd_display(LCD_Line1, vRAM); //display line1
-
- ad9850_init(); //reset ad9850
- //ad9850_freq(AD9850_1Khz); while (1);
- //mode = 1; //defaults to scan
- //band = N_BANDS-1; //default band, 455k IF
- while (1) {
- band=adc_band(); //read the band setting
- mode=IS_SCAN(SCAN_PIN); //1 for fixed frequency and 0 for scanning
- out_freq(); //output the frequency
- if (freq ^ freq_prev) { //frequency has changed -> update the display
- freq_prev=freq; //update the frequency
- strcpy(vRAM, str1); //prepare line1
- ultoa_s(&vRAM[2], freq, 12); //convert freq, with ','
- lcd_display(LCD_Line1, vRAM); //display line1
- }
- }
- }
复制代码 |
|