📄 setup.c
字号:
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 + -