STM32F0 Veri Okuma Problemim Neyden Kaynaklanıyor ?

Başlatan GaGuLi, 24 Nisan 2016, 19:20:00

GaGuLi

STM32F0 ile ilgili Baran arkadaşımızın yaptığı uygulamaları inceleyip öğrenmeye çalışıyorum. Üzerinde çalıştığım uygulama ADC okuyup USART ile bilgisayara yazdırma uygulaması. Kodlar aşağıdaki gibi

#include "stm32f0xx_conf.h"

static void RCC_Config(void);
static void GPIO_Config(void);
static void ADC1_Config(void);
static void UART_Config(void);
static void TIM3_Config(void);
static void NVIC_Config(void);

static float ADC_ReadVoltage(ADC_TypeDef* ADCx);
static char* FloatToString(float f);
static void USART_SendString(USART_TypeDef* USARTx, char* s);

static uint8_t flag = 0;

void TIM3_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM3, TIM_FLAG_Update) != RESET)
        flag = 1;
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}

int main(void)
{
    RCC_Config();
    GPIO_Config();
    UART_Config();
    ADC1_Config();
    TIM3_Config();
    NVIC_Config();

sprintf(dd, "%1.3f Volt", x);

    while(1)
    {
        if(flag == 1)
        {
            USART_SendString(USART1, FloatToString(ADC_ReadVoltage(ADC1)));
            flag = 0;
        }
    }
    return (0);
}

static void RCC_Config(void)
{
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_USART1, ENABLE);
}

static void GPIO_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10; //USART 1 : PA9 = TX, PA10 = RX
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

static void UART_Config(void)
{
    USART_InitTypeDef USART_InitStructure;

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_1);

    USART_InitStructure.USART_BaudRate            = 9600;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Tx;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;

    USART_Init(USART1, &USART_InitStructure);
    USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    USART_Cmd(USART1, ENABLE);
}

static void ADC1_Config(void)
{
    ADC_InitTypeDef   ADC_InitStructure;

    ADC_DeInit(ADC1);
    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Resolution            = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ContinuousConvMode    = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge  = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign             = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ScanDirection         = ADC_ScanDirection_Upward;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_239_5Cycles);

    ADC_Cmd(ADC1, ENABLE);
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
    ADC_StartOfConversion(ADC1);
    ADC_ITConfig(ADC1,ADC_IT_EOC, DISABLE);
}

static void TIM3_Config(void)
{
    TIM_TimeBaseInitTypeDef TIM3_InitStructure;

    TIM3_InitStructure.TIM_Prescaler         = 1000;
    TIM3_InitStructure.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM3_InitStructure.TIM_Period            = 24000;
    TIM3_InitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;

    TIM_TimeBaseInit(TIM3, &TIM3_InitStructure);
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM3, ENABLE);
}

static void NVIC_Config(void)
{
    NVIC_InitTypeDef  NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel          = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority  = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd       = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

static float ADC_ReadVoltage(ADC_TypeDef* ADCx)
{
    float voltage;

    voltage = ADC_GetConversionValue(ADCx);
    voltage *= (0.0008056640625);

    return (voltage);
}

static char* FloatToString(float f) // float sayýyý stringe çeviren fonksiyon
{
    char MyText[16];
    sprintf(MyText, "%f Volt", f); // virgülden sonra 3 basamak yazacaðý ifade edilir 1.3f ile
    return (MyText);
}

static void USART_SendString(USART_TypeDef* USARTx, char* s)
{
    while(*s)
    {

    while(!(USARTx->ISR & ((uint32_t)0x00000040))); // TC biti kontrol ediliyor
        USARTx->TDR = (*s & (uint16_t)0x01FF);
        
        //while(!USART_GetFlagStatus(USARTx, USART_FLAG_TC));
        //USART_SendData(USARTx, *s);

        s++;
    }
    USARTx->TDR = ('\r' & (uint16_t)0x01FF);
    USARTx->TDR = ('\n' & (uint16_t)0x01FF);
}


Anlayamadığım husus şu fonksiyonda :

static void USART_SendString(USART_TypeDef* USARTx, char* s)
{
    while(*s)
    {

    while(!(USARTx->ISR & ((uint32_t)0x00000040))); // TC biti kontrol ediliyor
        USARTx->TDR = (*s & (uint16_t)0x01FF);
        
        //while(!USART_GetFlagStatus(USARTx, USART_FLAG_TC));
        //USART_SendData(USARTx, *s);

        s++;
    }
    USARTx->TDR = ('\r' & (uint16_t)0x01FF);
    USARTx->TDR = ('\n' & (uint16_t)0x01FF);
}


Flag kontrol ve data yollama işlemlerini register ile yapınca veriler doğru bir şekilde geliyor. Ama kütüphane ile yazdığımda ADC okunan değerin 1. basamağı ve 2 nokta geliyor seri ekrana.

Doğru veri  -->  1.72 Volt
Yanlış veri   -->  1..          şeklinde.

Sorunun kaynağını tam anlayamadım. Yardımcı olursanız sevinirim

baran123

Hocam kusura bakmayın geç cevap verdim. MCU-Turkey deki yorumunuzu gördüm.Buradan da yazayım
Ben kodu denedim 2 türlüde bir sorun yaşamadım.
Size çalışan kodu tekrar veriyorum.Birde bunu dener misiniz ?
Hocam Embitz ve Emblocksda şöyle bir durum var.Sprintf fonksiyonunu float ile kullanabilmek için küçük bir ayar yapmanız gerekiyor.Bundan kaynaklı bir sorun olabilir.
Ayar için "Build  Options" -> "Compiler Settings" -> "Other" kısmına şu komutu ekleyin "-u _printf_float" (Tırnak arasındakini)
Kodda pek fark yok ben sadece biraz düzenleyip denedim.
Kolay gelsin. :)
/*****************************************************************************

* File Name        : main.c

* Description      : ADC_Uygulaması

* Additional Information : ADC ile gerilim okuma.

*******************************************************************************/
#include "stm32f0xx_conf.h"
#include <string.h>

static float voltage;
static uint16_t ADC_Value;
static char ADC_Buffer[16];

static void ADC_Config(void);
static void USART_Config(void);
static void USART_SendString(USART_TypeDef* USARTx, char* s);

void ADC1_COMP_IRQHandler(void)
{
    if(ADC_GetFlagStatus(ADC1, ADC_IT_EOC))
    {
        ADC_Value = ADC_GetConversionValue(ADC1);
        voltage  = ADC_Value * (0.0008056640625);
        sprintf(ADC_Buffer, "Voltage : %2.3f Volt", voltage);
        USART_SendString(USART1, ADC_Buffer);
        ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
    }
}

/***********************************************************
* Function Name  : main
* Description    : Ana program burada döner
* Input          : void
* Return         : int
***********************************************************/
int main(void)
{
    ADC_Config();
    USART_Config();

    while(1)
    {

    }
}

/***********************************************************
* Function Name  : Init_GPIO
* Description    : GPIO giriş çıkış işlemleri yapılır
* Input          : void
* Return         : void
***********************************************************/
static void ADC_Config(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;
    ADC_InitTypeDef     ADC_InitStructure;
    NVIC_InitTypeDef    NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_DeInit(ADC1);

    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_239_5Cycles);
    ADC_ChannelConfig(ADC1, ADC_Channel_3 , ADC_SampleTime_239_5Cycles);

    ADC_Cmd(ADC1, ENABLE);

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));

    ADC_StartOfConversion(ADC1);

    NVIC_InitStructure.NVIC_IRQChannel = ADC1_COMP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_Init(&NVIC_InitStructure);

    ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
}

/***********************************************************
* Function Name  : Init_UART
* Description    : UART hazırlanır. (115200, 8, N, 1, TX/RX)
* Input          : void
* Return         : void
***********************************************************/
static void USART_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,  GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate            = 115200;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Tx;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;

    USART_Init(USART1, &USART_InitStructure);
    USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    USART_Cmd(USART1, ENABLE);
}

/***********************************************************
* Function Name  : USART_SendString
* Description    : USART dan string yollar
* Input          : USART_TypeDef* USARTx, char* s
* Return         : void
***********************************************************/
static void USART_SendString(USART_TypeDef* USARTx, char* s)
{
    while(*s)
    {
        //while(!(USARTx->ISR & 0x00000040));
        //USARTx->TDR = (*s & (uint16_t)0x01FF);
        while(!USART_GetFlagStatus(USARTx, USART_FLAG_TC));
        USART_SendData(USARTx, *s);
        s++;
    }
    //USARTx->TDR = ('\r' & (uint16_t)0x01FF);
    //USARTx->TDR = ('\n' & (uint16_t)0x01FF);
    USART_SendData(USARTx, '\r');
    USART_SendData(USARTx, '\n');
}

GaGuLi

#2
Estağfurullah baran hocam ilginize teşekkür ederim  :) O ayarı yaptım sprintf i float ile kullanmak için. Birde bu kodu deneyeyim müsait olduğumda sonucu burdan yazarım.