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

📄 setup.c

📁 关于无传感器BLDC使用DSPIC现实的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		config_value &= 0xF0FF;
		config_value |= 0x0400;
		// Write the new config value into F80004
		WriteConfig(4,config_value);
	}
	// Now clear off any pending PWM or FLT interrupts due to config
	IFS2bits.PWMIF = 0;
	IFS2bits.FLTAIF =0;						
	return;
}

void setup_adc(void)
{
	// ADCON1 - ADC Control Regsiter#1
	// Bit 15 1=ADC Is On,0 = Off NB This bit should be set to turn on
	//		  the module after all other configuration bits are set.
	// Bit 14 - Not Implemented
	// Bit 13 1=Discontinue in IDLE, 0 = continue
	// Bits12-10 - Not Implemented
	// Bits9-8 - Output Data Formatting
	// 11 = Signed Fraction, 10 = Fractional
	// 01 = Signed Integer, 00 = Integer
	// Bits7-5 - Conversion Trigger Source
	// 111 = Internal counter ends sample and starts conversion
	// 110
	// :::
	// 100 = Reserved
	// 011 = Motor Control PWM Trigger ends sample and starts convert
	// 010 = TIMER3 compare ends sampling and starts conversion
	// 001 = INT0 transition ends sampling and starts conversion
	// 000 = Clearing Bit1 ends sampling and starts conversion
	// Bit4 - Not Implemented
	// Bit3 - Simulataneous Sample Select
	// See manual for details
	// Bit2 - 1 = Sampling begins immediately after last conversion complete
	// 		  0 = Sampling begins when Bit 1 (SAMP) set
	// Bit1 - See Manual
	// Bit0 - 1 = AD conversion cycle in progress, 0 = finished(Read),abort (write)
	
	ADCON1 = 0x006F; // Use PWM Trigger, continuous simulatenous sampling
	
	// ADCON2 - ADC Control Regsiter#2
	// Bits15-13 Voltage Reference Config
	// See Manual for details 000=AVdd/AVss used
	// Bit12 - Reserved but need to write 0
	// Bit11 - Not Implemented
	// Bit10 - Scan input Selection for CH0 S/H input
	// 		   1=scan inputs, 0 = don't scan
	// Bits9-8 S/H Channels used per sample
	//		   1x = All 4, 01 = CH0&1, 00 = CH0
	// Bit7 - Buffer Fill Status (when buffer into 2x8 words)
	//		  1=ADC filling 8-F, 0= ADC filling 0-7
	// Bit6 - Not Implemented
	// Bits5-2 No Sample/Convert Sequences / interrupt
	// 1111 = 16 sequences
	// ::::
	// 0000 = every sequence
	// Bit1 - 1=Results Buffer = 2x8,0 = 1x16
	// Bit0 - 0=Use MUXA settings, 1=Alternate MUXA & B starting with A
	
	ADCON2 = 0x0200; // Use Avdd/Avss, 4 samples, don't scan, 1 sequence/interrupt
							//Use MuxA settings
	
	// ADCON3 - ADC Control Regsiter#3
	// Bits15-13 - Not Implemented
	// Bits12-8 - Auto Sample Time Bits
	// 11111 = 31 TAD
	// :::::
	// 00000 = 0 TAD
	// Bit7 - 0=ADC Clock Derived from System, 1=ADC RC clock
	// Bit6 - Not Implemented
	// Bit5-0 ADC Conversion Clock
	// 111111 = 32 Tcy
	// ::::::
	// 000001 = Tcy
	// 000000 = Tcy/2

	ADCON3 = 0x0003; // Not using auto sample, system clock of 2Tcy
						  // giving 271ns Tad with 7.3728Mhz X4 PLL
						  // This gives approx 3us conversion time
	
	// ADCHS - A/D Input Select Register
	// See Manual For Details
	// Bits15-8 Are for MUXB
	// Bits7-0 Are for MUXA
	// If just doing single sample using channel 0
	// then can write channel number corresponding
	// to AN pin directly to ADCHS.
	
	ADCHS = VPH_RED; //MUXB not used, MUXA-ve=Vss,+ve=AN0-2 for CH1-3
						  //CH0 -ve=Vss +ve=AN12
	
	// ADPCFG - ADC port configuration register
	// Bits15-0 1=Digital, port read enabled, ADC Mux input=AVss
	//			0=Analogue, port read disabled, ADC samples pin
	
	ADPCFG = 0x8000; //AN15 used as OCFB digital pin
						  //For the moment assume that AN0,1 are used for ICD
						  //All other analogue channels

	// ADCSSL - ADC Scan Select Regsiter
	//	Bits15-0 - 1=ANx is selected for scan
	//				- 0=ANx is not selected for scan

	ADCSSL = 0x7020; //AN5, AN12-14 selected for scan

	// Clear Off Any Interrupt Due To Configuration
	IFS0bits.ADIF = 0;
	// Turn on ADC Module
	ADCON1bits.ADON=1;
	return;	
}

void setup_qei(void)
{

	// QEICON - QEI Control Register
	// Bit15 - 1=Position Error Count Has Occurred
	// Bit14 - Unused
	// Bit13 - 0=QEI Continues in idle, 1=discontinue
	// Bit12 - 1=Index Pin is High, 0=Low (Read Only)
	// Bit11 - 1=Pos Counter Dir is +,0=-ve
	//	Bits10-8 - Interface Mode Select - see manual
	// Bit7 - 1=A&B swapped
	// Bit6 - 1=DIR Output Enable,0=I/O Pin
	// Bit5 - 1=Enable Timer gate accumulation
	// Bits4-3 - Timer input prescale
	// 11 = 1:256
	// 10 = 1:64
	// 01 = 1:8
	// 00 = 1:1
	// Bit2 - 1=Index Pulse resets counter,0=doesn't
	// Bit1 - Timer Clock Select 1=QEA (rising),0 = Tcy
	// Bit0 - Counter Dir - 1=QEB state determines, 0=Bit11 determines

	QEICON = 0x0910;	//+ve count, 16 bit timer mode,DIR pin = I/O
							//1:64 divide from Tcy as clock = 115.2kHz with 7.3728 Mhz Tcy
	// DFLTCON - Digital Filter Control Register
	// Bit15-8 - Not Used
	// Bit7 - 1=Filters enabled on QEA/QEB,0=disabled
	// Bit6-4 - QEA/QEB Filter Clock Divide Bits
	// 111=1:256
	// 110=1:128
	// :::
	// 000=1:1
	// Bit3 -1=Filter enabled on index, 0=disabled
	// Bits2-0 - INDEX Filter Clock Divide ratio as per Bits6-4


	DFLTCON = 0x0000;

	MAXCNT = 0xffff;	//Set maximum count to full scale

	IFS2bits.QEIIF=0; //Clear off any interrupt due to config

	return;
}

	
void setup_timers(void)
{
	// Timer 1 is used for a guard timer to catch missed zero 
	// crossing events that otherwise would cause severe over currents
	// Timer 2 is used to time intervals between commutation events
	// Timer 3 is used to time the on time for the Brake Chopper switch
	// Brake Chopper PWM

	// T1CON
	// Bit 15 - 1=Timer 1 is on,o is off
	// Bit 14 - Not Used
	// Bit 13 - 0=continues in idle,1=discontinues
	// Bits12-7 - 	Not Used
	// Bit6 - 1=timer in gate mode using T1CK
	// Bits5-4 = clk prescalar
	// 11 = 1:256
	// 10 = 1:64
	// 01 = 1:8
	// 00 = 1:1
	// Bit 3 - Not Used
	// Bit 2 - 1= Synch external clock input
	// Bit 1 - 1=clk is rising edge of T1CK,0 = Tcy
	// Bit0 - Not Used
	
	T1CON= 0x8020;	//Timer On, 1:64 Tcy clk
						//Prescalar chsoen to match T2 and QEI
						//so that units are the same
	PR1=0xFFFF;		//Set Period Match Regsiter to full scale
	IFS0bits.T1IF=0; //Clear off any pending interrupt

	// T2CON
	// Bit 15 - 1=Timer 2 is on,0 is off
	// Bit 14 - Not Used
	// Bit 13 - 0=continues in idle,1=discontinues
	// Bits12-7 - 	Not Used
	// Bit6 - 1=timer in gate mode using T2CK
	// Bits5-4 = clk prescalar
	// 11 = 1:256
	// 10 = 1:64
	// 01 = 1:8
	// 00 = 1:1
	// Bit3 1=TIMER2&3 in 32 bit mode, 0= separate 16 bit
	// Bit2 - Not Used
	// Bit1 - 1=clk is rising edge of T2CK,0 = Tcy
	// Bit0 - Not Used

	T2CON=0x8020;	//Timer On, 1:64 Tcy clk, 16 bit mode
						//1:64 division chosen to match QEI config
						//which is being used as "input capture"
	PR2=0xFFFF;		//Set Period Match Regsiter to full scale
	IFS0bits.T2IF=0; //Clear off any pending interrupt

	// T3CON
	// Bit 15 - 1=Timer 3 is on,0 is off
	// Bit 14 - Not Used
	// Bit 13 - 0=continues in idle,1=discontinues
	// Bits12-7 - 	Not Used
	// Bit6 - 1=timer in gate mode using T3CK
	// Bits5-4 = clk prescalar
	// 11 = 1:256
	// 10 = 1:64
	// 01 = 1:8
	// 00 = 1:1
	// Bit3 - Not Used
	// Bit2 - Not Used
	// Bit1 - 1=clk is rising edge of T3CK,0 = Tcy
	// Bit0 - Not Used

	T3CON=0x8020; //Timer On, 1:64 Tcy clk
	PR3=0xFFFF;
	IFS0bits.T3IF=0; //Clear off any pending interrupt
	return;
}
unsigned int ReadConfig(int address)
{
	// Set Table Page to point to config page
	asm(" mov.w	#0x00F8,w2");
	asm(" mov.w w2,TBLPAG");
	// Now read the values
	asm(" tblrdl [w0],w0");
	// Note that strictly speaking the return WREG0
	// is uneccesary as the correct result is already in W0.
	// It does keep the compiler from generating a warning.
	return WREG0;
}
void WriteConfig(int address, int value) 
{ 
	// Set Table Page to point to config page
	asm(" mov.w	#0x00F8,w2");
	asm(" mov.w w2,TBLPAG");
	// Set NVMCON with correct value for program of
	// config location
	asm(" mov.w	#0x4008,w2");
	asm(" mov.w w2,NVMCON");
	// Address will be in w0 and value in w1
	// load these into the programming registers  
	asm(" tblwtl	W1,[W0]");
	asm(" bset		NVMCON,#14"); 
	asm(" mov		#0x55,W2 ");
	asm(" mov		W2,NVMKEY ");
	asm(" mov		#0xaa,W2 ");
	asm(" mov		W2,NVMKEY ");
	asm(" bset		NVMCON,#15"); 
	 

	while(NVMCONbits.WR); 
}


#ifdef DEVELOPMODE
void setup_uart(void)
{

 U1MODE = 0x8000;
 U1STA = 0x0000;
 U1BRG = ((CLOCK_FREQ/16)/BAUD) - 1;	// set baudrate to BAUD rate
 IEC0bits.U1RXIE = 1;
 RXPtr = &InData[0];		// point to first char in receive string
 control_flags2.CheckRX = 0;
 control_flags2.SendTX = 0;
 U1STAbits.UTXEN = 1;           // Initiate transmission
} 
#endif

⌨️ 快捷键说明

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