⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dds.c

📁 AD9850 DDS chip driver
💻 C
📖 第 1 页 / 共 2 页
字号:

// check if service mode start. SW1 pressed while start up

	if(SW1 == 0)
		{
		service_mode = 1;				// set service mode
		clear_lcd();
		putst("Service Mode");
		while(SW1 == 0)
			;
		}

// init operating variables from EEPROM

	read_eeprom_data();					// read defaults from EEPROM
	SIDEBAND = LSB;


// init irq system & timers

	Init_timers();						// init timers & irq system


// init DDS

	dds_init();						// init AD9850
	dds_load();						// do first load
	dds_load();						// test, start up problem

// start main process loop

	clear_lcd();						// start with clear screen

for (;;)
	{

#define MAX_NORMAL 4						// highest normal display mode number
#define MAX_DEBUG 8						// highest debug display mode number
#define CALMODE 6						// 125MHz calibration routine case

// do switches

	if(SW1 == 0 || SW3 == 0)				// select display mode
		{
		if(SW1 == 0)					// display mode up
			{
			delay(50);
			d_mode++;
			if(service_mode == 0)			// limit normal mode selections
				if(d_mode >= (MAX_NORMAL+1))
					d_mode = 1;
			else
				if(d_mode >= (MAX_DEBUG+1))	
					d_mode = 1;
			}

		if(SW3 == 0)		// display mode down
			{
			delay(50);
			d_mode--;
			if(d_mode < 1)
				{
				if(service_mode == 0)		// limit normal mode selections
					d_mode = MAX_NORMAL;
				else
					d_mode = MAX_DEBUG;
				}
			}

		clear_lcd();
		putst("Page ");
		putchhex(d_mode);
		delay(250);
		while(SW1 == 0 || SW3 == 0);			// show mode as long as pressed
			;
		clear_lcd();
		redraw = 1;
		if(d_mode == CALMODE)				// Calibration mode needs preparations
			{
			set_pw_data(eedata.caldata.osc_freq); 	// osc to pulse wheel
			step_idx = 0;
			f_step = f_steps[step_idx];		// 1 Hz step
			}
		delay(100);					// button debounce / repeat
		}

// do DDS load. Measured execution time 185us

	if(pw_ready && (d_mode != CALMODE))			// read pulse wheel if new data available
		{
		pw_ready = 0;
		redraw = 1;					// force redraw	
 
		dds.dds_regs.dds_freq = get_pw_data();
		dds_load();
		}


// measure ADC values or measure & calculate SWR

		if(TX == 0)
			{
			meas_swr();				// measure & calculate SWR if TX on
			}
		else
			{
			adc_ch0 = convert_adc(0);		// save ADC values for S-meter if RX
			adc_ch1 = convert_adc(1);
			oldpwr = 0;				// reset lag filter
			}


// do selected display page & functions

	switch (d_mode)
		{

		case 1:						// Main Frequency display
	LOOP_TEST = 1;				// test, measure loop performance. Measured 6ms RX, 12ms TX.
			redraw = 0;
			set_cur_lcd(LINE1);
			if(TX == 0)
				{
//				draw_bar((char)(fwdpwr/6), 0);	// forward power if TX on
				draw_bar((char)(oldpwr/6), 0);	// lag filtered total power if TX
				}				// show power bar graph 0 - 50 W, 500 / 6 = 83,3
			else
				{
				draw_s_meter((char)(adc_ch0/12)); 	// draw S-meter bar on RX
				}

			set_cur_lcd(LINE2);
			m1.m1l = dds.dds_regs.dds_freq;	  	// calculate display frequency
			m2.m2l = eedata.caldata.osc_freq; 	// f = (pw_data*osc_freq)/2^32
			vlmul();			  	// do JNi 32*32 multiplication
			putlongdec((prod.prodlng.prodhi >> 2), 1);  // use hi-part = divided 2^32 / 4
			putst(" Hz ");

			if(TX == 0)
				{
				putst("TX");			// show TX-status
				}
			else
				{
				if(SIDEBAND == LSB)		// show sideband
					putch('L');
				else
					putch('U');

				put1hex(step_idx);		// show DDS tuning step
				}
	LOOP_TEST = 0;	

			freq_step_adj();			// addjust freq step	
			break;



		case 2:						// Sideband select on RX
			if(TX == 0)
				{				// SWR & power display on TX
				set_cur_lcd(LINE1);
				putst("Fwd");
				putintdec(fwdpwr, 1);
				putst(" R");
				putintdec(revpwr, 1);

				set_cur_lcd(LINE2);
				putst("P");
				putintdec(peak_power, 1);

				putst(" SWR");
				if(peak_swr != 0)
					{
					putintdec(peak_swr, 2);
					putch(' ');
					}
				else
					putst(" -.-- ");	
				}
			else						// if RX show S-meter & sideband select
				{
				set_cur_lcd(LINE1);
				draw_s_meter((char)(adc_ch0/12)); 	// draw S-meter bar on RX

				set_cur_lcd(LINE2);

				if(SW2 == 0)
					{
					SIDEBAND = !SIDEBAND;		// change sideband
					delay(250);	
					}
				
				putst("Sideband=");
				if(SIDEBAND == LSB)			// test sideband selector
					putst(" LSB   ");
				else
					putst(" USB   ");
				}

			break;


		case 3:					// Back light DAC or I/O bit
			set_cur_lcd(LINE1);			
			putst("Back Light Set");
			set_cur_lcd(LINE2);		// print setting
			putst("   ");
#ifdef __A_TYPE
			putintdec(dac, 0);		// if 877A DAC
#else
			if(BL)
				putst("On  ");		// if 877 on/off control
			else
				putst("Off ");
#endif

			if(SW2 == 0)			// adjust back light with SW2
				{
#ifdef __A_TYPE
				dac++;			// addlust DAC if we have 877A chip
				if(dac > 16)
					dac = 0;
				set_bl(dac);
#else
				BL = !BL;		// else on / off toggle
#endif
			set_cur_lcd(LINE2);		// reprint after setting
			putst("   ");
#ifdef __A_TYPE
			putintdec(dac, 0);		// if 877A DAC
#else
			if(BL)
				putst("On  ");		// if 877 on/off control
			else
				putst("Off ");
#endif
				delay(250);		// button debounce / repeat
				}

			break;


		case 4:							// store in use operating values to EEPROM 
			set_cur_lcd(LINE1);				// need more thinking
			putst("Store Defaults");
			set_cur_lcd(LINE2);				
			putst("SW2 = Write");
			if(SW2 == 0)
				{
				d_mode = DEF_MODE;			// do this while better ideas appears
				write_eeprom_data();
				clear_lcd();
				putst("Write EEPROM");
				set_cur_lcd(LINE2);				
				putst("Ok.");
				delay(250);
				delay(250);
				delay(250);
				while(SW2 == 0)
					;
				delay(250);
				}
			break;


/* service mode displays & commands */

		case 5:						// load JNi "factory defaults" 
			set_cur_lcd(LINE1);
			putst("Factory Setup ?");
			set_cur_lcd(LINE2);				
			putst("SW2 = Load");
			if(SW2 == 0)
				{
				d_mode = DEF_MODE;		// do this while better ideas appears
				redraw = 1;
				load_defaults();
				write_eeprom_data();
				clear_lcd();				
				putst("Ok.");
				delay(250);
				delay(250);
				delay(250);
				while(SW2 == 0)
					;
				delay(250);
				}
			break;

		case 6:						// Calibrate 125MHz Oscilator 
			set_cur_lcd(LINE1);
			putst("Calibrate SW2");
			set_cur_lcd(LINE2);
			eedata.caldata.osc_freq = get_pw_data(); // addjust oscilator frequency setting	
			putlongdec(eedata.caldata.osc_freq, 0);
			putst(" Hz");

			if(SW2 == 0)
				{
				write_eeprom_data();		// save everything
				d_mode = DEF_MODE;		// return to normal mode
				set_pw_data(dds.dds_regs.dds_freq); // restore display freq
				redraw = 1;
				clear_lcd();				
				putst("Ok.");
				delay(250);
				delay(250);
				delay(250);
				while(SW2 == 0)
					;
				delay(250);
				}
			break;


		case 7:						// S-meter test display
			set_cur_lcd(LINE1);
			putst("AD ");
			putintdec(adc_ch0, 0);	// test
			putintdec(adc_ch1, 0);

			if(SW2 == 0)
				{
				SIDEBAND = !SIDEBAND;		// change sideband
				delay(250);	
				}

			if(SIDEBAND == LSB)			// test sideband selector
				putst("  LSB");
			else
				putst("  USB");


			set_cur_lcd(LINE2);
//			draw_s_meter((char)(adc_ch0/12));
			draw_bar((char)(adc_ch0/12), 0);	// draw meter bar

			break;

		case 8:						// DDS raw set value display

			set_cur_lcd(LINE1);
//			putchhex(step_idx);

			putchhex(pw_sample);	// pulse wheel test
			putch(' ');
			putchhex(PORTB & 7);	// pulse wheel test
			putch(' ');

			putlongdec(f_step, 0);

			set_cur_lcd(LINE2);

			putchhex(pw_state);	// pulse wheel test
			putst(" ");				

//			putst("N  ");
			putlongdec(dds.dds_regs.dds_freq, 0); // display DDS set value

			freq_step_adj();			// addjust freq step
			break;


		default: case 0:
			d_mode = 1;			// push to available displays range
			break;
		}

/* PC control interface */

	if(keypressed() == 1)				// Note ! code can be locked here !
		{					// all started commands must be completed

		set_cur_lcd(LINE2+14);			// write PC interface activity indicator to LCD
		if(d_mode == 1 || d_mode == 2)		// only in main RX / TX displays
			putst("PC");			// if PC stays on LCD command is not completed and rig is "locked"
		
		switch (sio_getch())
			{

			case 'f':			// read frequency
			sio_putlongdec((prod.prodlng.prodhi >> 2), 1);
			break;

			case 'd':			// read DDS set value
			sio_putlongdec(dds.dds_regs.dds_freq, 0);
			break;

			case 'D':			// set DDS set value
			dds.dds_regs.dds_freq = getlong(); // Note ! you can get stuck here if not completed
			set_pw_data(dds.dds_regs.dds_freq); // set also pulse wheel data
			dds_load();			// set dds
			break;

			case 's':			// read DDS step value
			sio_putlongdec(f_step, 0);
			break;

			case 'S':			// set DDS step value
			f_step = getlong(); 		// Note ! you can get stuck here if not completed
			break;

			case '+':			// step VFO up
			ltemp = get_pw_data() + f_step;
			if(ltemp > MAX_DDS)
				ltemp = MAX_DDS;
			set_pw_data(ltemp);
			pw_ready = 1;			// set data available flag
			break;

			case '-':			// step VFO down
			ltemp = get_pw_data() - f_step;
			if(pw_data < MIN_DDS)		// cut to limits
				pw_data = MIN_DDS;
			set_pw_data(ltemp);
			pw_ready = 1;			// set data available flag
			break;

			case 'p':			// A/D (S-meter & Fwd power value 0-1023)
			sio_putintdec(adc_ch0, 0);
			break;

			case 'r':			// A/D (Rev power value 0-1023)
			sio_putintdec(adc_ch1, 0);
			break;

			case 'b':			// read status bits. b0=usb, b1=tx
			dly = 0;			// collect & assemble status bits
			if(SIDEBAND == 1)
				dly = dly + 1;
			if(TX ==0)
				dly = dly + 2;
			sio_putchdec(dly);
			break;

			case 'B':			// set status bits. b0=sideband select
			dly = sio_getch();		// Note ! you can get stuck here if not completed
			if((dly & 1) == 1)
				SIDEBAND = 1;
			else
				SIDEBAND = 0;
			break;


			case 'o':			// read oscilator calibration value
			sio_putlongdec(eedata.caldata.osc_freq, 0);
			break;

			case 'O':			// set oscilator calibration value
			eedata.caldata.osc_freq = getlong(); // Note ! you can get stuck here if not completed
							// write calibration data, E-command must be send separatelly
			break;

			case 'h':			// HEX dump EEPROM calibration values
			dump_eeprom();
			break;


/* debug commands */
			case 'c':
			sio_putst("\nChecksum: ");
			sio_putchhex(calc_csum());
			break;

			case 'E':
			write_eeprom_data();
			break;

			case 'e':
			read_eeprom_data();
			break;

			}

		sio_putst("\n");			// terminate every response with cr, lf
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -