完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,我想问你一个问题。我想同时对Ch22和Ch23进行采样,但是我对Dma DSPIC33FJ256MC710-I/PT有些问题。我想这样做:1-一次转换这四个信道(每个信道一个采样)2-停止Dma和Addc3-做点什么,这个采样4-写在lcd5上-重新启动Dma和adc为下一个sa示例6-12位ADC转换,500Ksp,因为我使用miKroC pro进行dspic,我不能使用这种结构,当我使用编译器中已知的这种结构时,我得到一个毫无意义的结果,其中之一是ch22的“144042”和ch23的“32876”:这是我的代码:您能帮我什么吗?我的错是什么?我怎样才能从Mikro Cro中读取DMA呢?我不能改变我的编译器,因为我有一些有用的库在miKroC pro中,我需要他们提前感谢你
以上来自于百度翻译 以下为原文 Hi , i want to ask you for a problem. I want to do Simultaneously sampling of Ch22 and Ch23,but I've some problem with Dma DSPIC33FJ256MC710-I/PT . I want to do this: 1- convert this four channel ONE time(one sample for each channel) 2- stop Dma and Adc 3- do something whit this samples 4- write this on lcd 5- restart Dma and adc for next sample 6-12 bit ADC conversion with 500 Ksps brcause I am using miKroC pro for dspic, I cannot use this structure __eds__ int bufferA[NUMSAMP] __attribute__( (eds, space(dma)) ); __eds__ int bufferB[NUMSAMP] __attribute__( (eds, space(dma)) ); #else int bufferA[NUMSAMP] __attribute__( (space(xmemory)) ); int bufferB[NUMSAMP] __attribute__( (space(xmemory)) ); #endif void ProcessADCSamples( __eds__ int *adcBuffer ); void ProcessADCSamples( __eds__ int *adcBuffer ) { /* Do something with ADC Samples */ } void __attribute__ ( (interrupt, auto_psv) ) _DMA0Interrupt( void ) DMA0STAL = __builtin_dmaoffset( &bufferA ); DMA0STAH = __builtin_dmapage( &bufferA ); DMA0STBL = __builtin_dmaoffset( &bufferB ); DMA0STBH = __builtin_dmapage( &bufferB ); and when I use this structure which is known in my compiler, I get nonsense result which one of them is '144042' for ch22 and '-32876' for ch23: unsigned ADCRamStartAddress = 0x7800; BufferA ADCRAMBuffer[ADCRAMBUFFERSIZE] absolute 0x7800; // defined for mcus with 30kB of RAM here is my code: /// Setup of LCD//// ***it LCD_RS at LATF8_bit; ***it LCD_EN at LATD3_bit; ***it LCD_D4 at LATC13_bit; ***it LCD_D5 at LATD0_bit; ***it LCD_D6 at LATD2_bit; ***it LCD_D7 at LATF7_bit; ***it LCD_RS_Direction at TRISF8_bit; ***it LCD_EN_Direction at TRISD3_bit; ***it LCD_D4_Direction at TRISC13_bit; ***it LCD_D5_Direction at TRISD0_bit; ***it LCD_D6_Direction at TRISD2_bit; ***it LCD_D7_Direction at TRISF7_bit; //dma unsigned int dma_bufferA[24][4] absolute 0x7800;//Offset 0 DMA_START_ADDRESS = 0x4000; //dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8 //dma unsigned int dma_bufferB[24][4] absolute 0x7A00;//Offset 200 unsigned int DmaBuffer = 0; unsigned int ch17=0; unsigned int ch18=0; int flag = 0; char str[16]; char str_1[16]; void InitADC(){ ////// ADC config///// AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert) AD1CON1bits.ASAM = 0; // start sample when SAMP is set // AD1CON1bits.ASAM = 1; // Sampling begins when SAMP bit is set (for now) AD1CON1bits.AD12B = 1; // 12-bit ADC operation ////?? AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode AD1CON1bits.ADDMABM = 1; // buffer in order of conversion AD1CON1bits.SIMSAM = 1; // Samples multiple channels simultaneously in sequence AD1CON2bits.VCFG=0; //Vref+=AVDD Vref-=AVSS// //?? AD1CON2bits.SMPI = 1; // (NUM_CHS2SCAN-1); // 2 ADC Channel is scanned AD1CON2bits.SMPI = 0; // increment the dma address or generate interrupt after // completition of every sample/conversion operation AD1CON2bits.CHPS = 0; // Converts CH0/CH1 When AD12B = 1, CHPS is: U-0, Unimplemented, Read as ‘0’ AD1CON2bits.CSCNA=1; //Scan inputs // Scan Input Selections for CH0+ during Sample A bit // when CSCNA bit is set, the CH0SA bits are ignored AD1CON2bits.BUFM = 0; // start filling buffer from the beginning AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock AD1CON3bits.SAMC = 2; // Auto Sample Time = 2*Tad AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*3 = 75ns (13.3Mhz) // ADC Conversion Time for 10-bit Tc=14*Tad = 900ns (1.1MHz) //for 500 Khz sampling in 12-bit 1/500KHz=2*10^-6=200 ns //200ns=14Tad-->Tad=142ns---> ADCS+1=40M*142ns=5.71--> ADCS=~4 //?? AD1CON4bits.DMABL = 2; // Each buffer contains 4 words AD1CON4= 0; // allocates 1 word of bufferto each analog input //AD1CSSH/AD1CSSL: A/D Input Scan Selection Register ///??? AD1CHS0bits.CH0SB = 0b10110; //17=10001 22=0b10110 // MUXA +ve input selection (AN0) for CH0 AD1CHS0bits.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0 AD1CSSHbits.CSS17=1; // Enable AN17 for channel scan AD1CSSHbits.CSS18=1; // Enable AN18 for channel scan //AD1CSSH=0x40;//0x2; //ADC1 INPUT SCAN SELECT REGISTER HIGH AD1CSSL=0; //ADC1 INPUT SCAN SELECT REGISTER Low IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt AD1CON1bits.ADON = 1; // Turn on the A/D converter } typedef struct { int Adc1Ch0[3]; } BufferA ; #define ADCRAMBUFFERSIZE 1 // ADC buffers = 1 unsigned ADCRamStartAddress = 0x7800; BufferA ADCRAMBuffer[ADCRAMBUFFERSIZE] absolute 0x7800; // defined for mcus with 30kB of RAM // DMA0 configuration // Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM // AMODE: Peripheral Indirect Addressing Mode // MODE: Continuous, Ping-Pong Mode // IRQ: ADC Interrupt /*void initDma0(void) { DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode DMA0PAD=(int)&ADC1BUF0; DMA0CNT = 7; //(SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1; DMA0REQ = 13; // Select ADC1 as DMA Request source // DMA0STA = __builtin_dmaoffset(BufferA); // DMA0STB = __builtin_dmaoffset(BufferB); DMA5STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset DMA5STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address // DMA0STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset // DMA0STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit DMA0CONbits.CHEN=1; // Enable DMA } */ void initDma5(void) { DMA5CONbits.SIZE = 0; //16 bit DMA5CONbits.DIR=0; //Read from Peripheral address, write to DPSRAM address DMA5CONbits.AMODE = 0; // Register Indirect Addressing with Post-Increment DMA5CONbits.MODE = 2; //Continuous, Ping-Pong modes enabled DMA5PAD =(int)&ADC1BUF0; // Point DMA to ADC1BUF0 DMA5CNT = 1; // 2 DMA request (1 buffers, each with 8 words) DMA5REQbits.IRQSEL = 13; // Select ADC1 as DMA Request source DMA5STA = ADCRamStartAddress; IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit DMA5CONbits.CHEN=1; // Enable DMA } void Conversonemulti() { AD1CON1bits.ADON = 1; //TURN ON ADC AD1CON1bits.SAMP=1; //START SAMPLING while(!AD1CON1bits.DONE); AD1CON1bits.ADON = 0; //TURNOFF ADC DMA5CONbits.CHEN=0; //Disable DMA } /* void Timer1Interrupt() iv IVT_ADDR_DMA5INTERRUPT { if(DmaBuffer == 0) { ch17=&dma_bufferA[17][4]; ch18=&dma_bufferA[18][4]; // ProcessADCSamples(&BufferA[18][0]); } else { ch17=&dma_bufferB[17][4]; ch18=&dma_bufferB[17][4]; //ProcessADCSamples(&BufferB[17][0]); // ProcessADCSamples(&BufferB[18][0]); } DmaBuffer ^= 1; LATF.F4=~LATF.F4; IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag } */ void main() { //AD1PCFGH/AD1PCFGL: Port Configuration Register AD1PCFGL=0xFFFF; AD1PCFGH=0xFFFF; AD1PCFGHbits.PCFG17 = 0; // AN17 as Analog Input AD1PCFGHbits.PCFG18 = 0; // AN18 as Analog Input PORTA=0; PORTC=0; TRISA.F6= 1; TRISA.F7= 1; TRISF.F4= 0; TRISF.F5= 0; TRISB.F12= 0; TRISB.F13= 0; TRISC.F2= 1; // AN17 TRISC.F3= 1; // AN18 ///////////////PLL configue//////// // Configure Oscillator to operate the device at 40Mhz // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2 // Fosc= 8M*40/(2*2)=80Mhz for 8M input clock OSCCONbits.COSC=0x03; //0b 011 Primary oscillator (XT, HS, EC) with PLL OSCCONbits.OSWEN=0x1; // CLKDIVbits.PLLPRE=0; // N1=2 N1=PLLPRE+2 CLKDIVbits.PLLPOST=0; // N2=2 N2=2*(PLLPost+1) PLLFBDbits.PLLDIV=38; // M=40 M=PLLDIV+2 ////////////// Disable Watch Dog Timer//////// RCONbits.SWDTEN=0; // Disable Watch Dog Timer ///////////////// Lcd_init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // CLEAR display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,1,"Hello"); delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); // CLEAR display ADCRAMBuffer[0].Adc1Ch0[17]=0x0000; ADCRAMBuffer[0].Adc1Ch0[18]=0x0000; InitAdc(); // Initialize the A/D converter to convert Channel 5 InitDma5(); // Initialise the DMA controller to buffer ADC data in conversion order Conversonemulti(); while(1){ IntToStr(ADCRAMBuffer[0].Adc1Ch0[1], str); //converts int to str for Lcd function Lcd_Custom_Out(2,-1 ,txt); Lcd_Out(1,1,str); IntToStr(ADCRAMBuffer[0].Adc1Ch0[2], str_1); //converts int to str for Lcd function Lcd_Custom_Out(2,5 ,txt); Lcd_Out(2,1,str_1); /*intToStr(ch17,str); Lcd_Out(1,1,str); intToStr(ch18,str_1); Lcd_Out(1,2,str_1); */ //initialize buffer Delay_ms(50); // LATF.F4=0; LATF.F5=1; LATB.F12=0; LATB.F13=1; delay_ms(50); // LATF.F4=1; LATF.F5=0; LATB.F12=1; LATB.F13=0; } } could you please help me what my fault is? and how I can read from DMA in miKroC pro? I cannot change my compiler because I have some useful libraries in miKroC pro and I need them thank you in advance best regards |
|
相关推荐
12个回答
|
|
非常感谢你的时间,不幸的是,我没有和MPLAB一起工作,但是我下载了FoM微芯片的代码,关于如何从DMA读取ADC,在这个代码中我看到了这个函数DMA0STAs= BufferA。在MikoC和我搜索之后,我喜欢在一些论坛中,这个代码相当于MPLAB CODIDMA0STA=&;DMAYBuffle;//一个16位DMA RAM主起始地址偏移DMA0STB=和DMAYBuffRB;//一个16位DMA RAM二次启动地址地址I是对还是我犯了错误?
以上来自于百度翻译 以下为原文 Hi thank you so much Weydert because of your time, Unfortunately I did not work with MPLAB but I download the code feom microchip about how to read ADC from DMA and in that code I see this function DMA0STA = __builtin_dmaoffset(BufferA); DMA0STB = __builtin_dmaoffset(BufferB); but we do not this function in MikoC and after I searched I fond in some forums that this code is equivalent to MPLAB code DMA0STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset DMA0STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address Am I right or I made mistake? |
|
|
|
嗨,有些事情我不明白:1)你定义(3int值,Adc1Ch0[0],Adc1Ch0[1]和Adc1Ch0[2]),但是你写在缓冲区外部。2)振荡器是如何配置的?您必须编写一个特殊的解锁序列来写入OSCON SFR。(除非你的编译器能随时为您做这件事)而且写到COSC永远不会改变任何配置;下一个配置必须写到NOSC.3)ADC模块很复杂。-12位转换只能在信道0上完成。-如果只转换信道0,如果无意义则同时采样。- CH22,CH23是什么意思?4)得到CH22的“144042”的ADC结果。这不是一个16位的整数。如果您认为DMA设置是编译器的问题,我建议使用比ADC更简单的周期来获得DMA体验。也许用UART。
以上来自于百度翻译 以下为原文 hi, some things I don't understand: 1) you define typedef struct { int Adc1Ch0[3]; } BufferA ; ( 3 int values, Adc1Ch0[0],Adc1Ch0[1] and Adc1Ch0[2] ) but you write to ADCRAMBuffer[0].Adc1Ch0[17]=0x0000; ADCRAMBuffer[0].Adc1Ch0[18]=0x0000; Writing outside the buffer. 2) How gets the Oscillator configured ? You must program a special unlock-sequence to write to the OSCON SFR. (unless your compiler is very clever todo this for you) And writing to COSC will never change any configuration; next configuration must be written to NOSC. 3) ADC module is complicated. - 12 Bit conversion can only be done on Channel 0. - If only converting channel 0, simultanous sampling if meaningless. - what do you mean with CH22,CH23 ? 4) you get an ADC result of '144042' for ch22. This is not an 16bit integer. If you think the DMA-setup is the problem with your compiler, I suggest to get DMA experience with a more simple periphal than the ADC. Maybe with UART. |
|
|
|
当您使用“DMA”修饰符时,不需要指定绝对地址,MyKoc将在没有您帮助的情况下将缓冲区放置在正确的位置(参见截图)。
以上来自于百度翻译 以下为原文 dma unsigned int dma_bufferA[16] absolute 0x7800;//Offset 0 DMA_START_ADDRESS = 0x4000; dma unsigned int dma_bufferB[16] absolute 0x7C00;//Offset 500 when you use the "dma" modifier, there is no need to specify an absolute address, mirkoC will place the Buffer at the right place without your help. (See Screenshot) Attached Image(s) |
|
|
|
|
|
|
|
非常感谢你们这样的Weydertit,你们解释了DMA和振荡器。MikroC编译器不支持“u builtin_…”在搜索inhttp://..mikroe.com/和其中的一个主题时,我注意到如果我要配置振荡器,我必须在这个路径中完成这个操作->编辑Project->Oscillator.->Primary振荡器w/Pll,然后我们必须在代码中设置PLL,然后设置振荡器tor配置将完成,所以没有必要写“绝对”,谢谢你,因为您的调查,Weydert先生,我很抱歉,但我有另一个问题,我可以写代码阅读ADC结果,从DMA与您的帮助提示,但我面临着一个问题,当我给ADC引脚,A0伏。直流值为296,另一个引脚显示310!!!!而且,当我给2.82针伏特,它显示我4095!!!!如果我增加输入电压,它只显示4095!!!!我一遍又一遍地检查我的电路,我没有看到任何故障,当我检查一个ADC引脚或两个没有DMA的频道时,我可以从ADC读出正确的结果!!!!因此,我认为电路和参考没有问题,我必须使用DMA,因为我必须采样ADC值小于1mshere,这是我的代码,应该注意,当我改变“AD1CON3bits.SAMC”和“AD1CON3bits.ADCS”时,偏移值已经改变,但是对于0伏的输入,偏移值永远不会变成“0”。C时钟在MIKRORT的编辑项目中80 MHz,因为所有的问候
以上来自于百度翻译 以下为原文 Thank you so much Weydert it is your kind that you explained the DMA and oscillator comepletly The MikroC compiler does not support '' __builtin_... ,right'' function I search in http://forum.mikroe.com/ and in one of the topics, I noticed that if I want to configure the oscillator I have to do it in this path Project->edit Project->Oscillator Mode->Primary oscillator w/Pll and after that we must set the PLL in the code and then the oscillator configuration will be done aha so there is no need to write "absolute", thank you because of your investigation Mr. Weydert , I am so sorry but I have another question I could write the code to read ADC result from DMA with your helpful hint but I face a problem when I give 0volt to ADC pin , the ADC value is 296 and for another pin shows 310!!!! and when I give the pin 2.82 volt , it shows me 4095!!! and if I increase the input voltage, it shows just 4095!!! I check my circuit again and again and I did not see any fault and when I check the one ADC pin or two channels without DMA, I can read the right result from ADC !!! so I think the circuit and references do not have problem I must use DMA because I have to sample the ADC value less than 1ms here is my code /// Setup of LCD//// ***it LCD_RS at LATF8_bit; ***it LCD_EN at LATD3_bit; ***it LCD_D4 at LATC13_bit; ***it LCD_D5 at LATD0_bit; ***it LCD_D6 at LATD2_bit; ***it LCD_D7 at LATF7_bit; ***it LCD_RS_Direction at TRISF8_bit; ***it LCD_EN_Direction at TRISD3_bit; ***it LCD_D4_Direction at TRISC13_bit; ***it LCD_D5_Direction at TRISD0_bit; ***it LCD_D6_Direction at TRISD2_bit; ***it LCD_D7_Direction at TRISF7_bit; dma unsigned int dma_bufferA[2] absolute 0x7800;//Offset 0 DMA_START_ADDRESS = 0x4000; dma unsigned int dma_bufferB[2] absolute 0x7C00;//Offset 500 unsigned int DmaBuffer = 0; unsigned int ch17=0; unsigned int ch18=0; int flag = 0; char str[16]; char str_1[16]; AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer (Q15 format) Figure 16-14: ADC Output Format 70183D.pdf// AD1CON1bits.SSRC =2; // GP timer (Timer3 for ADC1, Timer5 for ADC2) compare ends sampling and starts conversion AD1CON1bits.ASAM = 0; // Sampling begins immediately after conversion AD1CON1bits.AD12B = 1; // 12-bit ADC operation When AD12B = 1, SIMSAM is: U-0, Unimplemented, Read as ‘0’ AD1CON2bits.BUFM = 0; AD1CHS0bits.CH0SA = 0; // MUXA +ve input selection (AIN0) for CH0 AD1CHS123bits.CH123SA = 0; // MUXA +ve input selection (AIN0) for CH1 AD1CHS123bits.CH123NA = 0; // MUXA -ve input selection (Vref-) for CH1 AD1CON2bits.SMPI = 1; AD1CON1bits.ADDMABM = 0; /*DMA buffers are written in Scatter/Gather mode. The module will provide a scatter/gather address to the DMA channel, based on the index of the analog input and the size of the DMA buffer */ AD1CON2bits.CSCNA=1; //Scan inputs // Scan Input Selections for CH0+ during Sample A bit AD1CON2bits.VCFG =0; //Vref+=AVDD Vref-=AVSS// AD1CON2bits.CHPS = 0; // Converts CH0 AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock AD1CON3bits.SAMC = 31; // Auto Sample Time = 31*Tad AD1CON3bits.ADCS = 1; // ADC Conversion Clock Tad=Tcy*(ADCS+1)4 AD1CON4bits.DMABL = 3; // Each buffer contains 8 words AD1CHS0bits.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0 AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0 AD1CHS0bits.CH0SA=17; AD1CHS0bits.CH0SA=18; AD1CHS0bits.CH0SB=17; AD1CHS0bits.CH0SB=18; AD1CSSH=0; AD1CSSHbits.CSS17=1; // Enable AN17 for channel scan AD1CSSHbits.CSS18=1; // Enable AN18 for channel scan AD1CSSL=0; //ADC1 INPUT SCAN SELECT REGISTER Low AD1PCFGL=0xFFFF; AD1PCFGH=0xFFFF; AD1PCFGHbits.PCFG17 = 0; // AN17 as Analog Input AD1PCFGHbits.PCFG18 = 0; // AN18 as Analog Input IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt AD1CON1bits.ADON = 1; // Turn on the A/D converter } // (1/40*10^6)=25*10^(-9) 4999*10^(-9)*499=124us void initTmr3() { TMR3 = 0x0000; PR3 = 4999; // Trigger ADC1 every 125usec IFS0bits.T3IF = 0; // Clear Timer 3 interrupt IEC0bits.T3IE = 1; // Disable Timer 3 interrupt T3CONbits.TON = 1; //Start Timer 3 } // DMA0 configuration // Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM // AMODE: Peripheral Indirect Addressing Mode // MODE: Continuous, Ping-Pong Mode // IRQ: ADC Interrupt void initDma0(void) { DMA0CONbits.AMODE = 0; // DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode /* Peripheral Indirect Addressing mode is a special addressing mode where the peripheral, not the DMA channel, provides the variable part of the DPSRAM address . ADC Peripheral Indirect Addressing mode defines a special addressing technique where data for each ADC channel is placed into its own buffer. For the example above, if the DMA channel is configured for Peripheral Indirect Addressing mode, DMA transfer moves ADC data into separate buffers */ DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode /////////////// DMA0CONbits.DIR = 0; /*If the Transfer Direction (DIR) bit in DMAxCON is clear, data is read from the peripheral (using the Peripheral Address as provided by DMAxPAD) and the destination write is directed to the DPSRAM DMA memory address offset (using DMAxSTA or DMAxSTB). */ ///////////// DMA0PAD=(int)&ADC1BUF0; DMA0CNT = 1; //(SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1; That is, a DMAxCNT value of ‘0’ will transfer one element DMA0REQ = 13; // Select ADC1 as DMA Request source DMA0STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset DMA0STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address //The DMA needs to know the DPSRAM address to read from or write to as an offset from the beginning of the DMA memory IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit DMA0CONbits.CHEN=1; // Enable DMA 0 } void DM0Interrupt() iv IVT_ADDR_DMA0INTERRUPT { if(DmaBuffer == 0) { ch17=dma_bufferA[0]; intToStr( ch17,str); UART1_Write_Text(str); UART1_Write('?'); ch18=dma_bufferA[1]; intToStr( ch18,str); UART1_Write_Text(str); UART1_Write(';'); } else { ch17=dma_bufferB[0]; intToStr( ch17,str); UART1_Write_Text(str); UART1_Write(','); ch18=dma_bufferB[1]; intToStr( ch18,str); UART1_Write_Text(str); UART1_Write_Text("t"); } DmaBuffer ^= 1; LATF.F4=~LATF.F4; IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag and prevent a pending interrupt. } void main() { //AD1PCFGH/AD1PCFGL: Port Configuration Register PORTA=0; PORTC=0; TRISA.F6= 1; TRISA.F7= 1; TRISF.F4= 0; TRISF.F5= 0; TRISB.F12= 0; TRISB.F13= 0; TRISC.F2= 1; // AN17 TRISC.F3= 1; // AN18 IPC1bits.DMA0IP=6; IPC2bits.T3IP=7; ///////////////PLL configue//////// // Configure Oscillator to operate the device at 40Mhz // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2 // Fosc= 8M*40/(2*2)=80Mhz for 8M input clock OSCCONbits.COSC=0b011; //0b 011 Primary oscillator (XT, HS, EC) with PLL //OSCCONbits.OSWEN=0x1; // CLKDIVbits.PLLPRE=0; // N1=2 N1=PLLPRE+2 CLKDIVbits.PLLPOST=0; // N2=2 N2=2*(PLLPost+1) PLLFBDbits.PLLDIV=38; // M=40 M=PLLDIV+2 ////////////// Disable Watch Dog Timer//////// RCONbits.SWDTEN=0; // Disable Watch Dog Timer ///////////////// Lcd_init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // CLEAR display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,1,"Hello"); delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); // CLEAR display InitAdc(); // Initialize the A/D converter to convert Channel 5 InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order initTmr3() ; UART1_Init(19200); UART1_Write_Text("test"); while(1){ } } it should be noted when I changed the "AD1CON3bits.SAMC "and "AD1CON3bits.ADCS " the offset value were changed but they never become '0' for 0 volt input I set MDC clock at 80 MHz in edit project of MikroC thank you so much because of everything best regards |
|
|
|
我将PR3更改为499999和499999,但是偏移值没有改变:(对于第22节中的最后一个代码,我使用了示例22-5)。微芯片释放的直接存储器存取(DMA)
以上来自于百度翻译 以下为原文 I changed PR3 to 49999 and 4999999 but the ofset value did not change :( for the last code I used the example 22-5 in Section 22. Direct Memory Access (DMA) that is released by microchip |
|
|
|
非常感谢您的关注,Weydert先生,我必须更改位,您说我的板布局没有任何问题,因为当我采样一个引脚,并且不需要使用DMA时,我可以在3.296V(AVDD)下获得0<8mv和4095(最大值是12位),但是当我使用DMA时,我没有问题。ACED不良偏移量:
以上来自于百度翻译 以下为原文 Thank you so much because of your attention Mr.Weydert I have to change the bits that you said I think my board layout did not have any problem because when I sample one pin and there is no need to use DMA, I can gain 0 at <8mv and 4095 (max. value for 12bit) at 3.296V (AVDD) but when I use DMA I faced bad offset :( |
|
|
|
嗨,我有一个FJ128GP708设备。检查了12位ADC扫描输入ANA1和ANA3,结果由DMA5传送。PIC与FRC时钟一起运行,ADC与内部RC时钟一起转换。结果看起来不错。所以我真的不知道你的代码或设备有什么问题。
以上来自于百度翻译 以下为原文 hi, I have a FJ128GP708 device. Checked 12bit ADC scanning inputs ANA1 and ANA3, results transfered by DMA5. Pic is running with FRC clock, ADC conversion with internal RC clock. The results are looking good. So I really don't know what is wrong with your code or device. |
|
|
|
您好,非常感谢韦德特先生,由于您的时间和注意力,我甚至用锁相环将振荡器模式改为FRC时钟,但结果没有改变:(为什么这么困惑?如果MyBoad布局有问题,我不能从一个通道采样得到正确的结果!!!!当我使用DMA时,我会面对这个问题:(我不知道我能做什么?)更改DSPIC并组装新的?我很感激Weydert先生,因为你的时间。
以上来自于百度翻译 以下为原文 Hi thank you so much Mr.Weydert because of your time and attention I even changed the oscillator Mode to FRC clock with PLL but the result did not change :( I am so confused whyyyy?? if My board layout has problem, I must not get right result from one channel sampling !!!! when I use DMA I face this problem :( I don't know what I can do? change the dspic and assemble new one? I am so thankful Mr.Weydert because of your time |
|
|
|
你好,NKurzman,因为你的关注,在采样一个频道时,我没有使用DMA,我只是使用ADC1BUF0,正如你知道的,对于多重采样,我必须在带有DMA的设备中使用DMA,而且我面临着这个问题。第一个,清理ADCBUF0,然后我采样第二个)我没有遇到任何问题,我可以得到正确的结果!!!!我如何设定采集时间?我认为只是设置Time3、AD1CON3BIT、ADC、AD1CON3BIT.ADRC和AD1CON3BITS。
以上来自于百度翻译 以下为原文 Hi thank you NKurzman because of your attention In sampling of one channel I did not use DMA and I just used ADC1BUF0 and as you know for multiple sampling I have to use DMA in devices with DMA, and I faced this problem It is so amusing for me When I use just ADCBUF0 for sampling 2 channels, (I sample first one and clean the ADCBUF0 then I sample the second one ) I do not face any problem and I can get right result !!!! How can I set acquisition time? I think just setting timer3,AD1CON3bits.ADCS,AD1CON3bits.ADRC and AD1CON3bits.SAMC is enogh best regard |
|
|
|
我给你我的33 FJ128GP708的代码:和你的代码有什么不同?我真的不知道有什么要注意的:-我不在乒乓模式下使用DMA来保持它更加简单。-我正在扫描3个输入来测试AD1CON2bits.SMPI和DMA5CNT的含义。-我使用ADC1-Inter.以及DMA5-Inter.。并且在两个中断中设置断点。-在我看来,如果扫描CH0上的多个输入,则不需要DMA。-MPLAB-X、XC16、ICD3:1-第一ADC1中断后的计时~4160Tcy->输入1转换完成~8160Tcy->输入2转换完成后的2秒ADC1中断在~12160Tcy->输入3转换完成后,~12223Tcy->所有三个输入在~16160Tcy->输入1转换完成后,~12223Tcy->所有三个输入在DMA缓冲区5-第四ADC1中断中准备就绪。两个ADC1中断之间的时间为4000Tcy(PR3被设置为3999),如果每个ADC1中断都能读取ADC1BUF0,就不需要使用DMA。-你能调试代码吗?-在没有任何T3 ISR的代码中?关于SAMC<4:0>:自动采样时间位(1,2)注1:该位仅当SSRC<2:0>位(ADxCON1<7:5>)=111.(DS70183D)时才使用,即当使用Timer3作为转换触发器SAMC值时被忽略。
以上来自于百度翻译 以下为原文 I give you the code for my 33FJ128GP708: void InitDMA5(); void InitADC1(); void InitTimer3(); //trigger for ADC conversion void InitTimer45(); //cycle counter void ReadT45(); #define NumInputsToScan 3 unsigned int DMABufferA[32] __attribute__((space(dma))); unsigned int DMABufferB[32] __attribute__((space(dma))); unsigned int ANAResult[NumInputsToScan]; volatile unsigned long TIC32=0; volatile unsigned int T32L=0; volatile unsigned int T32H=0; volatile unsigned int InputCount=0; int main() { ConfigureOscillator(); //40Mips InitADC1(); InitDMA5(); InitTimer3(); InitTimer45(); T3CONbits.TON=1; //start conversion trigger Nop(); Nop(); while (1) { Nop(); } } void InitTimer3() { T3CON=0; TMR3=0; PR3=3999; } void InitTimer45() { //cycle count in T5::T4 32 bit timer TMR4=0; TMR5=0; PR4=0xFFFF; PR5=0xFFFF; T4CONbits.T32=1; T4CONbits.TON=1; } void InitDMA5() { unsigned int i; for (i=0;i<32;i++) { DMABufferA=0; DMABufferB=0; } // DMA5STA=__builtin_dmaoffset(&DMABufferA); // DMA5STB=__builtin_dmaoffset(&DMABufferB); DMA5STA=(unsigned int)&DMABufferA; DMA5STB=(unsigned int)&DMABufferB; DMA5CON=0; DMA5CONbits.SIZE=0; //word DMA5CONbits.DIR=0; //from periphal DMA5CONbits.MODE0=0; //continuous, no ping-pong //DMA5CONbits.AMODE=0b10; //periphal indirect DMA5CONbits.AMODE=0; //register indirect with post-increment // sample from ADC1 DMA5PAD=(unsigned int)&ADC1BUF0; DMA5REQ=13; //IRQ for ADC1 DMA5CNT=NumInputsToScan-1; // interrupt after 3 transfers _DMA5IF=0; _DMA5IE=1; DMA5CONbits.CHEN=1; }; void InitADC1() { AD1CON1=0; AD1CON2=0; AD1CON3=0; AD1CON4=0; AD1CON2bits.VCFG=0b000; // Vref+=AVDD, Vref-=AVSS // CH0, 12bits ANA1,ANA2 and ANA3 scanning AD1CON1bits.AD12B=1; //12bits AD1CON1bits.ADDMABM=1; //fill buffer in order of conversion AD1CON1bits.FORM=0b000; //integer format //AD1CON1bits.SSRC=0b000; //clearing SAMP bits ends sampling and starts conversion AD1CON1bits.SSRC=0b010; //Timer3 starts conversion AD1CON1bits.ASAM=1; //automatic sampling AD1CON2bits.CHPS=0b00; //use channel 0 only AD1CON2bits.CSCNA=1; //scan inputs on CH0 AD1CON2bits.SMPI=NumInputsToScan-1; //3 conversions AD1CON3bits.ADRC=1; //use internal RC clock for conversion //CH0 configuration AD1CHS0=0; AD1CHS0bits.CH0NA=0; //negative input for CH0 is Vref- //Analog inputs to scan: AD1CSSL=0; AD1CSSH=0; AD1CSSLbits.CSS1=1; //ANA1 AD1CSSLbits.CSS2=1; //ANA2 AD1CSSLbits.CSS3=1; //ANA3 _AD1IF=0; _AD1IE=1; AD1CON1bits.ADON=1; //enable ADC1 } void ReadT45() { T32L=TMR4; T32H=TMR5HLD; TIC32=(long)T32H<<16; TIC32=TIC32|T32L; Nop(); } void __attribute__((interrupt,no_auto_psv)) _ADC1Interrupt() { unsigned int i; _AD1IF=0; i=ADC1BUF0; ReadT45(); //get Number of cycles ANAResult[InputCount]=i; InputCount++; if (InputCount>=NumInputsToScan) InputCount=0; Nop(); Nop(); } void __attribute__((interrupt,no_auto_psv)) _DMA5Interrupt() { _DMA5IF=0; ANAResult[0]=DMABufferA[0]; ANAResult[1]=DMABufferA[1]; ANAResult[2]=DMABufferA[2]; ReadT45(); //get Number of cycles Nop(); Nop(); Nop(); } What is different from your code? I really don't know Some things to notice: - I don't use DMA in ping-pong mode to keep it mores simple. - I'm scanning through 3 inputs to test the meaning of AD1CON2bits.SMPI and DMA5CNT. - I use ADC1-Interrupt as well as DMA5-Interrupt. And set a breakpoint in both interrupts. - From my point of view you don't need the DMA if scanning several inputs on CH0. - Timing in MPLAB-X, XC16, ICD3: 1- first ADC1 interrupt after ~ 4160 Tcy -> input 1 conversion finished 2- second ADC1 interrupt after ~ 8160 Tcy -> input 2 conversion finished 3- third ADC1 Interrupt after ~ 12160 Tcy -> input 3 conversion finished 4- first DMA5 Interrupt after ~ 12223 Tcy -> all three inputs are ready in the DMA buffer 5- fourth ADC1 interrupt after ~ 16160 Tcy -> input 1 conversion finished .... and so on Time between two ADC1 Interrupts is 4000 Tcy (as PR3 is set to 3999) No need to use the DMA if you can read the ADC1BUF0 every ADC1 Interrupt. Questions: - do you read the same analog input pin when using DMA and when not using DMA? - are you able to debug the code? -IEC0bits.T3IE = 1; // Disable Timer 3 interrupt still in your code without any T3 ISR? Hint about SAMC<4:0>: Auto Sample Time bits(1,2) Note 1: This bit is only used when the SSRC<2:0> bits (ADxCON1<7:5>) = 111. (DS70183D) i.e. when using Timer3 as conversion trigger SAMC value is ignored. |
|
|
|
你好,Weydertthank先生,因为每件事,非常抱歉,因为我的答复延误了。是的,我检查了2个电位器的电压值,当我没有DMA检查时,我没有遇到问题,但是这种方法我需要更多的时间来清洗ADCBUF0和初始ADC。对于下一次扫描,虽然我至少有1ms扫描我的频道,并获得样本,我很抱歉,但我有一些疑问1)这个功能的用途是什么?我的编译器(MikROC)不理解它,它类似吗?2)我不熟悉MPLAB,你是指DMA5中断向量和ADC1中断向量,分别用这些代码行吗?如果我理解得很好,它们的等价物是:3)是否需要配置//AD1PCFGH/AD1PCFGL:端口配置寄存器,并将ADC管脚设置为输入?4)如何读取Read T45()函数的值?有必要在代码中吗?5)我的最后一个问题,如果我想用UART发送ADC结果,我必须把UART发送代码放在While 1主函数循环中或DMA5中断函数中?非常感谢,因为所有的问候。
以上来自于百度翻译 以下为原文 Hello Mr.Weydert thank you sooooo much because of everything I am sorry because of my delay in answering Yes I did, and even I check the voltage values of 2 Potentiometers and when I check them without DMA, I face no problem but this method I need more time about 3-4 ms to clean ADCBUF0 and initial ADC for next scan though I have at least 1ms to scan my channels and get samples I am sorry but I have some questions 1)what is the usage of this function? Nop(); my compiler (MikroC) did not understand it,does it similar to asm nop; ? 2)I am not familiar with MPLAB, do you mean DMA5 interrupt vector and ADC1 interrupt vector respectively by these lines of your code? void __attribute__((interrupt,no_auto_psv)) _DMA5Interrupt() void __attribute__((interrupt,no_auto_psv)) _ADC1Interrupt() and if I understood them well, their equivalents are: void DM5Interrupt() iv IVT_ADDR_DMA5INTERRUPT void ADC1Interrupt() iv IVT_ADDR_ADC1INTERRUPT 3) is there any need to configure //AD1PCFGH/AD1PCFGL: Port Configuration Register and set the ADC pin as input? 4)How can I read the value of ReadT45() function? and is it necessary to be in the code? 5) My last question, If I want to send the ADC result with UART, I have to put UART sending codes in While(1) loop of main function or in DMA5 interrupt function? int main() { InitConfigureOscillator(); //40Mips Lcd_init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // CLEAR display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Out(1,1,"Hello"); delay_ms(1000); UART1_Init(19200); UART1_Write_Text("test"); Lcd_Cmd(_LCD_CLEAR); // CLEAR display InitADC1(); InitDMA5(); InitTimer3(); InitTimer45(); T3CONbits.TON=1; //start conversion trigger // Nop(); // Nop(); while (1) { ch17=ANAResult[0]; intToStr( ch17,str); UART1_Write_Text(str); UART1_Write(','); ch18=ANAResult[1]; intToStr( ch18,str); UART1_Write_Text(str); UART1_Write(','); ch22=ANAResult[2]; intToStr( ch22,str); UART1_Write_Text(str); UART1_Write(','); // Nop(); } } thank you so much because of everything best regards |
|
|
|
只有小组成员才能发言,加入小组>>
5178 浏览 9 评论
2003 浏览 8 评论
1931 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3177 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2228 浏览 5 评论
738浏览 1评论
622浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
509浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
636浏览 0评论
533浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 02:02 , Processed in 1.459803 second(s), Total 99, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号