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

📄 lab3.c

📁 该程序源码是基于dsPIC单片机的无刷电机驱动程序。
💻 C
字号:
/*
Lab 3 of 845 SNS interfaces the PWm to the ADC.  The user will learn
how the configure the PWM, and more complex functions fo the ADC.
The 3 MC PWMs are configured for 25%, 50% and 75% duty cycles.
These PWMs are sent to ADC inputs which are simultaneously sampled. 
There is a low pass filter at the ADC input so the PWM is converted to
a DC value which can be sampled by the ADC.
The Converted values are displayed serially using the UART.
The four channels displayed are:
1. The Pot called REF on the board
2. PWM1, PWM2 and PWM3

The user has to use Hyperterm to view the serial output at 9600 baud

*/

#define __dsPIC30F2010__
#include "C:\pic30_tools\support\h\uart.h"
#include "c:\pic30_tools\support\h\p30F2010.h"

#define BAUDRATE 9600		// desired baud rate
#define FCY  20000000			// xtal = 5.0Mhz; PLLx16
#define MILLISEC FCY/10000			// 1 mSec delay constant
#define FPWM	80000			// PWM freq = 80 khz


#define LF	0x0A
#define CR	0x0D
#define NULL 0x00
#define SPACE 0x20




void InitADC10(void);
void LoadADC(unsigned int offset);
void AverageADC(void);
void InitUART1(void);
void DelayNmSec(unsigned int N);
void InitMCPWM(void);

unsigned int ANValue[] = {1,2,3,4};

char ADCdata[] = {'P','o','t',SPACE,SPACE,'=',SPACE,'0','x','1','2','3',SPACE,
						'P','W','M','1',SPACE,'=',SPACE,'0','x','1','2','3',SPACE,
						'P','W','M','2',SPACE,'=',SPACE,'0','x','1','2','3',SPACE,
						'P','W','M','3',SPACE,'=',SPACE,'0','x','1','2','3',SPACE,
						CR,LF,NULL};

#define ROWOFFSET 13
#define COLOFFSET 9

// interrupt vector for UART1 TX interrupt
void _ISR _U1TXInterrupt(void)
{
	IFS0bits.U1TXIF = 0;
}



int main(void)
{
unsigned char TxIndex;
unsigned char i;

	LATE = 0x0000;		// PWMs are outputs
	TRISE = 0xFFC0;	//		--do--
	InitMCPWM();
	InitADC10();
	InitUART1();
	while(1)			// do for ever
	{

			TxIndex = 0;		// point to first ADC char
/*******************************************************************/
			ADCON1bits.ADON = 1;			// turn on ADC
			while (!IFS0bits.ADIF); 	// conversion done?
			IFS0bits.ADIF = 0;			// yes then clear flag
			ADCON1bits.ADON = 0;			// turn off ADC
 			AverageADC();
			for (i = 0; i<=3; i++)
				LoadADC(i);						// Load  UART buffer
	 		while (ADCdata[TxIndex])	// and transmit
				{
				WriteUART1((int)ADCdata[TxIndex++]);
				while(BusyUART1());
				}
			DelayNmSec(500);				//  for 500 mS
  
	}	// end of while (1)

}
	
/*******************************************************************
		Below is the code required to setup the ADC registers for :
		1. 4channel Simultaneous sample conversion (AN2,3,4 and 5)
		2. Conversion trigger using PWM interval
		3. Sample after conversion ends
		4. Use Tad = 8*Tcy = 200 nS
		5. Do 4 sample/convert operations before interrupt flag set
		6. Use Mux A only and configure CH0 to AN2, CH1 to AN3,
			CH2 to AN4 and CH3 to AN5. All minus inputs are GND

																	
*********************************************************************/
void InitADC10(void)
{

 ADPCFG = 'Replace text with code			// RB2,3,4 and 5 = analog
 ADCON1 = 'Replace text with code				// Sampling using PWM
									// and SIMSAM on
 ADCHS = 'Replace text with code				// CH0 = AN2, CH1 = AN3, CH2 = AN4
									// CH3 = AN5, All -inputs = GND
 ADCON3 = 'Replace text with code				// Tad = (Tcy/2)*8 = 200 nS
 ADCON2 = 'Replace text with code				// Interrupt @ 4 sample, SimSAm = 4ch 

}

/**********************************************************************
	InitMCPWM configures the PWM 1 to 3.  The PWM is set up for:
	1. Continuous Centered PWM
	2. FPWM = 80Khz
	3. PWM triggers the ADC at every 16 PWM periods
	4. PDC1 = 25%, PDC2 = 50% and PDC3 = 75%
	5. Set outputs as complementary pairs with dead time A
	6. Set dead time = 1uS for all outputs
**********************************************************************/

void InitMCPWM(void)
{
	PTPER = 'Replace text with code	// Use formula for period value
	SEVTCMP = 'Replace text with code				// Special Event trigger for full period 
	PWMCON1 = 'Replace text with code				// Complementary pairs for 6 PWMs
	PWMCON2 = 'Replace text with code				// Spec. Event trigger = 16 periods
	DTCON1bits.DTAPS = 'Replace text with code		// Deadtime = 20*50nS = 1uS
	PDC1 = 'Replace text with code			// PWM1 = 25% 
	PDC2 = 'Replace text with code					// PWM2 = 50%
	PDC3 = 'Replace text with code			// PWM3 = 75%
	PTCON = 0x8002;				// turn on PMW with Centered PWMs

}

/********************************************************************

	AverageADC() averages the 4 values saved in the buffer in RP2,RP3
	and RP1
*********************************************************************/
void AverageADC(void)
{

	ANValue[0] = ADCBUF0 + ADCBUF4 + ADCBUF8 + ADCBUFC;
	ANValue[0] = ANValue[0] >> 2;
	ANValue[1] = ADCBUF1 + ADCBUF5 + ADCBUF9 + ADCBUFD;
	ANValue[1] = ANValue[1] >> 2;
	ANValue[2] = ADCBUF2 + ADCBUF6 + ADCBUFA + ADCBUFE;
	ANValue[2] = ANValue[2] >> 2;
	ANValue[3] = ADCBUF3 + ADCBUF7 + ADCBUFB + ADCBUFF;
	ANValue[3] = ANValue[3] >> 2;
}


/********************************************************************

	LoadADC(i) converts the 10-bit value sampled on the pot REF,
	the PWM1, PWM2 and PWM3  and load the 3 digit BCD value in the
	serial xmit buffer.  The offset i, corresponds to each values
	offset in the array.  This is purely for display purposes only
	Each Line will be:
	Pot =  0x123 PWM1 = 0x234 PWM2 = 0x245 PWM3 = 0x265

*********************************************************************/
void LoadADC(unsigned int offset)
{
unsigned char ADCbcd;
unsigned int j;

	j = offset;
	offset = offset*ROWOFFSET + COLOFFSET;
	while(BusyUART1());						// wait till transmit is over
	ADCbcd = (char)(ANValue[j] >> 8);		// convert the ADC value 
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else ADCbcd = ADCbcd + 0x30;
	ADCdata[offset] = ADCbcd;
	ADCbcd = (char)(ANValue[j] >> 4);
	ADCbcd = ADCbcd & 0x0F;
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else ADCbcd = ADCbcd + 0x30;
	ADCdata[offset+1] = ADCbcd;
	ADCbcd = (char)ANValue[j] & 0x0F;
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else ADCbcd = ADCbcd + 0x30;
	ADCdata[offset+2] = ADCbcd;

}



void InitUART1(void)
{

unsigned int baudvalue;
unsigned int U1MODEvalue;
unsigned int U1STAvalue;

	CloseUART1();
	ConfigIntUART1(UART_RX_INT_DIS & UART_RX_INT_PR6 & 
						UART_TX_INT_DIS & UART_TX_INT_PR2);
	baudvalue = ((FCY/16)/BAUDRATE) - 1;
	U1MODEvalue = 	UART_EN & UART_IDLE_CON & UART_RX_TX &
						UART_DIS_WAKE & UART_DIS_LOOPBACK &
						UART_EN_ABAUD & UART_NO_PAR_8BIT &
						UART_1STOPBIT;
	U1STAvalue =	UART_INT_TX_BUF_EMPTY &
						UART_TX_PIN_NORMAL &
						UART_TX_ENABLE & UART_INT_RX_3_4_FUL &
						UART_ADR_DETECT_DIS &
						UART_RX_OVERRUN_CLEAR;
	OpenUART1(U1MODEvalue, U1STAvalue, baudvalue);
}

//---------------------------------------------------------------------
// 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 + -