📄 setup.c
字号:
/**********************************************************************
* *
* Software License Agreement *
* *
* The software supplied herewith by Microchip Technology *
* Incorporated (the "Company") for its dsPIC controller *
* is intended and supplied to you, the Company's customer, *
* for use solely and exclusively on Microchip dsPIC *
* products. The software is owned by the Company and/or its *
* supplier, and is protected under applicable copyright laws. All *
* rights are reserved. Any use in violation of the foregoing *
* restrictions may subject the user to criminal sanctions under *
* applicable laws, as well as to civil liability for the breach of *
* the terms and conditions of this license. *
* *
* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO *
* WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, *
* BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND *
* FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE *
* COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, *
* INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. *
* *
**********************************************************************/
/**********************************************************************
* *
* Author: Smart Power Soutions, LLP *
* *
* Filename: setup.c *
* Date: 4/21/04 *
* File Version: 4.00 *
* Project: 53 *
* Drawing: 2 *
* *
* Tools used: MPLAB C30 Compiler v 1.20.01 *
* *
* Linker File: p30f6010.gld *
* *
* *
***********************************************************************
* Code Description
*
* This file contains all of the peripheral setup routines for the
* dsPIC. There is also a WriteConfig() function, which is used to
* make sure the device configuration bits at runtime.
* In particular, the WriteConfig() function inverts the polarity of
* The PWM output signals. Normally, this would be done because
* the gate driver circuits require active low polarity. However, in
* this application, the polarity is changed so that the active portion
* of the duty cycle will occur at the end of the PWM timer count
* period. The PWM is configured to trigger an A/D conversion at
* the end of the PWM cycle. This allows the A/D to always be
* triggered at the end of the on time, regardless of the PWM duty
* cycle. The user must write a complemented duty cycle value to
* the PDC registers for this technique to work. (Note: This trick
* will only work when the PWM is operating in the independent mode
* where no dead time insertion is used.)
*
*
* ADC triggered here
* |
* PWM1 _____ _______________
* |________________| |_______
*
* PWM2 _____ _______________________
* |________| |_______
*
* PWM3 _____ _________
* |______________________| |_______
*
*
**********************************************************************/
#include "general.h"
#include "hardware.h"
#include "defs.h"
#include "extern_globals.h"
void setup_ports(void);
void setup_motor_pwms(void);
void setup_adc(void);
void setup_qei(void);
void setup_timers(void);
unsigned int ReadConfig(int);
void WriteConfig(int,int);
#ifdef DEVELOPMODE
void setup_uart(void);
#endif
void setup_ports(void)
{
// Clear All Ports Prior to defining I/O
PORTB=0;
PORTC=0;
PORTD=0;
PORTE=0;
// Ensure Firing is disabled
DISABLE_FIRING;
// Now set pin direction registers
TRISB = 0xFFFF; // RB15 is the Output Compare(B) Fault Input -> input
// RB14-0 Left as inputs as these are the analogue channels.
TRISC = 0x6000; // RC14 is S2 Start/Stop switch -> input
// RC13 is S3 Rev/Fwd switch -> input
TRISD = 0x0003; // RD0 and 1 default -> inputs used for debug EMUC2/EMUD2
TRISE = 0x0100; // RE8 is the input from the Trip Button for the PWM FLTA -> input
// RE5-0 are the PWMs -> outputs
return;
}
// Note that the normal operation of the PWM module
// is that switches turn on at the start of the cycle
// when the PWM ramp resets to zero. Switches turn off when
// the ramp reaches the duty cycle value.
// This means that if you want to use the special event
// trigger to the ADC module, the natural place to put
// the trigger is just after the switches turn on.
// This is so you don't have to keep moving the sample
// point which is not recommended as the SFR for
// the sample point (SEVTCMP) is not double buffered.
// If SEVTCMP is changed on the fly then the next ADC trigger
// might occur too early in the PWM cycle or may not happen.
// In this instance we would like to trigger ADC just before
// the switches turn off to get best sample of ibus.
// This avoids problems with discontinuous current waveforms.
// In order to do this without changing SEVTCMP, all firing
// has been inverted. The actual ACTIVE state of firing is 1
// but this has been changed to be 0 in the config bits
// This means that switches turn off when ramp resets and
// back on when duty cycle (PDCx) = ramp.
// All duty cycle values therefore need to be corrected to be
// 2*PTER-D where D is the required duty.
// Also all definitions of what happens during faults and
// output overrides need to be changed to drive swicthes
// INACTIVE to be on and ACTIVE to be off.
// All comments below related to bit bit defs etc are for
// conventional (non-inverted) firing.
void setup_motor_pwms(void)
{
unsigned int config_value,temp;
// Setup Motor Control PWM Module
// PTCON - Timebase Control
// Bit 15 1=Timebase is ON, 0=OFF
// Bit 14 - Not Implemented
// Bit 13 1=Timebase Halts in CPU idle,0 = runs
// Bits12-8 - Not Implemented
// Bits7-4 Timebase Interrupt Postscaler Select
// 1111 = 1:16 Postscale
// ::::
// 0001 = 1:2 Postscale
// 0000 = 1:1 Postscle
// Bits3-2 Timebase I/p Clk Prescale Select
// 11 = 1:64 Prescale
// 10 = 1:16 Prescale
// 01 = 1:4 Prescale
// 00 = 1:1 Prescale
// Bits1-0 Timebase Mode Select
// 11 = Continuous Up/Down with Double Updates
// 10 = Continuous Up/Down
// 01 = Single Event
// 00 = Free-running
PTCON = 0x8000; //Timebase On, runs in idle, no post or prescaler, free-running
// PTPER - Period Register
// Bit 15 - Not Implemented
// Bits14-0 - Value used for period comparison and therefore
// reset or change in direct of PWM ramp
// PWM period is given by (PTER+1) * Tcy * Prescaler if in Free-run or single event
// and by (PTER+1) * Tcy * Prescaler / 2 otherwise
PTPER = FULL_DUTY/2; // With 7.3728MHz Fcy and no prescaler
// When FULL_DUTY= 922 this gives 16kHz PWM
// SEVTCMP - Special Event Trigger Control
// Bit15 1=Trigger Occurs When Counting Down, 0 = Up
// Bits14-0 = Special Event Compare Value
SEVTCMP = FULL_DUTY/2; // Trigger occurs just before switch turns off
// as firing is inverted
// PWMCON1 - PWM Control Register #1
// Bits15-12 Not Implemented
// Bits11-8 1=PWM Pin Pair Independent, 0=Complementary
// Bit11 = PWM4 --- Bit8 = PWM1
// Bits7-4 1=PWM High Side Pin is Enabled for PWM, 0 = I/O
// Bit7 = PWM4 --- Bit4 = PWM1
// Bits3-0 1=PWM Low Side Pin is Enabled for PWM, 0 = I/O
// Bit3 = PWM4 --- Bit4 = PWM1
PWMCON1 = 0x0700; // Phase#4 Firing Signals Not Used, all others independent
// PWMCON2 - PWM Control Register #2
// Bits15-12 Not Implemented
// Bits11-8 Special Event Trigger Postscale
// 1111 = 1:16 Postscale
// ::::
// 0001 = 1:2 Postscale
// 0000 = 1:1 Postscle
// Bits7-2 Not Implemented
// Bit1 - 1=Output Overrides Synch to PWM Timebase
// 0=Output Overrides Occur on next Tcy boundary
// Bit0 - 1=Updates from Duty Cycle and Period Registers Disabled
// 0=Updates from Duty Cycle and Period Registers Enabled
PWMCON2 = 0x0000; // No Special Event Prescale, Fast Overrides, Updates enabled
// DTCON1 & 2 - Deadtime control registers
// See manual for details of bits
DTCON1 = 0x0000; // Deadtime disabled as only modulating diagonally
// FLTACON - FaultA Input control register
// Bits15-8 1=PWMs Driven ACTIVE on Fault, 0 = INACTIVE
// Bit15 = #4 High Side
// Bit14 = #4 Low Side
// Bit13 = #3 High Side
// :::::
// Bit8 = #1 Low Side
// Bit7 - 1=Cycle-cycle limit, 0=latched fault
// Bits6-4 Not Implemented
// Bits3-0 1=Pin Pair Controlled by FLTA, 0 = not controlled
// Bit3 = #4 Pair
// ::::
// Bit0 = #1 Pair
FLTACON = 0xFF0F; //All pins driven ACTIVE with latched FLTA
//but this turns switches off due to inversion
//of ACTIVE definition
OVDCON = 0x3FFF; // All outputs (except #4 which is not used) made PWMs.
// All override states = ACTIVE due to inversion
// PDC1-4 - PWM#1-4 Duty Cycle Register
// Bits15-0 PWM Duty Cycle Value
PDC1=FULL_DUTY; // In this instance 0 duty cycle is full value
PDC2=FULL_DUTY; // in duty cycle registers due to inversion
PDC3=FULL_DUTY;
// Note that the Pin Polarity Definition (ie ACTIVE=1 or ACTIVE=0)
// And the Reset state is determined by device configuaration bits
// usually set during programming.
// However in this instance as inverting this definition we want
// ACTIVE to be set to zero which is not what user would expect.
// Therefore we will read the config value and check to see if the
// bits which determine PWM operation are set correctly
// Call ReadConfig with 4 first to get the bottom 16 bits of F80004
// config register.
config_value=ReadConfig(4);
temp=config_value;
// Mask off the bits we are interested in and shift them down
temp=(temp & 0x0700)>>8;
// If the PWM polarity and reset definition bits are set
// correctly already then temp should be set to 4
if (temp != 4)
{
// Form correct config_value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -