Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

STM8L ADC YARDIM

Başlatan fatal16, 24 Nisan 2016, 21:28:57

fatal16

ADC EOC kesmesinin adresini bulamadım. Veya farklı bir sıkıntı bulamadım. Yardımcı olur musunuz ?

#include <iostm8l152c6.h>
#include <intrinsics.h>

#define   LED_OUTPUT1   PE_ODR_ODR7
#define   LED_OUTPUT2  PC_ODR_ODR7  
#define   BUTON_INPUT  PC_IDR_IDR1 

#define Timer4_Start (TIM4_CR1_CEN=1)
int i=0;
unsigned char ADCRL, ADCRH; 
unsigned int  ADCR;
unsigned int  ADC_Total;
unsigned char SampleCounter;
unsigned int  AverageADC;

void InitClock(void)
{
   CLK_ICKCR_HSION = 1;
   while(!CLK_ICKCR_HSIRDY);
   CLK_CKDIVR = 0x00;
   CLK_PCKENR1_PCKEN12 = 1;     //tim4 için clock aktif ediliyor
   CLK_PCKENR2_PCKEN20 = 1;     //adc için clock aktif ediliyor

}
 
void InitGPIO(void)
{
   // LED ÇIKIŞI (PE7)  E7
   PE_DDR_DDR7 = 1;             //Output
   PE_CR1_C17  = 1;             //Push-pull
   PE_CR2_C27  = 0;             //2Mhz
   PE_ODR_ODR7 = 0;             //LED_OUTPUT1 Output data
   // LED ÇIKIŞI (PC7)  C7
   PC_DDR_DDR7 = 1;
   PC_CR1_C17  = 1;
   PC_CR2_C27  = 1;             //10Mhz
   PC_ODR_ODR7 = 0;             //LED_OUTPUT2 Output data
 /*
   // BUTON GİRİŞİ (PC1)   C1
   PC_DDR_DDR1 = 0;     //set PC1 as input
   PC_CR1_C11  = 0;     //set PC1 as floating input.
   PC_CR2_C21  = 1;     //External input enable*/
  
   // ADC GİRİŞİ(ADC_IN0) (PA6)   C1
   PA_DDR_DDR6 = 0;     //set PA6 as input
   PA_CR1_C16  = 0;     //set PA6 as floating input.
   PA_CR2_C26  = 0;
}

void InitTim4(void)
{
  TIM4_CR1_ARPE = 1;
  TIM4_IER_UIE  = 1;            //update interrupt kesmesi aktif
  TIM4_PSCR_PSC = 6;            //prescaler değeri 6
  TIM4_CR1_CEN = 1;             //Tim4 counter(sayıcısı) aktif ediliyor
  TIM4_ARR      = 0xFA;         //sayıcı değeri 250 olarak ayarlanıyor
                                //Timer4 sayıcı değeri 250 değerine eşitlendiğinde kesme oluşturacak
}

void InitADC(void)
{
  ADC1_CR1_EOCIE=1;     // ADC Interrupt Enable
  ADC1_CR3_CHSEL = 0;   // Channel 0 select
  ADC1_CR2_PRESC=1;     // Fmaster/2
  ADC1_CR1_CONT=0;      // Single Conversion
  ADC1_CR1_ADON = 1;    // ADC ON
  ADC1_CR1_RES = 0;     //12bit adc
  //ADC1_CR1_START=1;
  
}
 
void main(void)
{
  __disable_interrupt();
  InitClock();
  InitGPIO();
  InitTim4();
  InitADC();
  LED_OUTPUT1=1;
  LED_OUTPUT2=1;
  Timer4_Start;
  
  __enable_interrupt();
  for(;;)
  {
    if(ADCR>1000)
    {
        LED_OUTPUT2=1;
    }
     else if(ADCR<=1000)
    {
        LED_OUTPUT2=0;
    }
  }
}

#pragma vector=TIM4_UIF_vector
__interrupt void Timer4_ISR(void)
{
  TIM4_SR1_UIF = 0;              //Kesme bayrağını temizleme
  ADC1_CR1_ADON = 1;             //ADC enabled
  i = i+1;
  if (i==100)
  {
    i=0;
    LED_OUTPUT1 = !LED_OUTPUT1;
  }
}

#pragma vector=ADC1_EOC_vector
__interrupt void ADC_ISR(void)
{
  ADC1_SR_EOC = 0;                      //ADC bayrağını temizleme
  ADCRL = ADC1_DRL, ADCRH = ADC1_DRH;   //ADC Verisinin Yüksek ve Düşük değerlikli bitleri atanıyor
  ADCR = ((ADCRH & 0x03)<<8) | ADCRL;   //Bu değerler seçimimize göre 12-10-8-6 bit şekline getiriliyor

}


WrtM

biraz saçma olacak ama, sanırsam aynı vector adresi  config dosyasında

#define COMP_EF2_vector                      0x14
#define COMP_EF1_vector                      0x14   şelinde ADC_EOC interruptı ile payşaılıyor o yüzden yazmamış olabilirler.

Bu şekilde deneyebilir misiniz?

#pragma vector=0x14
__interrupt void ADC_ISR(void)
{
  ADC1_SR_EOC = 0;                      //ADC bayrağını temizleme
  ADCRL = ADC1_DRL, ADCRH = ADC1_DRH;   //ADC Verisinin Yüksek ve Düşük değerlikli bitleri atanıyor
  ADCR = ((ADCRH & 0x03)<<8) | ADCRL;   //Bu değerler seçimimize göre 12-10-8-6 bit şekline getiriliyor


fatal16

#3
@WrtM teşekkür ederim Datasheet'de aynı vector olduğu yazıyormuş ama onu da görememişim.

Artık kesmeye girebiliyorum ama Okuma işini düzgünce yapamadım ney eksik hala anlamış değilim.

Standart Peripheral Library ile 15dk geçmeden adc okumasını yapmıştım bu şekilde daha uğraştıracak sanırım.

#include <iostm8l152c6.h>
#include <intrinsics.h>

#define ADC1_EOC_vector 0x14
#define LED_OUTPUT1     PE_ODR_ODR7
#define LED_OUTPUT2     PC_ODR_ODR7  
#define BUTON_INPUT     PC_IDR_IDR1 

#define Timer4_Start (TIM4_CR1_CEN=1)
int i=0;
unsigned int    ADCRL, ADCRH; 
unsigned int    ADCR;

void InitClock(void)
{
   CLK_ICKCR_HSION = 1;
   while(!CLK_ICKCR_HSIRDY);
   CLK_CKDIVR = 0x00;
   CLK_PCKENR1_PCKEN12 = 1;     //tim4 için clock aktif ediliyor
   CLK_PCKENR2_PCKEN20 = 1;     //adc için clock aktif ediliyor
}
 
void InitGPIO(void)
{
   // LED ÇIKIŞI (PE7)  E7
   PE_DDR_DDR7 = 1;             //Output
   PE_CR1_C17  = 1;             //Push-pull
   PE_CR2_C27  = 0;             //2Mhz
   PE_ODR_ODR7 = 0;             //LED_OUTPUT1 Output data
   // LED ÇIKIŞI (PC7)  C7
   PC_DDR_DDR7 = 1;
   PC_CR1_C17  = 1;
   PC_CR2_C27  = 1;             //10Mhz
   PC_ODR_ODR7 = 0;             //LED_OUTPUT2 Output data 
   // BUTON GİRİŞİ (PC1)   C1
   PC_DDR_DDR1 = 0;     //set PC1 as input
   PC_CR1_C11  = 0;     //set PC1 as floating input.
   PC_CR2_C21  = 1;     //External input enable  
   // ADC GİRİŞİ(ADC_IN0) (PA6)   A6
   PA_DDR_DDR6 = 0;     //set PA6 as input
   PA_CR1_C16  = 0;     //set PA6 as floating input.
   PA_CR2_C26  = 0;
}

void InitTim4(void)
{
  TIM4_CR1_ARPE = 1;
  TIM4_IER_UIE  = 1;            //update interrupt kesmesi aktif
  TIM4_PSCR_PSC = 6;            //prescaler değeri 6
  TIM4_CR1_CEN = 1;             //Tim4 counter(sayıcısı) aktif ediliyor
  TIM4_ARR      = 0xFA;         //sayıcı değeri 250 olarak ayarlanıyor
                                //Timer4 sayıcı değeri 250 değerine eşitlendiğinde kesme oluşturacak
}

void InitADC(void)
{
  ADC1_CR1_EOCIE=1;     // ADC Interrupt Enable
  ADC1_CR3_CHSEL = 0;   // Channel 0 select
  ADC1_CR2_PRESC=1;     // Fmaster/2
  ADC1_CR2_SMTP1=7;     // 384 ADC Clock Cycles
  ADC1_CR1_CONT=1;      // Continuous Conversion
  ADC1_CR1_RES = 0;     //12bit adc
  ADC1_CR1_ADON = 1;    // ADC ON
  ADC1_CR1_START=1;     //Conversion start
}
 
void main(void)
{
  __disable_interrupt();
  InitClock();
  InitGPIO();
  InitTim4();
  InitADC();
  LED_OUTPUT1=1;
  LED_OUTPUT2=1;
  Timer4_Start;
  
  __enable_interrupt();
  for(;;)
  {
    if(ADCR>1000)       LED_OUTPUT2=1;
    else if(ADCR<=1000) LED_OUTPUT2=0;
  }
}

#pragma vector=TIM4_UIF_vector
__interrupt void Timer4_ISR(void)
{
  i++;
  if (i==100)
  {
    i=0;
    LED_OUTPUT1 = !LED_OUTPUT1;   
  }
  TIM4_SR1_UIF = 0;              //Kesme bayrağını temizleme
}


#pragma vector=ADC1_EOC_vector
__interrupt void ADC_ISR(void)
{
  ADCRL = ADC1_DRL, ADCRH = ADC1_DRH;   //ADC Verisinin Yüksek ve Düşük değerlikli bitleri atanıyor
  //ADCR = ((ADCRH & 0x0F)<<8) | ADCRL;   //Bu değerler seçimimize göre 12-10-8-6 bit şekline getiriliyor
  ADCR = (ADCRH <<8) | ADCRL;
  ADC1_SR_EOC = 0;                      //ADC bayrağını temizleme
}

fatal16

ADC Channel 0 için taramayı aktif edince çalıştı :) 

Scan Mod ve DMA ile ilgili bir register olduğunu sandığım için hiç dokunmamıştım.

Yardımcı olan herkese teşekkürler.