📄 lab3.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 + -