|
|
View previous topic :: View next topic |
Author |
Message |
Orcino
Joined: 07 Sep 2003 Posts: 56
|
example ADC 30F2020 |
Posted: Fri May 08, 2009 4:03 pm |
|
|
Hi ever body,
I need a simple example prg using ADC the 30F2020, my code not work and i'm a very crazzy with this.
Thanks
Orcino |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Fri May 08, 2009 4:36 pm |
|
|
Post your code, we'll try to fix it ;) |
|
|
Orcino
Joined: 07 Sep 2003 Posts: 56
|
|
Posted: Fri May 08, 2009 5:48 pm |
|
|
Hi, thanks for your help. This below is a little code for test, but ADC not work.
Code: |
#include <30F2020.h>
#device ADC=10
#device *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOWRTB //Boot block not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES FRC_PLL //Internal Fast RC oscillator with PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES FRANGE_HIGH
#FUSES NOOSCIO //OSC2 is clock output
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES PUT128 //Power On Reset Timer value 128ms
#FUSES NODEBUG //No Debug mode for ICD
//#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#use delay(clock=58200000)
#use rs232(UART1,baud=19200,parity=N,bits=8)
//*****************************************************************************
//
//*****************************************************************************
void config_PWM(void);
//*****************************************************************************
// Variaveis globais
//*****************************************************************************
unsigned int16 volts=0;
int1 inter=0;
//******************************************************************************
// Configuração de alguns REGISTROS
//******************************************************************************
unsigned int16 IOCON1, IOCON2,
DUTY_PWM1, DUTY_PWM2,
D_TIME1, D_TIME2,
PWMCON1, PWMCON2,
ALTDTR1,ALTDTR2,
PTPER, PTCON;
//******************** PWM1 *********************************
#locate IOCON1 = 0x40A
#bit IOCON1_PENH = 0X40A.15
#bit IOCON1_PENL = 0X40A.14
#bit IOCON1_POLH = 0X40A.13
#bit IOCON1_POLL = 0X40A.12
#bit IOCON1_PMOD1= 0X40A.11
#bit IOCON1_PMOD0= 0X40A.10
#bit IOCON1_OVERENH= 0X40A.9
#bit IOCON1_OVERENL= 0X40A.8
#bit IOCON1_OVRDAT1= 0X40A.7
#bit IOCON1_OVRDAT0= 0X40A.6
#bit IOCON1_FLTDAT1= 0X40A.5
#bit IOCON1_FLTDAT0= 0X40A.4
#bit IOCON1_CLDAT1= 0X40A.3
#bit IOCON1_CLDAT0= 0X40A.2
#bit IOCON1_0SYNC= 0X40A.0
#locate DUTY_PWM1 = 0X40E // DUTY CYCLE canal 1
#locate D_TIME1 = 0X412 // DEAD TIME canal 1
#locate ALTDTR1=0X414
#locate PWMCON1 = 0X408
#bit PWMCON1_IUE =0X408.0 // Atualiza DUTY instantaneamente
//**************** PWM2 *************************************
#locate IOCON2 = 0x041E
#bit IOCON2_PENH = 0X41E.15
#bit IOCON2_PENL = 0X41E.14
#bit IOCON2_POLH = 0X41E.13
#bit IOCON2_POLL = 0X41E.12
#bit IOCON2_PMOD1= 0X413.11
#bit IOCON2_PMOD0= 0X41E.10
#bit IOCON2_OVERENH=0X41E.9
#bit IOCON2_OVERENL=0X41E.8
#bit IOCON2_OVRDAT1=0X41E.7
#bit IOCON2_OVRDAT0=0X41E.6
#bit IOCON2_FLTDAT1=0X41E.5
#bit IOCON2_FLTDAT0=0X41E.4
#bit IOCON2_CLDAT1= 0X41E.3
#bit IOCON2_CLDAT0= 0X41E.2
#bit IOCON2_0SYNC= 0X41E.0
#locate DUTY_PWM2 = 0X422 // DUTY CYCLE canal 2
#locate D_TIME2 = 0X426 // DEAD TIME canal 2
#locate ALTDTR2=0X428
#locate PWMCON2 = 0X41C
#bit PWMCON2_IUE =0X41C.0 // Atualiza DUTY instantaneamente
#locate PTPER=0X402
#locate PTCON=0X400
#bit PTCON_PTEN=0X400.15
#word IEC0=0X098
#bit IECO_ADCPOIE=0X98.5
//****************************************************************************
// Função Principal
//****************************************************************************
void main(void)
{
config_PWM();
SETUP_ADC_PORTS(sAN0|VSS_VDD);
SETUP_ADC(ADC_CLOCK_DIV_16|ADC_TAD_MUL_16);
SET_ADC_CHANNEL(0);
while(1)
{
volts = read_adc(ADC_START_AND_READ);
printf(" Volts...= %lu \n\r ",volts);
delay_ms(300);
}
}
//*****************************************************************************
// Configuração do PWMs
//*****************************************************************************
void config_PWM(void)
{
IOCON1_PENH = 1; // PWM1H is controlled by PWM module */
IOCON1_PENL = 1; // PWM1L is controlled by PWM module */
IOCON1_PMOD0 = 1; // Select independente Output PWM mode */
IOCON1_PMOD1 = 0;
PWMCON1_IUE = 1; // Atualizaçao instantanea do DUTY CYCLE */
DUTY_PWM1 = 2000; /* Duty Cycle = PDC2*1.05nsec = 672nsec */
// 9000 valor máximo a ser usado
/* Load PDTR1 and ALTDTR2 register with preset dead time value */
D_TIME1 = 60; // Deadtime setting */
// Deadtime = DTR1*1.05 = 67.2nsec */
ALTDTR1 = 60; // Deadtime setting */
// Deadtime = ALTDTR1*1.05 = 67.2nsec */
//* ~~~~~~~~~~~~~~~~~~~~ PWM2 Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//* PWM2 I/O Control Register register */
IOCON2_PENH = 1; //* PWM2H is controlled by PWM module
IOCON2_PENL = 1; //* PWM2L is controlled by PWM module
IOCON2_PMOD0 = 1; //* Select independente Output PWM mode
IOCON2_PMOD1 = 0;
PWMCON2_IUE = 1; //* Atualizaçao instantanea do DUTY CYCLE
// PMOD - 00 -> comprementar
// - 01 -> independente
// - 10 -> Push Pull
DUTY_PWM2 = 2000; //* Duty Cycle = PDC2*1.05nsec = 672nsec
D_TIME2 = 1800; //* Deadtime setting
//* Deadtime = DTR2*1.05 = 67.2nsec
ALTDTR2 = 1800; //* Deadtime setting */
//* Deadtime = ALTDTR2*1.05 = 67.2nsec
//* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//* Configure PTPER register to produce 80kHz PWM frequency */
PTPER = 11500; //* PWM Period @30 MIPS, 2.5usec == 80kHz
//* Period = PTPER*1.05nsec = 2.499use
PTCON_PTEN = 1; //* Enable the PWM Module
}
//****************************************************************************
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat May 09, 2009 2:32 am |
|
|
I'm not using dsPIC variants of the 16-bit chips and I don't plan it for the time being. So I can't go very deep into the problem. I just run your code in MPLAB SIM and checked, how it configured the ADC.
Code: | SETUP_ADC(ADC_CLOCK_DIV_16|ADC_TAD_MUL_16);
024A 2100F4 mov.w #0x100f,0x0008
024C 881804 mov.w 0x0008,0x0300 |
Without knowing much dsPIC details, I see, that the code sets non-existing bits in ADCON, but misses to enable the ADC at all (Bit15=1).
So apparently, PCD built-in functions don't work yet with this chip.
You have to go back to the 30F2020 datasheet and perform the ADC control in your own code. Imagine, you are using C30 and have no built-in functions at all. You can possbly inherit the basic ADC handling from Microchip example software, e.g. the Sync Buck Board Dev. Kit support package. Lab3 is dealing with ADC control, as far as I see. |
|
|
Orcino
Joined: 07 Sep 2003 Posts: 56
|
|
Posted: Sat May 09, 2009 5:59 am |
|
|
Hi, i change the register but not work again, look below.
Thanks for your help
Orcino
Code: |
#include <30F2020.h>
#device ADC=10
#device *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOWRTB //Boot block not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES FRC_PLL //Internal Fast RC oscillator with PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES FRANGE_HIGH
#FUSES NOOSCIO //OSC2 is clock output
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES PUT128 //Power On Reset Timer value 128ms
#FUSES NODEBUG //No Debug mode for ICD
//#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#use delay(clock=58200000)
#use rs232(UART1,baud=19200,parity=N,bits=8)
//*****************************************************************************
//
//*****************************************************************************
void config_adc(void);
void config_PWM(void);
//*****************************************************************************
// Variaveis globais
//*****************************************************************************
unsigned int16 volts=0;
int1 inter=0;
//******************************************************************************
// Configuração de alguns REGISTROS
//******************************************************************************
unsigned int16 IOCON1, IOCON2,
DUTY_PWM1, DUTY_PWM2,
D_TIME1, D_TIME2,
PWMCON1, PWMCON2,
ALTDTR1,ALTDTR2,
PTPER, PTCON;
unsigned int16 ADCON,
ADSTAT,
ADPCFG,
ADCPC0;
unsigned int16 IFS0,
IPC2,
IEC0;
unsigned int16 ADC_BUFFER;
//******************** Registros do ADC **************************************
#locate ADCON=0X300
#bit ADCON_ADON=0X300.15
#bit ADCON_ADSIDL=0X300.13
#bit ADCON_GSWTG=0X300.10
#bit ADCON_FORM=0X300.8
#bit ADCON_EIE=0X300.7
#bit ADCON_ORDER=0X300.6
#bit ADCON_SEQSAMP=0X300.5
#bit ADCON_ADCS2=0X300.2
#bit ADCON_ADCS1=0X300.1
#bit ADCON_ADCS0=0X300.0
#locate ADSTAT=0X306
#locate ADPCFG=0X302
#bit ADPCFG_AD0=0X302.0
#bit ADPCFG_AD1=0X302.1
#word ADC_BUFFER=0X320
#word ADC_BUFFER1=0X322
#locate ADCPC0=0X30A
#bit ADCPC0_TRGSRC3=0X30A.3
#bit ADCPC0_TRGSRC2=0X30A.2
#bit ADCPC0_TRGSRC1=0X30A.1
#bit ADCPC0_TRGSRC0=0X30A.0
#bit ADCPC0_IRQEN0 =0X30A.7
#locate IFS0=0X084
#bit IFS0_ADIF=0X84.11
#locate IPC2=0X0A8
#bit IPC2_ADIP2=0X0A8.14
#bit IPC2_ADIP1=0X0A8.13
#bit IPC2_ADIP0=0X0A8.12
#locate IEC0=0X094
#bit IEC0_ADIE=0X094.11
//******************** PWM1 *********************************
#locate IOCON1 = 0x40A
#bit IOCON1_PENH = 0X40A.15
#bit IOCON1_PENL = 0X40A.14
#bit IOCON1_POLH = 0X40A.13
#bit IOCON1_POLL = 0X40A.12
#bit IOCON1_PMOD1= 0X40A.11
#bit IOCON1_PMOD0= 0X40A.10
#bit IOCON1_OVERENH= 0X40A.9
#bit IOCON1_OVERENL= 0X40A.8
#bit IOCON1_OVRDAT1= 0X40A.7
#bit IOCON1_OVRDAT0= 0X40A.6
#bit IOCON1_FLTDAT1= 0X40A.5
#bit IOCON1_FLTDAT0= 0X40A.4
#bit IOCON1_CLDAT1= 0X40A.3
#bit IOCON1_CLDAT0= 0X40A.2
#bit IOCON1_0SYNC= 0X40A.0
#locate DUTY_PWM1 = 0X40E // DUTY CYCLE canal 1
#locate D_TIME1 = 0X412 // DEAD TIME canal 1
#locate ALTDTR1=0X414
#locate PWMCON1 = 0X408
#bit PWMCON1_IUE =0X408.0 // Atualiza DUTY instantaneamente
//**************** PWM2 *************************************
#locate IOCON2 = 0x041E
#bit IOCON2_PENH = 0X41E.15
#bit IOCON2_PENL = 0X41E.14
#bit IOCON2_POLH = 0X41E.13
#bit IOCON2_POLL = 0X41E.12
#bit IOCON2_PMOD1= 0X413.11
#bit IOCON2_PMOD0= 0X41E.10
#bit IOCON2_OVERENH=0X41E.9
#bit IOCON2_OVERENL=0X41E.8
#bit IOCON2_OVRDAT1=0X41E.7
#bit IOCON2_OVRDAT0=0X41E.6
#bit IOCON2_FLTDAT1=0X41E.5
#bit IOCON2_FLTDAT0=0X41E.4
#bit IOCON2_CLDAT1= 0X41E.3
#bit IOCON2_CLDAT0= 0X41E.2
#bit IOCON2_0SYNC= 0X41E.0
#locate DUTY_PWM2 = 0X422 // DUTY CYCLE canal 2
#locate D_TIME2 = 0X426 // DEAD TIME canal 2
#locate ALTDTR2=0X428
#locate PWMCON2 = 0X41C
#bit PWMCON2_IUE =0X41C.0 // Atualiza DUTY instantaneamente
#locate PTPER=0X402
#locate PTCON=0X400
#bit PTCON_PTEN=0X400.15
#word IEC0=0X098
#bit IECO_ADCPOIE=0X98.5
//****************************************************************************
// Função Principal
//****************************************************************************
void main(void)
{
config_adc();
config_PWM();
enable_interrupts(INT_ADCP0);
enable_interrupts(INTR_GLOBAL);
SET_TRIS_B(0B1111111111);
DUTY_PWM1=9000;
while(1)
{
printf(" Volts...= %lu \n\r ",ADC_BUFFER);
delay_ms(300);
if(inter)
printf("Gerou int \r\n ");
}
}
//****************************************************************************
// Interrupção ADC
//****************************************************************************
#int_ADC1
void ADC1_isr(void)
{
IFS0_ADIF=0;
inter=1;
}
#int_ADCP0
void ADCP0_isr(void)
{
IFS0_ADIF = 0;
inter=1;
volts=ADC_BUFFER;
}
//*****************************************************************************
// Config ADC
//*****************************************************************************
void config_adc(void)
{
ADCON_ADON = 0; // desabilita / configuração
ADCON_ADSIDL = 0; // Operate in Idle Mode
ADCON_FORM = 0; // Output in Integer Format
ADCON_EIE = 1; // Enable Early Interrupt
ADCON_ORDER = 0; // Even channel first
ADCON_SEQSAMP = 1; // Sequential Sampling Enabled
ADCON_ADCS2 = 1; // Clock Divider is set up for Fadc/12
ADCON_ADCS1 = 0;
ADCON_ADCS0 = 0;
ADSTAT = 0; // Clear the ADSTAT register
ADPCFG_AD0=0; //AN0/AN1
ADPCFG_AD1=0;
ADCPC0_TRGSRC3 = 0; // Trigger conversion OF CHANNELS AN0/AN1 on PWM#1 Trigger
ADCPC0_TRGSRC2 = 1;
ADCPC0_TRGSRC1 = 0;
ADCPC0_TRGSRC0 = 0;
ADCPC0_IRQEN0 = 1; // Enable the interrupt
ADCON_ADON = 1; // Start the ADC module
/* Set up the Interrupts */
IFS0_ADIF = 0; // Clear AD Interrupt Flag
IPC2_ADIP0 = 0; // ADC Interrupt Priority Is Set To 1
IPC2_ADIP1 = 0;
IPC2_ADIP2 = 1;
IECO_ADCPOIE =1;
IEC0_ADIE = 1; // Enable the ADC Interrupt
}
//*****************************************************************************
// Configuração do PWMs
//*****************************************************************************
void config_PWM(void)
{
IOCON1_PENH = 1; // PWM1H is controlled by PWM module */
IOCON1_PENL = 1; // PWM1L is controlled by PWM module */
IOCON1_PMOD0 = 1; // Select independente Output PWM mode */
IOCON1_PMOD1 = 0;
PWMCON1_IUE = 1; // Atualizaçao instantanea do DUTY CYCLE */
DUTY_PWM1 = 2000; /* Duty Cycle = PDC2*1.05nsec = 672nsec */
// 9000 valor máximo a ser usado
/* Load PDTR1 and ALTDTR2 register with preset dead time value */
D_TIME1 = 60; // Deadtime setting */
// Deadtime = DTR1*1.05 = 67.2nsec */
ALTDTR1 = 60; // Deadtime setting */
// Deadtime = ALTDTR1*1.05 = 67.2nsec */
//* ~~~~~~~~~~~~~~~~~~~~ PWM2 Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//* PWM2 I/O Control Register register */
IOCON2_PENH = 1; //* PWM2H is controlled by PWM module
IOCON2_PENL = 1; //* PWM2L is controlled by PWM module
IOCON2_PMOD0 = 1; //* Select independente Output PWM mode
IOCON2_PMOD1 = 0;
PWMCON2_IUE = 1; //* Atualizaçao instantanea do DUTY CYCLE
// PMOD - 00 -> comprementar
// - 01 -> independente
// - 10 -> Push Pull
DUTY_PWM2 = 2000; //* Duty Cycle = PDC2*1.05nsec = 672nsec
D_TIME2 = 1800; //* Deadtime setting
//* Deadtime = DTR2*1.05 = 67.2nsec
ALTDTR2 = 1800; //* Deadtime setting */
//* Deadtime = ALTDTR2*1.05 = 67.2nsec
//* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
//* Configure PTPER register to produce 80kHz PWM frequency */
PTPER = 11500; //* PWM Period @30 MIPS, 2.5usec == 80kHz
//* Period = PTPER*1.05nsec = 2.499use
PTCON_PTEN = 1; //* Enable the PWM Module
}
//****************************************************************************
|
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat May 09, 2009 6:06 am |
|
|
I think, you're on the right track. As I said, I'm not working with these chips, so I can't test the code with dsPIC hardware. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|