forum.mcontrollers.com - hlavní stránka forum.mcontrollers.com - fórum

 

.: fórum - hlavní stránka :.
Technology Stronghold by Rudolf Vesely
How to build Microsoft System Center hosted cloud series
FAQFAQ HledatHledat Seznam uživatelůSeznam uživatelů Uživatelské skupinyUživatelské skupiny RegistraceRegistrace
ProfilProfil StatistikaStatistika Soukromé zprávySoukromé zprávy PřihlášeníPřihlášení

 
Discovery STM32F0 problemy s AD prevodem

 
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> ARM
 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 23 červenec 2015, 16:54    Předmět: Discovery STM32F0 problemy s AD prevodem Citovat

Dobry den, chci se poradit s AD prevodem na vyvojovem kitu discovery STM32F0, pouzivam vyvojove prostredi CoIDE.

V mem kodu AD prevod nefunguje, ale kdyz zakomentuju inicializaci SPI, tak najednou funguje. Nevim v cem je problem, kdyz kod debuguju, tak se zasekne na radku:

while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion

Budu vdecny za kazdou radu.

kód:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include <stm32f0xx.h>
#include <stm32f0xx_gpio.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_usart.h>
#include <stm32f0xx_spi.h>
#include <stm32f0xx_adc.h>
#include <stm32f0xx_misc.h>

#include <stm32f0xx_conf.h>

#define LED_GREEN   GPIO_Pin_9
#define LED_BLUE   GPIO_Pin_8
#define USER_BUTTON   GPIO_Pin_0

//DDS RESET
#define DDS_MSTR_RST GPIO_Pin_4      //PA4

//DDS IO UPDATE
#define DDS_IO_UPD GPIO_Pin_6      //PA6

//DDS SCLK
#define DDS_SCLK GPIO_Pin_5         //PA5


#define DDS_SDIO_0 GPIO_Pin_7      //PA7

//SDIO_3
#define DDS_SDIO_3 GPIO_Pin_0      //PC0

//RANGE_1 R = 5k
#define RANGE_1 GPIO_Pin_13         //PB13

//RANGE_2 R = 50R
#define RANGE_2 GPIO_Pin_14         //PB14

//RANGE_3 R = 500R
#define RANGE_3 GPIO_Pin_15         //PB15

//CHANNEL SWITCH
#define CH_SWITCH GPIO_Pin_6      //PC6

//UART RX             PA3
//UART TX             PA2




void delay_ad9958(int a)
{
   volatile int i,j;

   for (i=0 ; i < a ; i++)
   {
      j++;
   }

   return;
}


void io_update(void)
{
   GPIO_ResetBits(GPIOA,DDS_IO_UPD);
   delay_ad9958(200000);
   GPIO_SetBits(GPIOA,DDS_IO_UPD);
   delay_ad9958(200000);
   GPIO_ResetBits(GPIOA,DDS_IO_UPD);

   return;
}


void AD9958_Set_Ch0_Phase(unsigned int phase)// in deg
{
   unsigned int PTW = 0;
   float temp;
   unsigned char CPOW0_1, CPOW0_0;


   temp = phase*45.5111;
   PTW = (unsigned int)temp;

   CPOW0_1 = (PTW & 0x3f00) >> 8;
   CPOW0_0 = (PTW & 0x00ff);

   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x00);   //CSR registr
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0x70);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x05);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CPOW0_1);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CPOW0_0);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x00);   //CSR registr
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0xF0);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   io_update();
}


void AD9958_Set_Freq(unsigned int freq)// frequency in Hz
{
   unsigned long FTW = 0;
   float temp;
   unsigned char CFTW0_3, CFTW0_2, CFTW0_1, CFTW0_0;

   temp = freq*8.589934592;
   FTW = (unsigned long)temp;

   CFTW0_3 = (FTW & 0xff000000) >> 24;
   CFTW0_2 = (FTW & 0x00ff0000) >> 16;
   CFTW0_1 = (FTW & 0x0000ff00) >> 8;
   CFTW0_0 = (FTW & 0x000000ff);


   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x04);   //CFTWo registr
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CFTW0_3);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CFTW0_2);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CFTW0_1);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,CFTW0_0);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   io_update();
}


void USART_Send_String(USART_TypeDef* USARTx,volatile char *str)
{
   while(*str)
   {
      while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE) == RESET);
      USART_SendData(USARTx,*str);
      str++;
   }
}


float AD_conversion(char channel)
{
   unsigned int pom;
   float pom2;

   if (channel == 0)
   {
      ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_239_5Cycles);      //8~PB0;9~PB1
   }
   else
   {
      ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_239_5Cycles);
   }


   ADC_StartOfConversion(ADC1);

   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion

   pom = ADC_GetConversionValue(ADC1);

   pom2 = (float) pom;
   pom2 = pom2*(3.0/4096);

   return(pom2);
}


/*========== global_variables ==========*/
char rec_buffer[10];
unsigned int RxCnt;
unsigned int MyNumber;
unsigned int MyNumberValid;
double R;                     //rezistor in bridge
/*======================================*/


int main(void)
{
   float value;
   char print_value[50];
   int i = 0;


   GPIO_InitTypeDef GPIO;
   USART_InitTypeDef USART;
   SPI_InitTypeDef SPI;
   ADC_InitTypeDef ADC_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE);
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0);

/*==================USART=====================*/
   GPIO.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
   GPIO.GPIO_Mode = GPIO_Mode_AF;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_3;
   GPIO_Init(GPIOA,&GPIO);

   USART.USART_BaudRate = 9600;
   USART.USART_WordLength = USART_WordLength_8b;
   USART.USART_StopBits = USART_StopBits_1;
   USART.USART_Parity = USART_Parity_No;
   USART.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

   USART_Init(USART2, &USART);
   USART_Cmd(USART2, ENABLE);

   NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);

   USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

/*==================SPI=====================*/
   GPIO.GPIO_Pin = DDS_SCLK | DDS_SDIO_0;
   GPIO.GPIO_Mode = GPIO_Mode_AF;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_3;
   GPIO_Init(GPIOA,&GPIO);

   GPIO.GPIO_Pin = DDS_MSTR_RST | DDS_IO_UPD;
   GPIO.GPIO_Mode = GPIO_Mode_OUT;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_1;
   GPIO_Init(GPIOA,&GPIO);

   GPIO.GPIO_Pin = DDS_SDIO_3;
   GPIO.GPIO_Mode = GPIO_Mode_OUT;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_1;
   GPIO_Init(GPIOC,&GPIO);

   SPI.SPI_Direction = SPI_Direction_1Line_Tx;
   SPI.SPI_Mode = SPI_Mode_Master;
   SPI.SPI_DataSize = SPI_DataSize_8b;
   SPI.SPI_CPOL = SPI_CPOL_Low;
   SPI.SPI_CPHA = SPI_CPHA_1Edge;
   SPI.SPI_NSS = SPI_NSS_Soft;
   SPI.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
   SPI.SPI_FirstBit = SPI_FirstBit_MSB;

   SPI_Init(SPI1, &SPI);
   SPI_Cmd(SPI1,ENABLE);

/*===========DEAFULT_DDS_SETTINGS=============*/
   GPIO_SetBits(GPIOA, DDS_MSTR_RST);
   delay_ad9958(200000);
   GPIO_ResetBits(GPIOA, DDS_MSTR_RST);


   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x00);   //CSR registr, channel settings
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0xF0);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x01);   //FR1 registr, PLL divider
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0xD0);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0x00);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0x20);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   //default frequency 100 kHz
   AD9958_Set_Freq(100000);

   GPIO_ResetBits(GPIOC, DDS_SDIO_3);
   SPI_SendData8(SPI1,0x06);   //amplitude 333 mV
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0b00010000);
   delay_ad9958(20000);
   SPI_SendData8(SPI1,0x15);
   delay_ad9958(20000);
   GPIO_SetBits(GPIOC, DDS_SDIO_3);
   delay_ad9958(20000);

   io_update();
   delay_ad9958(20000);

/*==================OTHERS=====================*/
   GPIO.GPIO_Pin = LED_BLUE | LED_GREEN | CH_SWITCH;
   GPIO.GPIO_Mode = GPIO_Mode_OUT;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_1;
   GPIO_Init(GPIOC,&GPIO);

   GPIO.GPIO_Pin = RANGE_1 | RANGE_2 | RANGE_3;
   GPIO.GPIO_Mode = GPIO_Mode_OUT;
   GPIO.GPIO_OType = GPIO_OType_PP;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO.GPIO_Speed = GPIO_Speed_Level_1;
   GPIO_Init(GPIOB,&GPIO);

   GPIO.GPIO_Pin = USER_BUTTON;
   GPIO.GPIO_Mode = GPIO_Mode_IN;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOA,&GPIO);

   GPIO_SetBits(GPIOC, LED_BLUE);
   GPIO_ResetBits(GPIOC, LED_GREEN);

/*==================ADC=====================*/
   GPIO.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
   GPIO.GPIO_Mode = GPIO_Mode_AN;
   GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOB,&GPIO);

   ADC_DeInit(ADC1);
   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
   ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
   ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
   ADC_Init(ADC1, &ADC_InitStructure);
   ADC_Cmd(ADC1, ENABLE);

/*=============================================*/

   while(1)
    {

      //if(strcmp(rec_buffer, "m\r")==0)
      //{
         USART_Send_String(USART2,"voltage: ");
         value = AD_conversion(1);
         sprintf(print_value,"%f",value);   //lf for double
         USART_Send_String(USART2, print_value);
         USART_Send_String(USART2,"\r\n");
/*
         for(i=0;i<11;i++)
         {
           rec_buffer[i] = '\0';
         }
         RxCnt = 0;
      }
*/

      delay_ad9958(1500000);
    }
}


/*=============================================*/
/*=============================================*/


void USART2_IRQHandler(void)
{
   char char_buff;
   char buff[50];
   int i = 0;


   if((USART_GetITStatus(USART2, USART_IT_RXNE) != RESET))
   {
      char_buff = (unsigned char)(USART_ReceiveData(USART2));
   }

   sprintf(buff,"%c",char_buff);
   USART_Send_String(USART2,buff);
/*
   if(char_buff == 13)
   {
      MyNumber = atoi(rec_buffer);
      if (MyNumber > 0)
      {
        MyNumberValid = 1;
      }

      for(i=0;i<11;i++)
      {
        rec_buffer[i] = '\0';
      }

      RxCnt = 0;
   }
*/
   rec_buffer[RxCnt] = char_buff;
   RxCnt++;
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
Jan16
moderátor
moderátor


Založen: 10.3.2008
Příspěvky: 547

PříspěvekZaslal: 10 leden 2016, 12:42    Předmět: Citovat

A jak to prosím vypadá v debugu? (nebo ten nepoužíváš?)

Co je za hodnoty v registrech ADC? Zřejmě asi když nechce ADC hodit EOC flag, tak nekonvertuje.

Není v těchto případech nic vhodnějšího, než do debugu vlézt, otevřít registry ADC a ručně si zaklikat a zjistit, co tomu chybí.

Kód jsem prošel, vypadá v pořádku, až na pár drobností:

Nevím, co používáš za kompilátor, ale věčně jsou problémy s neinicializovanou pěmětí. Takže prosím ještě použij ADC_StructInit(&ADC_InitStruct);

(případný problém s neinicializovanou strukturou zjistíš taktéž v debugu, protože v registrech ADC bude bordel a ve struktuře taky).

Udělej nám kdyžtak prosím screenshot registrů v ADC, nějak pokudmožno čitelně (pokud to tvé IDE umí), luštit 32bitové hexa hodnoty se nikomu chtít nebude.

____________________
Potom jen taková poznámka pod čarou: Valit flouty v M0, to seš teda dobrej drak. Nezkoušej mi namluvit, že to nejde spočítat ve fixed point aritmetice. Ale já vim, lenost, že jo? Rychlost float výpočtů na CM0 si doufám uvědomuješ, stějně jako potřebnou rozsáhlost PRINTF knihovních funkcí s obsahem floutu ve FLASH. Když sem kdysi začínal na shnilých AVR, tak se ADC zvládno naškálovat několika instrukcema a vypsat na displej i bez printfu.

Mimochodem, použití sprintf je nebezpečné a ve složitějších aplikacích super díra pro hackery. Používej korektní funkci snprintf, která ti zabrání přetečení paměti.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
 

Zobrazit příspěvky z předchozích:   
Zobrazit předchozí téma :: Zobrazit následující téma  
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> ARM Časy uváděny v GMT + 2 hodiny
 
Strana 1 z 1
Přejdi na:  
Můžete přidat nové téma do tohoto fóra.
Můžete odpovídat na témata v tomto fóru.
Nemůžete upravovat své příspěvky v tomto fóru.
Nemůžete mazat své příspěvky v tomto fóru.
Nemůžete hlasovat v tomto fóru.
Můžete k příspěvkům připojovat soubory
Můžete stahovat a prohlížet přiložené soubory
 



Num Lock Holder - app to hold Numlock
Copyright © 2017 Rudolf Veselý, mcontrollers.com.
Je zakázáno používat části tohoto webu bez souhlasu autora. || Powered by phpBB © 2001, 2002 phpBB Group - with RedSquare DoubleJ(Jan Jaap)