📄 setup.c
字号:
// Call ReadConfig with 4 first to get the bottom 16 bits of F80004
// config register.
// Now clear off any pending PWM or FLT interrupts due to config
IFS3bits.PWMIF = 0;
IFS3bits.FLTAIF =0;
PTCON = 0x8000; //Timebase On, runs in idle, no post or prescaler, free-running
return;
}
void setup_adc(void)
{
// ADCON1 - ADC Control Regsiter#1
// Bit 15 1=ADC Is On,0 = Off 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 DMA Buffer Build Mode 0= DMA Buffers Scatter/Gather mode
// Bit 11 - Not Implemented
// Bit 10 - 10b/12b 0- 10bit 4-channel
// 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 - ADC Sample END bit
// Bit0 - 1 = AD conversion cycle in progress, 0 = finished(Read),abort (write)
#ifndef HIGH_SPEED
AD1CON1 = 0x006E; // Use PWM Trigger, continuous simulatenous sampling
#endif
#ifdef HIGH_SPEED
AD1CON1 = 0x004E; // Use TMR3 trigger instead of PWM trigger
#endif
// ADCON2 - ADC Control Regsiter#2
// Bits15-13 Voltage Reference Config
// See Manual for details 000=AVdd/AVss used
// Bits 12-11 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 - Buffer Fill Mode 0=Start filling the buffer from start address
// Bit0 - 0=Use MUXA settings, 1=Alternate MUXA & B starting with A
AD1CON2 = 0x0200; // Use Avdd/Avss, 4 samples, don't scan, 1 sequence/interrupt
//Use MuxA settings
// ADCON3 - ADC Control Regsiter#3
// Bits14-13 - Not Implemented
// Bits12-8 - Auto Sample Time Bits
// 11111 = 31 TAD
// :::::
// 00000 = 0 TAD
// Bit7-0 ADC Conversion Clock
// 111111 = 32 Tcy
// ::::::
// 000001 = 1 Tcy
// 000000 = Tcy
AD1CON3 = 0x000A; // Not using auto sample, 11 Tcy = Tad
// 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.
AD1CHS0 = VPH_RED;
// ADPCFG - ADC port configuration register
// Bits15-0 1=Digital, port read enabled, ADC Mux input=AVss
// 0=Analog, port read disabled, ADC samples pin
AD1PCFGH = 0xFFFF;
AD1PCFGL = 0x8FF8; //AN15 used as OCFB digital pin
// ADCSSL - ADC Scan Select Regsiter
// Bits15-0 - 1=ANx is selected for scan
// - 0=ANx is not selected for scan
AD1CSSL = 0x7000; //Scan AN12, AN13, AN14
DMA0CONbits.CHEN = 1;
AD1CON1bits.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
IFS3bits.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
#ifndef HIGH_SPEED
T3CON=0x8020; //Timer On, 1:64 Tcy clk
PR3=0xFFFF;
IFS0bits.T3IF=0; //Clear off any pending interrupt
#endif
// If HIGH_SPEED is defined, then use Timer3 to trigger
// ADC.
#ifdef HIGH_SPEED
PR3 = 625; // 64 KHz ADC sampling @ 40 MIPS
TMR3 = 0;
T3CON = 0x8000;
IFS0bits.T3IF=0; //Clear off any pending interrupt
#endif
return;
}
void setup_dma(void)
{
DMA0CONbits.AMODE = 0; // Register Indirect with Post-Incrementing
DMA0CONbits.MODE = 0; // Continuous Mode with Ping-Pong mode disabled
DMA0PAD = (volatile unsigned int) &ADC1BUF0; // Assign DMA to ADC
DMA0CNT = 3; // DMA Count
DMA0REQ = 13; // DMA Peripheral IRQ Selection
DMA0STA = __builtin_dmaoffset(&ADCBuffer[0]);
IFS0bits.DMA0IF = 0; // Clear Interrupt Flag
IEC0bits.DMA0IE = 0; // Enable Interrupt
DMA0CONbits.CHEN = 1; // Enable DMA
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -