Ingo Electronics


    HOME                                                           Stellaris LM4F120 LaunchPad


  Stellaris LM4F120 LaunchPad.     ADC

Visų, žemiau tekste pavartotų funkcijų vardus ir parametrų reikšmes galima rasti atsidarius Includes/StellarisWare/driverlib/adc.c ir adc.h failus !!! 

Kai kurie vertimo iš angl. kalbos terminai  naudojami šiame tekste ir gali būti randami mikrokontrolerio pdf aprašyme:

sample                  - matavimas

sample rate           - matavimų greitis

sequencer             - matavimų konfiguratorius   (SequenceNum 0,1,2,3) sample sequence    - matuojama eilė,žingsnis     (Step 1-8, 1-4, 1)

triger                   - signalas pradėti matavimą

Yra du 12bitų ADC moduliai, prie kurių gali būti prijungiama 12 analoginių kanalų, atitinkamai juos komutuojant, norimu eiliškumu ir tvarka.


Pirmiausia inicializuojami reikalingi  matavimo kanalai.

Kiekvienas kanalas yra priskirtas konkrečiam mikrovaldiklio išvadui:

AIN0 – PE3     AIN4 – PD3     AIN8    PE5

AIN1 – PE2     AIN5 – PD2     AIN9    PE4

AIN2 – PE1     AIN6 – PD1     AIN10 – PB4

AIN3 – PE0     AIN7 – PD0     AIN11 – PB5

Pasirinkus reikiamus išvadus įjungiame, portų taktavimą, kurie priklauso pasirinktiems matavimo kanalams.
Pvz.:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

Pasirinktus kanalus padarome analoginiais įėjimais. Pvz:
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0);
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);

Įjungiame taktavimą pasirinktam ADC moduliui:
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
arba(ir)
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);

Nustatome matavimų greitį (sample rate).
SysCtlADCSpeedSet(Speed);
//******************************************************************************************
//parametras Speed gali turėti sekančias reikšmes:

 SYSCTL_ADCSPEED_1MSPS   // 1,000,000 samples per second

 SYSCTL_ADCSPEED_500KSPS // 500,000 samples per second

 SYSCTL_ADCSPEED_250KSPS // 250,000 samples per second

 SYSCTL_ADCSPEED_125KSPS // 125,000 samples per second

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

Pagal nutylėjimą default sample rate yra 125KSPS, todėl jeigu pakanka tokio greičio, jo papildomai nustatyti nebūtina.

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

Esant reikalui, faktinį matavimų greitį galime gauti su f-ja:

SysCtlADCSpeedGet();

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

Mikrovaldiklio ADC turi taip vadinamą Hardware Averager modulį, kuris suvidurkina nustatytą skaičių matavimų .

Pagal pirminius mikrovaldiklio nustatymus,šis modulis yra išjungtas.

Šis modulis įjungiamas ir nustatomas matavimų skaičius, iš kurių apskaičiuojama vidutinė vertė f-ja:

ADCHardwareOversampleConfigure(ADC0_BASE, 64);

//Gali būti sekantis matavimų skaičius: 2, 4, 8, 16, 32, arba 64. //0 – modulis išjungtas

 
Šis modulis yra įjungiamas visam ADC moduliui bendrai, todėl tokiu atveju bus vidurkinamas kiekvienas pasirinktas kanalas.

Naudojant Hardware Averager modulį, į FIFO buferį yra įrašoma vidutinė matavimų reikšmė.

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

Konfiguratoriaus inicializavimas

Prieš atliekant toliau nurodytus veiksmus, patartina išjungti konfiguratorių f-ja: pvz.

ADCSequenceDisable(ADC0_BASE, 2);

Kiekvienas ADC modulis turi keturis matavimų konfiguratorius, kurie skiriasi tik matavimo žingsnių skaičiumi:

Sequencer0 – 8žingsniai

Sequencer1 – 4žingsniai

Sequencer2 – 4žingsniai

Sequencer3 – 1žingsnis

Matavimų konfiguratorius yra inicializuojamas funkcija, kurioje nurodomas ADC modulis, konfiguratoriaus nr., signalas pradėti matavimą ir matavimų prioritetas.

ADCSequenceConfigure(Base,SequenceNum,Trigger,Priority);

Pvz.:
ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

Jeigu yra naudojami keli matavimų konfiguratoriai, tai prioritetų reikšmės visiems turi būti skirtingos.

TRIGGER nurodo iš kokio šaltinio yra gaunamas signalas matavimų konfiguratoriams pradėti skanavimą.

TRIGGER šaltinis nustato skanavimo dažnį (nemaišyti su sample rate).  

//Prioritetų reikšmės gali būti pasirenkamos:  0,1,2,3

//Gali būti pasirinkti sekantys Trigger parameterai.

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

ADC_TRIGGER_PROCESSOR     // Processor event

ADC_TRIGGER_COMP0         // Analog comparator 0 event

ADC_TRIGGER_COMP1         // Analog comparator 1 event

ADC_TRIGGER_COMP2         // Analog comparator 2 event

ADC_TRIGGER_EXTERNAL      // External event

ADC_TRIGGER_TIMER         // Timer event

ADC_TRIGGER_PWM0          // PWM0 event

ADC_TRIGGER_PWM1          // PWM1 event

ADC_TRIGGER_PWM2          // PWM2 event

ADC_TRIGGER_PWM3          // PWM3 event

ADC_TRIGGER_ALWAYS        // Always event

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

Matavimo žingsnių konfiguravimas

Kiekvienas žingsnis atlieka tik jam skirtą t.y jam sukonfiguruotą matavimą, kuriame yra nurodoma:

Įėjimo šaltinis.

Matavimo režimas.

Pertraukimų rodyklės generavimas atlikus matavimą.

Galutiniame žingsnyje būtina nurrodyti, kad tai paskutinis matavimas.

Paskutinis matavimas gali būti nurodomas bet kuriame žingsnyje, nepriklausomai kiek žingsnių turi konfiguratorius.

Matavimo žingsnio konfiguravimą atlieka funkcija ADCSequenceStepConfigure

Pvz.: konfigurujame du žingsnius:
ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);

 
ADCSequenceStepConfigure(Base,SequenceNum,Step,Config);

//******************************************************************************************
// Reikšmės kurios gali būti naudojamos kaip Config
parameteras.
//******************************************************************************************

ADC_CTL_TS              // Temperature sensor select//OR
ADC_CTL_IE              // Interrupt enable//OR
ADC_CTL_END             // Sequence end select//OR
ADC_CTL_D               // Differential select//OR
ADC_CTL_CH0             // Input channel 0
ADC_CTL_CH1             // Input channel 1
ADC_CTL_CH2             // Input channel 2
ADC_CTL_CH3             // Input channel 3
ADC_CTL_CH4             // Input channel 4
ADC_CTL_CH5             // Input channel 5
ADC_CTL_CH6             // Input channel 6
ADC_CTL_CH7             // Input channel 7
ADC_CTL_CH8             // Input channel 8
ADC_CTL_CH9             // Input channel 9
ADC_CTL_CH10            // Input channel 10
ADC_CTL_CH11            // Input channel 11

ADC_CTL_CMP0            // Select Comparator 0
ADC_CTL_CMP1            // Select Comparator 1
//******************************************************************************************

 Po kiekvieno žingsnio, matavimo rezultatas yra įrašomas į FIFO buferį.

Matavimų rezultatus galima nuskaityti  f-ja  ADCSequenceDataGet(Base,SequenceNum,*pulBuffer)

Pvz.:
ADCSequenceDataGet(ADC0_BASE, 1, ADC0Value);

čia ADC0Value buferis į kurį sudedami matavimo rezultatai. Pvz.: unsigned long ADC0Value[4];

Ši funkcija nuskaito visus FIFO buferyje esančius matavimų rezultatus, todėl buferis į kurį bus talpinami gauti rezultatai turi būti nemažesnio ilgio, negu buvo atlikta matavimo žingsnių.

F-ja ADCSequenceDataGet grąžina matavimo rezultatų skaičių, t.y parodo kiek buvo užimtas FIFO buferis.

Nuskaičius FIFO buferį, jame esantys duomenys automatiškai pašalinami, ir ta pačia tvarka gali būti vėl talpinami nauji rezultatai.

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

Programinių pertraukimų inicializavimas   (Interrupts)

Kiekvienas matavimų konfiguratorius gali generuoti pertraukimų rodykles.

ADC modulio pertrukimai yra konfiguruojami sekančia tvarka:

Atlikus paskutinį matavimo žingsnį gali būti generuojama pertraukimų rodyklė, jeigu tai yra numatyta f-joje ADCSequenceStepConfigure

 
Programiniai pertraukimai inicializuojami sekančia tvarka:

//užregistruojame kokia bus naudojama pertraukimų f-ja

ADCIntRegister(Base, SequenceNum,interrupt_name);

Pvz.: ADCIntRegister(ADC0_BASE, 3,adc_interrupt);

čia: adc_interrupt - pertraukimų funkcijos vardas (šią funkciją reikia pasirašyti patiems), kuri bus vykdoma atsiradus pertraukimų rodyklei, šiuo atveju trečiame matavimų konfiguratoriuje. 

 
//leidžiame generuoti pertraukimų rodykles f-joje nurodytam matavimų konfiguratoriui

ADCIntEnable(Base, SequenceNum);

Pvz.: ADCIntEnable(ADC0_BASE, 3);

 
//Leidžiame generuoti pertraukimų rodykles f-joje nurodytam ADC moduliui

IntEnable(INT_ADC0); arba IntEnable(INT_ADC1); 

//leidžiami globalūs pertraukimai

IntMasterEnable();

//pertraukimų rodyklės panaikinimas

ADCIntClear(Base, SequenceNum);

Pvz.: ADCIntClear(ADC0_BASE, 3);

//išvalome FIFO buferį (jeigu būtina)

ADCSequenceDataGet(ADC0_BASE, 3, Data_buff);

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

Baigus kofiguruoti ir inicializuoti ADC, įjungiame visus sukonfiguruotus konfiguratorius

Pvz.:

ADCSequenceEnable(ADC0_BASE, 2);

ADCSequenceEnable(ADC0_BASE, 3);

ADCSequenceEnable(ADC1_BASE, 0);

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

//Programinių pertraukimų inicializavimas baigtas

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

Esant reikalui, pertraukimų rodyklės būsena (true arba false) gali būti nuskaitoma panaudojus f-ją:

ADCIntStatus(Base, SequenceNum, true);

arba

ADCIntStatus(Base, SequenceNum, false);

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

Žemiau yra pateiktas paprastas ADC konfiguravimo pavyzdys, skirtas mokymosi tikslais.

Turime pasirinkę du analoginius kanalus: AIN0(PE3) ir  AIN2(PE1) .

Naudojame taimerį matavimų trigeriavimui.

Vaizdumo dėlei pasirinkto taimerio periodą padarome maksimalų.

Šiame pavyzdyje matavimų rezultatai niekur nėra išvedami, todėl jų stebėjimui pasinaudosime CCS esančiu debugeriu.

ADC pertraukimų funkcijoje yra įvesta LED indikaciją.

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

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h" 

unsigned int state;
unsigned long Data_buff[2]; 
volatile unsigned long PE1_channel;
volatile unsigned long PE3_channel;

//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
void init_timer(){

       SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

       TimerConfigure(TIMER0_BASE,TIMER_CFG_SPLIT_PAIR |  TIMER_CFG_A_PERIODIC_UP);

       //TimerPrescaleSet(TIMER0_BASE, TIMER_A,0x4C);

       TimerPrescaleSet(TIMER0_BASE, TIMER_A,0xFF);

       //TimerLoadSet(TIMER0_BASE, TIMER_A, 0x4B40);

       TimerLoadSet(TIMER0_BASE, TIMER_A, 0xFFFF);

       //Enable the ADC trigger output on time-out event .

       TimerControlTrigger(TIMER0_BASE, TIMER_A,true);

       TimerEnable(TIMER0_BASE, TIMER_A);

}

//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

void adc_interrupt(){

ADCIntClear(ADC0_BASE, 2);

state = ~state&0x08;
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3,state);

ADCSequenceDataGet(ADC0_BASE, 2, Data_buff);

PE3_channel = Data_buff[0];
PE1_channel = Data_buff[1];

}

//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

void main(){

       //200/4=50Mhz

       SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

 

             SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

              GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3);

              GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x00);

 

        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1| GPIO_PIN_3);

 

        ADCSequenceDisable(ADC0_BASE, 2);

        ADCSequenceConfigure(ADC0_BASE, 2,ADC_TRIGGER_TIMER, 0);

        //ADCHardwareOversampleConfigure(ADC0_BASE, 64);

        ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH0);

        ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);

 

        ADCIntRegister(ADC0_BASE,2,adc_interrupt);

        ADCIntEnable(ADC0_BASE,2);

        IntEnable(INT_ADC0);

        IntMasterEnable();

        ADCIntClear(ADC0_BASE,2);

        //išvalome FIFO buferį

        ADCSequenceDataGet(ADC0_BASE,2, Data_buff);

        ADCSequenceEnable(ADC0_BASE,2);

 

        init_timer();

 

while(1){ }

      

}//end main

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

 

1. Sukompiliuojame aukščiau pateiktą programos kodą: Project>>Build Project

2. Toliau: Run>>Debug

3. Į lentelę Expressions įkeliame kintamujų vardus: PE1_channel ir PE3_channel

capture20

4. Parenkame Breakpoint tašką: programos kode ties adc_interrupt funkcijos pabaiga su dešiniu pelės klavišu pasirenkame menu Breakpoint(Code Composer Studio)>>Breakpoint Atsiranda piktograma:
capture19

5. Su dešiniu pelės klavišu spaudžiame ant piktogramos, pasirenkame Breakpoint Properties..
6. Atsiradusiame Breakpoint Properties lange, lentelės eilutėje Action iš menu pasirenkame Update View capture21
7. Spaudžiame capture22 Resume(F8),  lentelėje Expression realiu laiku matome kokie yra ir kaip kinta PE1_channel ir PE3_channel.