📄 lab4.c
字号:
/*
Lab4 is the exercise needed to spin a sensored BLDC motor.
The task consists of the following:
Sense changes in the Hall Sensors connected to CN4,5 & 6 (PortB)
During the CNInterrupt, read the sensors input by reading PortB
Mask and determine the state of the position 1, 2, ... 6.
Use the state and the lookup table provided to determine the
Overload Control Register value. Set the OVDCON to this value.
The PWM is initialized to generate independant continuous PWMs.
All 3 PWM Duty cycles are set by reading the Pot REF 10-bit value.
The FPWM = 4750hz
The ADC is configured to manually sample the Pot REF every 100 mS
The converted 10-bit value is loaded in all 3 PWM duty cycle registers
*/
#define __dsPIC30F2010__
#include "c:\pic30_tools\support\h\p30F2010.h"
#define FCY 5000000 // xtal = 5.0Mhz; PLLx4
#define MILLISEC FCY/10000 // 1 mSec delay constant
#define FPWM 4750
void InitADC10(void);
void AverageADC(void);
void DelayNmSec(unsigned int N);
void InitMCPWM(void);
unsigned int HallValue;
/*************************************************************
High side driver table is as below. In this StateHiTable,
the high side driver is PWM while the low side driver is
either on or off. THIS Table IS NOT USED in THIS EXERCISE
*************************************************************/
unsigned int StateHiTable[] = {0x0000, 0x0210, 0x2004, 0x0204,
0x0801, 0x0810, 0x2001, 0x0000};
/*************************************************************
Low side driver table is as below. In this StateLoTable,
the Low side driver is PWM while the high side driver is
either on or off. This table is used in this exercise
*************************************************************/
unsigned int StateLoTable[] = {0x0000, 0x1002, 0x0420, 0x0402,
0x0108, 0x1008, 0x0120, 0x0000};
/****************************************************************
Interrupt vector for Change Notification CN4, 5 and 6 is as below.
When a Hall sensor changes states, an interrupt will be
caused which will vector to the routine below
The user has to then read the PORTB, mask bits 3, 4 and 5,
shift and adjust the value to read as 1, 2 ... 6. This
value is then used as an offset in the lookup table StateLoTable
to determine the value loaded in the OCDCON register
*****************************************************************/
void _ISR _CNInterrupt(void)
{
'Replace text with Code // CNIF clear flag
HallValue = 'Replace text with Code // mask RB3,4 & 5
HallValue = 'Replace text with Code // shift right 3 times
OVDCON = 'Replace text with Code // Load the overide control register
}
int main(void)
{
LATE = 0x0000;
TRISE = 0xFFC0; // PWMs are outputs
CNEN1 = 0x0070; // CN4,5 and 6 enabled
IFS0bits.CNIF = 0; // clear CNIF
IEC0bits.CNIE = 1; // enable CN interrupt
InitMCPWM();
InitADC10();
while(1) // do for ever
{
ADCON1bits.SAMP = 1; // start sampling ...
DelayNmSec(100); // for 100 mS
ADCON1bits.SAMP = 0; // start Converting
while (!IFS0bits.ADIF); // wait till conversion done
IFS0bits.ADIF = 0; // clear ADIF if done
PDC1 = 'Replace text with Code // PWM = ADC value mulitplied by 2 ...
PDC2 = PDC1; // and load all three PWMs ...
PDC3 = PDC1; // with same duty cycles
} // end of while (1)
}
/*******************************************************************
Below is the code required to setup the ADC registers for :
1. 1 channel conversion (in this case RB2/AN2)
2. Manual Sample start
3. User specified sampling delay (100mS in this case)
4. Manual Stop Sampling and start converting
5. Manual check of Conversion complete
*********************************************************************/
void InitADC10(void)
{
ADPCFG = 'Replace text with Code // all PORTB = Digital; RB2 = analog
ADCON1 = 'Replace text with Code // SAMP bit = 0 ends sampling ...
// and starts converting
ADCHS = 'Replace text with Code // Connect RB2/AN2 as CH0 input ..
// in this example RB2/AN2 is the input
ADCON3 = 'Replace text with Code // Tad = internal RC (4uS)
ADCON1bits.ADON = 1; // turn ADC ON
}
/********************************************************************
InitMCPWM, intializes the PWM as follows:
1. FPWM = 4750 hz
2. Independant PWMs
3. Control outputs using OVDCON
4. Set Duty Cycle by reading ADC Pot Value
*********************************************************************/
void InitMCPWM(void)
{
PTPER = 'Replace text with Code // use formula for FPWM = 4750 hz
PWMCON1 = 'Replace text with Code // independant PWMs
OVDCON = 0x0000; // allow control using OVD
PDC1 = 0; // init PWM 1, 2 and 3 to 0
PDC2 = 0;
PDC3 = 0;
PTCON = 0x8000; // start PWM
}
//---------------------------------------------------------------------
// This is a generic 1ms delay routine to give a 1mS to 65.5 Seconds delay
// For N = 1 the delay is 1 mS, for N = 65535 the delay is 65,535 mS.
// Note that FCY is used in the computation. Please make the necessary
// Changes(PLLx4 or PLLx8 etc) to compute the right FCY as in the define
// statement above.
void DelayNmSec(unsigned int N)
{
unsigned int j;
while(N--)
for(j=0;j < MILLISEC;j++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -