Перейти к содержанию
    

kil00

Участник
  • Постов

    57
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные kil00


  1. Попробовал такой код на работоспособность в разных компиляторах:

     

    #include <cstdlib>

    #include <iostream>

    using namespace std;

     

    int main(int argc, char *argv[])

    {

    int rows, row_width;

    rows = 2672;

    row_width = 4008;

    char strII[2672*4008*2];

    printf("size %d\n",sizeof(strII));

    system("PAUSE");

    return EXIT_SUCCESS;

    }

     

    Мой wx-Dev С++ компилирует, как я уже говорил, но при выполнении программы, Windows выдаёт ошибку не доходя до

    printf("size %d\n",sizeof(strII));

     

    Интересно, что онлайн компилятор http://ideone.com/ компилирует и возвращаемое значение равно:

    size 21418752,

    а вот http://liveworkspace.org/ и http://codepad.org/ тоже выдают ошибки.

     

    Это, значит, что проблемы в компиляторе?

     

    пс Жаль, что никто не ответил, я думал - вопрос простой...

  2. Здравствуйте!

     

    Появилась задача написания небольшой програмы для работы с камерами FLI с помощью их SDK (flicamera.com).

     

    Вопрос такой: как правильно отписывать в буфер ряды(rows) с камеры, чтобы они накапливались непосредственно в буфере, а потом отписывались все вместе в файл, а не по-одному из буфера в файл, как это сделано у меня?

     

    Конкретно в реализации приёма рядов у меня появилось несколько проблем:

     

    Проблема 1-ая заключается в том, что, увеличивая буфер до разрешения изображения 4000x2700 пикселей, компилятор компилирует файл, а вот, когда запускаешь exe-файл, вылетает ошибка Windows, ряды не принимаются, файл не создаётся.

    Проблема 2-ая: при отписывании рядов, в конце каждого ряда появляются какие-то одинаковые значения (проверил с помощью засветки кадра, когда все значения равны FF FF).

    Проблема 3-я: создаваемый файл должен весить около 20 мб (при моих настройках), но, по какой-то причине он периодически в 10 раз меньше. Это, вообще, не укладывается в голове.

     

    Ряды отписываются с помощью ф-ции FLIGrabRow():

    LIBFLIAPI FLIGrabRow (flidev t dev, void* buff, size t width)

    Grab a row of an image. This function grabs the next available row of the image from camera device dev. The row of width width is placed in the buffer pointed to by buff. The size of the buffer pointed to by buff must take into account the bit depth of the image, meaning the buffer size must be at least width bytes for an 8-bit image, and at least 2*width for a 16-bit image.

    Return Value: Zero on success.

    Non-zero on failure.

    Parameters:

    dev: Camera whose image to grab the next available row from.

    buff: Pointer to where the next available row will be placed.

    width: Row width in pixels.

    Полная документация здесь:

    http://flicamera.com/downloads/FLI_SDK_Documentation.pdf

     

    Используемый компилятор:wxDev-C++ 7.3.1.3.

     

    Проблемная часть кода:

     
       long img_size; 
    
       char strII[row_width*2]; //row_width*rows;  
       char *intarray = strII; 
    
    //intarray=(char*)malloc(4080*sizeof(char));
    
    // if((malloc(img_size)) == NULL)  printf("malloc() failed");
         //  else printf("malloc() good\n\n"); 
    
    	img_size = rows * row_width*sizeof(char);
        printf("img_size -->> %d%\n\n", img_size);
    
           FILE *pf;                    
    
       // Приём изображения
               int row = 0;
           	int portion = 0;
    		for (row = 0; row < rows; row++)
                   {
                    x = FLIGrabRow (dev, intarray, row_width); 		      
    
                    pf=fopen("data","ab");         
                    fprintf(pf,"%s\n",intarray);               
                    fclose(pf);                                 
    
     fflush(pf);
                   }
                   // free (intarray);  

     

    Весь код:

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include "libfli.h"
    
    #pragma comment(lib,"E:\projects\c_projects\43_FLI_2\libfli.lib")
    
    #define BUFFSIZE 10000
    
     	 int x,y,z;
    
    int main(int argc, char *argv[])
    {
       flidev_t dev;
       flidomain_t domain;
       domain = (FLIDOMAIN_USB | FLIDEVICE_CAMERA);
       char str[]="flipro0";
    char *m =str;                                                                 // FLIOpen
    	y =	FLIOpen(&dev, m, domain);                                             // Начать работу с устройством
    //----------------------------------------------------------------------------
      long hwrev, fwrev;
    
    FLIGetHWRevision (dev,  &hwrev);                                                  // FLIGetHWRevision
    FLIGetFWRevision (dev,  &fwrev);                                                  // FLIGetFWRevision
    
    printf("FLIGet(F)HWRevision: fwrev:%d, hwrev: %d\n\n", fwrev, hwrev);
    //----------------------------------------------------------------------------
      long ul_x, ul_y, lr_x, lr_y, row_width, rows;
    
    FLIGetArrayArea (dev, &ul_x, &ul_y, &lr_x, &lr_y);                               // FLIGetArrayArea
    row_width = lr_x - ul_x;
    rows = lr_y - ul_y; 
    printf("FLIGetArrayArea: %d;%d;%d;%d; rows: %d  row_width: %d\n\n", ul_x, ul_y,
                                                     lr_x, lr_y, rows, row_width);
    //----------------------------------------------------------------------------
    FLIGetVisibleArea (dev, &ul_x, &ul_y, &lr_x, &lr_y);                             // FLIGetVisibleArea
    
    row_width = lr_x - ul_x;
    rows = lr_y - ul_y; 
    
    printf("FLIGetVisibleArea: %d;%d;%d;%d; rows: %d  row_width: %d\n\n", ul_x, ul_y,
                                                     lr_x, lr_y, rows, row_width);
    //----------------------------------------------------------------------------
      double pixelX, pixelY;
    
    FLIGetPixelSize (dev, &pixelX, &pixelY);                                         // FLIGetPixelSize
    printf("FLIGetPixelSize: pixelX: %f  pixelY: %f\n\n", pixelX, pixelY);
    //----------------------------------------------------------------------------
      double temperature;
    
    FLIGetTemperature (dev, &temperature);                                      // FLIGetTemperature 
    printf("FLIGetTemperature: %f;\n\n",temperature);
    //----------------------------------------------------------------------------
      char vr[50];                                                                 
      char *ver = vr;
    
      size_t col = 50;
    FLIGetLibVersion( vr, col);                                                         // FLIGetLibVersion 
    printf("FLIGetLibVersion: %s;\n\n", ver);
    //---------------------------------------------------------------------------- 
      size_t len;
     char model[20];
     char *mod = model; 
    
     FLIGetModel(dev, mod, 20);                                                      // FLIGetModel
     printf("FLIGetModel: %s;\n\n",mod);
    //----------------------------------------------------------------------------
      flidebug_t level;
      level = FLIDEBUG_NONE;
        char ht[20];                                                                 
        char *host = ht; 
    
    FLISetDebugLevel (host, level);                                                  // FLISetDebugLevel
    
    printf("FLISetDebugLevel: %s;\n\n",host);
    //---------------------------------------------------------------------------- 
    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------
    FLISetVBin (dev, 1);                                                              // FLISetVBin
    FLISetHBin (dev, 1);                                                              // FLISetVBin   
    //----------------------------------------------------------------------------
    FLISetImageArea (dev, ul_x, ul_y, lr_x, lr_y);                                   // FLISetImageArea
    //----------------------------------------------------------------------------
    fliframe_t frametype;
    frametype = FLI_FRAME_TYPE_NORMAL; // FLI_FRAME_TYPE_DARK;
    FLISetFrameType (dev, frametype);                                                 // FLISetFrameType
    //----------------------------------------------------------------------------
    long exptime = 1000;               //msec
    FLISetExposureTime (dev, exptime);                                                // FLISetExposureTime
    //----------------------------------------------------------------------------
    double temperatureToCCD = 0.0;
    FLISetTemperature (dev, temperatureToCCD);                                  // FLISetTemperature
    //----------------------------------------------------------------------------
    flibitdepth_t bitdepth;
    bitdepth = FLI_MODE_16BIT; //FLI_MODE_8BIT
    FLISetBitDepth (dev, bitdepth);                                                        // FLISetBitDepth
    //----------------------------------------------------------------------------
    long nflushes = 16; // îò 0 äî 16
    FLISetNFlushes (dev, nflushes);
    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------
    //startExposure 
    
    FLIExposeFrame (dev);
    //----------------------------------------------------------------------------
    //FLICancelExposure (dev);
       Sleep(exptime+1000);
    //----------------------------------------------------------------------------  
       flishutter_t shutter;
       shutter = FLI_SHUTTER_OPEN; // (FLI_SHUTTER_EXTERNAL_TRIGGER_LOW|FLI_SHUTTER_OPEN)
                                   // FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH
    //        z = FLIControlShutter (dev, shutter);                                   
    //    Sleep(2000);
    //----------------------------------------------------------------------------
       shutter = FLI_SHUTTER_CLOSE;
    //        z = FLIControlShutter (dev, shutter);                                   
    //----------------------------------------------------------------------------
    long img_size; 
    
    	char strII[row_width*2]; 
       char *intarray = strII; 
    
    //intarray=(char*)malloc(4080*sizeof(char));
    
         //  if((malloc(img_size)) == NULL)  printf("malloc() failed");
         //  else printf("malloc() good\n\n"); 
    
    	img_size = rows * row_width*sizeof(char);
        printf("img_size -->> %d%\n\n", img_size);
    
           FILE *pf;                    
    
       // Приём изображения
               int row = 0;
           	int portion = 0;
    		for (row = 0; row < rows; row++)
                   {
                    x = FLIGrabRow (dev, intarray, row_width);			      
    
                    pf=fopen("data","ab");         
                    fprintf(pf,"%s\n",intarray);               
                    fclose(pf);                                 
    
    			 fflush(pf);
                   }
                   // free (intarray); 
    
    //---------------------------------------------------------------------------- 
       printf("FLIGrabRow = %d;\nFLIOpen = %d;\nFLIControlShutter = %d;\n\n",x,y,z);
    //---------------------------------------------------------------------------- 
       FLIFlushRow (dev, rows, 16);                                                     // очистка рядов
    //----------------------------------------------------------------------------
     	FLIClose(dev);                                                                // закончить работу с устройством
    //----------------------------------------------------------------------------
     system("PAUSE");	
     return 0;
    }
    

  3. Не только. Там есть PREDIV1, PREDIV1SRC, PREDIV2, PLL2MUL и ещё что-то. По крайней мере мимо PREDIV1 и PREDIV1SRC никак не затактировать PLL.

    Просто я не использую делители, даже не заглняул в RCC->CFGR2.

     

    А вот не сможет стартовать HSE - и код зависнет вместо того, чтобы вернуть единицу.

    Исправлю.

     

    Спасибо за помощь!

  4. Как минимум ещё PLL и таймер. Нуи время входа в прерывание и время на дрыгание ножкой.

     

    Только времени(тактов) на это уходит слишком много. Кстати, я синхронизирую включение таймера TIM2 с приходом 1PPS в EXTI, это я забыл написать. И тут тоже не должно быть большого расхождения в тактах:

    void EXTI1_1PPS_Config(void)
    {
      AFIO->EXTICR [0] |= AFIO_EXTICR1_EXTI1_PE; // Прерывание на (PE1)
      EXTI->IMR |= EXTI_IMR_MR1;   // Разрешить запрос от EXTI1									
      EXTI->RTSR |= EXTI_RTSR_TR1; // Прерывание от EXTI1 по переднему фронту
    
      // ширина приходящего по EXTI импульса должна быть минимум --> 10 нс(см. datasheet стр 90)
    }
    //********************************************************************************
    *
    // Функция EXTI1_IRQHandler: Синхронизация от импульса 1PPS                                          
    //********************************************************************************
    *
    void EXTI1_IRQHandler (void)
    {
      if (EXTI->PR & EXTI_PR_PR1) // Прерывание от (PE1) по приходу 1PPS
         { 
       	    TIM2->CR1 |= TIM_CR1_CEN;	// Разрешить работу таймера генерации 1Гц 
    
       if (TimeGlobalFlag==1) 
    	      {// Cинхронизация 
    
    			TIM5->CNT = 0; // обнулить счётчик, чтобы его значение после синхронизации равнялось 0x00 			
    		TIM5secs=secs; // если время по NMEA получено, присвоить TIM5secs значения secs  
    
    			TIM3->CNT = 0; // обнулить счётчик, чтобы его значение после синхронизации равнялось 0x00 			
    		TIM3microsecs = 0; // если время по NMEA получено, TIM3microsecs = 0 
    
    		TIM5->CR1 |= TIM_CR1_CEN;	// Разрешить работу секундного таймера TIM5 
    		TIM3->CR1 |= TIM_CR1_CEN;	// Разрешить работу микроcекундного TIM3 таймера 
    
    	//	TIM2->CR1 |= TIM_CR1_CEN;	// Разрешить работу таймера генерации 1Гц 
    
    		TIM1->CCER |= TIM_CCER_CC1E; // включить захват из счётчика			
    
    		TimeGlobalFlag=0;  // устанавливаем флаг успешного получения времени
    	//  flagEXTI=1;	   	
    		flagSynchro=0;	   // флаг синхронизации - в ПК будут слаться ответы с временем
    
    		AFIO->EXTICR [0] &=~ AFIO_EXTICR1_EXTI1_PE; // Отключиться от (PE1)					  ////////
    
     EXTI->IMR &=~ EXTI_IMR_MR1;   // Запретить запрос от EXTI1
    	  }
      EXTI->PR |= EXTI_PR_PR1; // Сбросить флаг	   										    
      }
    }

    Что касаемо приведённых настроек PLL, то я не вижу там ни одного упоминания о RCC->CFGR2. У вас же 107? Надо настроить.

     

    Да 107, только, я так понял, регистр RCC->CFGR2 весь для I2C.

     

    ЗЫ. Кстати, код
    Код
      while((RCC->CR & RCC_CR_HSERDY)==0)    //Ожидание готовности HSE
      if(TimeOut) TimeOut--;
      if(TimeOut==0) return 1;               // Генератор HSE не запустился
    
    никогда не вернёт 1. Вместо этого он наглухо зависнет в ожидании HSERDY.

     

    Да, 1 он не вернёт (скобок не хватает). А зависать он не должен, он и не зависает :)

     

    В конце-концов, выдайте не 1Гц, а 1 КГц, и измерьте осциллоскопом, какая частота получится.

     

    В общем, если что-то получится, то отпишусь.

  5. В формировании секундного импульса участвует не только рубидиевый стандарт.

     

    По схемам (RM0008 (стр.123) и даташит на stm32f107 (стр.12)) должен участвовать только он, как я понимаю.

     

    Возможно, вы ошиблись при настройке PLL? Как вы получили из 10МГц 35МГц? И почему TIM2->PSC = 35000 у вас даёт 2000Гц?

     

    Я как раз задавал этот вопрос на форуме несколько месяцев назад. Если посмотреть на схему тактирования stm32f107 (RM0008 стр.123), то там есть такая строчка "TIM2,3,4,5,6,7 If(APB1 prescaler =1) x1 else x2", т.е у меня частота тактирования таймера TIM2 = 70 МГц.

     

    Код инициализации HSEBYP:

    unsigned char InitHSEBYP(void)
    {
     unsigned long int TimeOut = 10000000;     
    
     //Запустить HSEBYP
     RCC->CR   |=  RCC_CR_HSEBYP;           //Включить генератор HSEBYP  
     RCC->CR   |=  RCC_CR_HSEON;            //Включить генератор HSE
     while((RCC->CR & RCC_CR_HSERDY)==0)    //Ожидание готовности HSE
     if(TimeOut) TimeOut--;
     if(TimeOut==0) return 1;               // Генератор HSE не запустился
     RCC->CR   |=  RCC_CR_CSSON;            //Разрешить работу системы защиты от сбоя HSE
    
     RCC->CFGR &= ~RCC_CFGR_PLLXTPRE;       //Не использовать делитель HSE
    
     //Частота  SystemCoreClock выше 24 MHz - разрешить буфер предварительной выборки FLASH
     FLASH->ACR|=  FLASH_ACR_PRFTBE;        //Включить буфер предварительной выборки
     FLASH->ACR&= ~FLASH_ACR_LATENCY;       //Очистить FLASH_ACR_LATENCY
     FLASH->ACR |= FLASH_ACR_LATENCY_2;     //Пропускать 2 такта
    
     //Настройка PLL 
     RCC->CFGR  |= RCC_CFGR_PLLSRC;         //Источником сигнала для PLL выбран HSE
     RCC->CR   &= ~RCC_CR_PLLON;            //Отключить генератор PLL
     RCC->CFGR &= ~RCC_CFGR_PLLMULL;        //Очистить PLLMULL
     RCC->CFGR |=  RCC_CFGR_PLLMULL7;       //Коефициент умножения = 7
     RCC->CR   |=  RCC_CR_PLLON;            //Включить генератор PLL
     while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL
    
     //Переключиться на тактирование от PLL
     RCC->CFGR &= ~RCC_CFGR_SW;             //Очистка битов выбора источника тактового сигнала
     RCC->CFGR |=  RCC_CFGR_SW_PLL;         //Выбрать источником тактового сигнала PLL
     while((RCC->CFGR&RCC_CFGR_SWS)!=0x08){}//Ожидание переключения на PLL
    
     // apb1 
    RCC->CFGR &=~RCC_CFGR_PPRE1;        // Очистка битов предделителя "APB1 Prescaler"
    // RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; // HCLK not divided 
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;   // HCLK divided by 2 
    
     // apb2
    RCC->CFGR &= ~RCC_CFGR_PPRE2;       // Очистка битов предделителя "APB2 Prescaler"
    // RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; // HCLK not divided 
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;   // HCLK divided by 2 
    
     return 0;                          // HSE готов к работе
    }                    
    }

     

  6. Почему? В первом и втором случае вы засекаете секунду, которую формирует GPS. А в третьем - секунду, которая формируется из вашего кварца.

    Я использую вместо кварца внешнюю частоту (рубидиевый стандарт) для тактирования МК (значит и таймеры тактируются от этой частоты), поэтому такой погрешности быть не может.

     

  7. 2103/35000000 = 0,000060086. Видимо, это погрешность вашего кварца, помноженная на PLL.

     

    Если бы это была погрешность, то она распространилась и на пункты 1 и 2 моего предыдущего сообщения. Плюс 10Мгц у меня от рубидиевого стандарта. Поэтому я грешу на код...

  8. Опять всё напутал. Извиняюсь! В общем теперь задача точно описывается так (всё проверил несколько раз!):

    1. Если на оба выхода таймера в режиме Input Capture подаётся один и тот же сигнал, то разница между регистрами сравнения каналов = 00 либо 01 (т.е 1 такт при частоте шины тактирования таймера 35 Мгц).

    2. Если на выходы таймера в режиме Input Capture подаются сигналы (1PPS) с разных GPS-ов, то разница между регистрами сравнения каналов варьируется и ползает в разные стороны в пределах от 00 до 10.

    3. Если же я из 35МГц (которые получаюся из 10МГц) генерирую 1Гц и в режиме Capture/Campare сравниваю с любым из PPS-ов (т. е. от любого из GPS-ов ), то разница между регистрами сравнения = 2103 (плюс-минус 3).

     

    Вопрос всё тот же: откуда берутся эти постоянные 2103 тактов?

     

    Инициализация и прерывание для таймера, генерирующего 1Гц:

    //********************************************************************************
    *
    // Функция TIM2_Divider_Config: Делитель на таймере                                           
    //********************************************************************************
    *
    void TIM2_Divider_Config (void)
    {
      RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // подача тактов на TIM2 от шины тактирования APB1
    
      TIM2->PSC = 35000 - 1;  // предделитель до частоты  2000 Гц
      TIM2->ARR = 2000 - 1;   // выход в прерывание каждую секунду
      TIM2->DIER |= TIM_DIER_UIE;	 // После того как таймер достигнет своего максимального значения генерируется прерываие 
      TIM2->CR1 |= TIM_CR1_ARPE;	// сброс по достижении максимального значения
    // TIM2->CR1 |= TIM_CR1_CEN;	// Разрешить работу таймера 
    }
    //********************************************************************************
    *
    // Функция TIM2_IRQHandler: Обработчик прерываний для TIM2                                           
    //********************************************************************************
    *
    void TIM2_IRQHandler(void)
    {
      if (TIM2->SR&TIM_SR_UIF)
         {
          GPIOE->BSRR |= GPIO_BSRR_BS0; // генерация импульса, который подаётся на (PE0), его надо принять на TIM4_CH3 (PB8) 
          GPIOE->BSRR |= GPIO_BSRR_BR0;
          TIM2->SR &=~ TIM_SR_UIF; // очиcтка флага прерывания                    
         }
    }
    

  9. а вот еще момент с вычислением разницы. Есть потенциальная возможность глюков. Я бы как-то так написал:

    if (count1>count2)
    {
        razn = count1 - count2;
    }
    else
    {
        razn = count2 - count1;
    }

     

     

     

    а уверены, что именно это не приводит к непонятным глюкам?

     

    Не уверен. Буду ещё разбираться.. Напишу, как что-нибудь получится.

  10. Сформулировал вопрос конкретно по таймеру.

     

    Подаю один сигнал параллельно на 2 канала таймера TIM4 (на 2 ноги). Я думаю, что таймер должен защёлкнуть их одновременно, и значения регистров Capture/Compare должны быть одинаковыми. В реальности получается между ними разница в 2103 (плюс минус 3, от включения к включеию) такта шины таймера (35 МГц), которая сохраняется постоянной при приходе этого сигнала, например, раз в секунду.

     

    Откуда берутся эти 2103 тактов?

  11. Здравствуйте!

     

    У меня есть, на мой взгляд, интересная задачка (хотя я новичок в МК, может быть, преувеличиваю), над которой я изрядно поломал мозг, но так и не решил.

     

    Есть устройство (на основе STM32f107), которое синхронизируется от GPS и тактируется от высокостабильного источника частоты.

     

    После того, как прибор засинхронизировался, таймер (TIM4) в режиме Input Capture начинает захватывать 1PPS от GPS в третьем канале и 1PPS от того же GPS в четвёртом канале, дальше из одного значения вычитается другое и получаем... (2103 плюс-минус 3) такта, это, примерно, 29 мкс. Снимая таким образом показания каждую секунду, получаем одно и то же значение.

     

    Вопрос возникает сам собой — откуда берутся эти 2103 тактов?

     

    Если нужно будет, я выложу весь код.

     

    Инициализация таймера:

    void TIM4_Alarm_Config (void)
    {
      RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // подача тактов на TIM4 от шины тактирования APB1
    
      TIM4->PSC = 1 - 1; // Предварительный делитель: значения счетчика будут инкрементироваться с частотой 35 MГц 
      TIM4->ARR = 65534 - 1;	// Максимальное значение, до которого будет считать таймер, равно 65535				
    
      // канал 3  (1Гц)
      TIM4->CCMR2 |= TIM_CCMR2_CC3S_0; // выбор активного входа, канал 3 TIM4_CH3 (PB8)    <<------ подать на этот канал 1Гц
      TIM4->CCER  &=~ TIM_CCER_CC3P; // срабатывание по переднему фронту
      TIM4->CCMR2 &=~ TIM_CCMR2_IC3PSC; // захват каждого импульса
    //   TIM4->CCER |= TIM_CCER_CC3E; // включить захват из счётчика	  // в EXTI1
      TIM4->DIER |= TIM_DIER_CC3IE; // включение прерывания от захвата
    
      // канал 4  (1PPS)
      TIM4->CCMR2 |= TIM_CCMR2_CC4S_0; // выбор активного входа, канал 4 TIM4_CH4 (PB9)	<<------ подать на этот канал 1PPS
      TIM4->CCER  &=~ TIM_CCER_CC4P; // срабатывание по переднему фронту
      TIM4->CCMR2 &=~ TIM_CCMR2_IC4PSC; // захват каждого импульса
    //   TIM4->CCER |= TIM_CCER_CC4E; // включить захват из счётчика	  // в EXTI1
      TIM4->DIER |= TIM_DIER_CC4IE; // включение прерывания от захвата
    }
    

     

    Прерывание от таймера:

    void TIM4_IRQHandler(void)
    {
    
      if (TIM4->SR&TIM_SR_CC3IF) // 1Гц
      	  {
      TIM4->SR &=~ TIM_SR_CC3IF; // очиcтка флага прерывания
       count1 = TIM4->CCR3;	// считываем значение счётчика в переменную count1, если выставлен флаг прерывания
         }
    
      if (TIM4->SR&TIM_SR_CC4IF) // 1PPS 	
      {
       TIM4->SR &=~ TIM_SR_CC4IF; // очиcтка флага прерывания
       count2 = TIM4->CCR4;	// считываем значение счётчика в переменную count1, если выставлен флаг прерывания
      }
    
     if((count1>0)&&(count2>0))
         {
       	if(count1>count2)
              {
                razn = count1 - count2;              
              }
           if(count2>count1)
              {
                razn = count2 - count1;			
              }   
    
              count1=0;                        
              count2=0;
    
    	if (razn >(bias+1000)){razn = 65534 - razn;}
    
    //	   	if(bias>razn)
    //           {
                rash = razn + 100;// - bias;    // добавил биас    rash - unsigned int      
    //           }
    //        if(razn>bias)
    //           {
    //             rash = razn - bias;			
    //           }   	  
    
    //while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
    //USART2->DR=rash; 
    
    	 		 union {
            unsigned int Mylong2;
            char buf3[2];									 // рассогласование в микросекундах
            }MyUnion2;
    	 MyUnion2.Mylong2 = rash;
    
    
     while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
          USART2->DR=MyUnion2.buf3[1];							// рассогласование в микросекундах
     while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
         USART2->DR=MyUnion2.buf3[0]; 
    
      	if (rash<90) 
    
    	  {GPIOA->BSRR |= GPIO_BSRR_BS7;}  // генерация импульса, который подаётся на GPIOA_PIN6 (PA7),            <<----- импульс сигнализации}
    
    	if (rash>110)
    
    	  {GPIOA->BSRR |= GPIO_BSRR_BS7;}  // генерация импульса, который подаётся на GPIOA_PIN6 (PA7),            <<----- импульс сигнализации}
       }
    }

  12. Здравствуйте!

     

    Подскажите, пожалуйста, как написать парсер на Си, который будет принимать (по USART через DMA) и обрабатывать бинарные(hex) числа?

     

    Я разобрался, как это сделать с помощью строк и ASCII, но, например, если мне нужно получить данные типа 0x12 0x23 0x34 0x00 0x56, то с помощью строк и ASCII это сделать не удаётся из-за того, что 0x00 воспринимается как нуль-терминатор, т.о. и 0x00 и 0х56 опускаются.

  13. Здравствуйте!

     

    Пытаюсь настроить таймеры в TIM3 и TIM5 в stm32f107. Частота шины AHB=70 МГц поэтому делю её,

     

    // apb1

    RCC->CFGR &=~RCC_CFGR_PPRE1; // предочистка

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // HCLK divided by 2

     

    и получаю 35 МГц на APB1, где находятся таймеры

    Настраиваю таймеры

     

    RCC->APB1ENR |= 1<<3;

    TIM5->PSC = 35000 - 1;

    TIM5->ARR = 1000 - 1;

     

    Таймер выходит в прерывание примерно в 2 раза чаще. Тогда я делаю так

     

    // apb1

    RCC->CFGR &=~RCC_CFGR_PPRE1; // предочистка

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; // HCLK not divided

     

    И ничего с таймером не меняется. За то USART2, настроенный на 35МГц и находящийся на той же шине, перестаёт правильно работать.

     

    Питаюсь от HSEBYP 10 МГц и умножаю PLL на 7.

     

    В чем может быть проблема?

  14. Спасибо, Gorby и Xenia!

     

    Воспользовался объединением - это то, что надо. Всё работает.

     

    Удивила ваша скорость ответа.. :)

     

    Xenia, а со вторым вариантом буду разбираться.

     

    А я весь день просидел и ничего не мог сделать...

  15. Здравствуйте!

     

    Как можно отправить по USART переменную unsigned long равную, допустим, 4294967294 (0xFFFF FFFE) таким образом, чтобы получить на ПК эти значения в HEX. То есть поразрядно поочереди получить FF, FF, FF, FE?

     

    Пока ничего лучше я не придумал, чем это

         unsigned long TIM5secs=4294967294;
    
     long del = 1000000000; 
     int sP=0;
        char secsMass[10];
     int i = 0;
    
        while (del!=1)
       {
         sP=TIM5secs/del;
       	    secsMass[i]=sP;
                      TIM5secs=TIM5secs-sP*del;
    
    
        while (!(USART1->SR & USART_SR_TXE)) {} 
         USART1->DR=secsMass[i]; 
        i++;
       del=del/10;
           }

     

    Получаю:

    04 02 09 04 00 06 07 00 02 04 02 09 04

     

    Но это не совсем то, что хотелось бы.

     

     

  16. Спасибо, andron86, всё работает!

     

    Вячик13, sprintf() я тоже пробовал, не работает, может не так пробовал?

     

    Пробую так:

     

    char bf[50];

    int sp, a = 12, b = 112;

    sp = sprintf(bf, "%d minus %d = %d",a,b,a-B );

    print("\n\r");

  17. Здравствуйте!

     

    Использую Keil и stm32f103.

     

    Как преобразовать переменную в строку? В хидерах нет функции itoa().

     

    Хотел, как альтернативу для передачи по USART использовать функцию printf() - контроллер зависает напрочь.

     

  18. Как организовать буфер я нашёл. А вот как работать со строкой я так и не понял, тем более что библиотека iostream не подключается, а выдаёт ошибки при компиляции, поэтому невозможно использовать фунцию типа strcpy(s1,s2)..

     

    compiling main.c...

    P:\Keil\ARM\RV31\INC\rw/_defs.h(781): error: #20: identifier "namespace" is undefined

    P:\Keil\ARM\RV31\INC\rw/_defs.h(781): error: #65: expected a ";"

    P:\Keil\ARM\RV31\INC\iosfwd(93): error: #20: identifier "namespace" is undefined

    P:\Keil\ARM\RV31\INC\iosfwd(93): error: #65: expected a ";"

    P:\Keil\ARM\RV31\INC\iosfwd(117): error: #65: expected a ";"

    P:\Keil\ARM\RV31\INC\iosfwd(122): error: #65: expected a ";"

    P:\Keil\ARM\RV31\INC\iosfwd(127): error: #65: expected a ";"

    ...

     

    Что делать с принятой строкой, чтобы извлечь из неё нужную мне информацию?

     

     

  19. Непонятен алгоритм, который вы пытаетесь реализовать.

    while (!Character==32)[/code]

    Почему 32? Некоторые поля могут иметь фиксированный фориат (и при этом иногда отсутствовать в строке - быть пустуми).

     

    Я ошибся, просто быстро накидал часть кода, как вижу решение. Должно быть

     

    while (!CharNum==32)

     

    32 символа передаётся в одном пакете $GPZDA.

     

    Ты ЩО дурный (С) Без обид

     

    Я думал, что вчера написал, что мне нужно вычленить только определённые символы из этой последовательности: время без десятых и сотых, и дату. А сейчас не мог понять, зачем мне пишут то, что и так понятно ещё и ругают... Спать надо больше. Извиняюсь.

     

    А сам вопрос звучит так: как вычленить только определённые символы из этой последовательности: время без десятых и сотых, и дату? вот. т.е. в моём варианте примерно так(если я опять нигде не ошибся)

     

     
    while (!CharNum==32)
    {  
       while ( ! (USART1->SR & USART_SR_RXNE) ) ;   //  ждать, пока символ не получен
          {
             CharNum++;
    
             if (CharNum==1) 
               {
     USART1->SR &=~ USART_SR_RXNE;}     // пропустить 1-ый символ , 
    
              // то же для 2,3-7
    
             if (CharNum==8)
               {
                 Character = (USART1->DR & 0x1FF ) ;}    // считать 2-ой символ 

     

    // то же для 9,10-13

     

    // и т.д.

     

     

  20. Я 3 раза перечитал, но так и не понял сути вопроса.

     

    Потому я такие вопросы и задаю, что новичок как в С++, так и в программировании контроллеров. Занимаюсь ими месяцев 8-9, периодически отрываясь от основной работы.

     

    Ну если начальство сказало, что надо, то преобразовывайте.

     

    Начальство тут не при чём, тут дело в непонимании.

     

    Мой алгоритм примерно выглядит так:

     
    while (!Character==32)
    {  
       while ( ! (USART1->SR & USART_SR_RXNE) ) ; // ждать, пока символ не получен
          {
             CharNum++;
    
             if (CharNum==1) 
               {
     USART1->SR &=~ USART_SR_RXNE;}     // пропустить 1-ый символ
             if (CharNum==3)
               {
                Character = (USART1->DR & 0x1FF ) ;}      // считать 2-ой символ
            .....

     

    Получается, что я каждый символ должен посчитать, а их 32, через оператор if.

     

    Следующий этап - синтаксический анализ. В этом случае он тривиален, из входного потока лексем просто лишние выбрасываются, нужные сохраняются.

     

    Делаю я это так: считываю байт, если приёмник не пуст, повторяю в цикле.

     

    Вот я и спрашиваю, как это сделать (на уровне кода)? можно ли это упростить с помощью языка? А не использовать для этого 60 строчек кода.

     

×
×
  • Создать...