Skocz do zawartości

qwee

Użytkownicy
  • Zawartość

    42
  • Rejestracja

  • Ostatnio

Wszystko napisane przez qwee

  1. Czy zna ktoś algorytm synchronizacji podnośnika dwukolumnowego? Konkretnie chodzi o podnośnik stenhoj. Napędzany jest dwoma silnikami trójfazowymi asynchronicznymi. Na kole pasowym śruby zamocowany jest magnes a pod nim czujnik halla z wyjściem OC, który służy do zliczania obrotów. Silniki sterowane są poprzez 4 styczniki. Po 2 na każdy silnik do zmiany kierunku obrotów. Styczniki sterowane przez tranzystory i ULN2003. Synchronizację zapewne ogarnia PIC16F, który uwzględnia tez krańcówki mechaniczne. Prawdopodobnie poleciał PIC. Tutaj pytanie czy wie ktoś w jakiś sposób przebiega synchronizacja silników? Złącza od czujników obrotów są jednoznacznie opisane jako Master i Slave, stąd wnioskuje, że obroty jednego są uwarunkowane obrotami drugiego, lecz mechanizm jest zapewne prostszy niż sterowanie prędkością obrotową ponieważ zastosowane są styczniki. Raczej logika jest dwustanowa.
  2. Dokładnie - element będzie pojawiał się przed nosem czujnika raz na obrót. W takim razie spróbuje z parą fototranzystor i dioda IR. Czy możecie polecić jakieś konkretne elementy? Jeśli to nie spełni moich oczekiwań to planuje umieścić magnes a jako czujnik wykorzystać czujnik halla. Pozostaje tylko problem jaki czujnik? Magnes rozumiem, że neodymowy, jak najmocniejszy.
  3. Dziękuję za zainteresowanie. Dokładnie to mam na myśli - Wykrywanie pojedynczego zdarzenia ma nastąpić nie częściej niż 500 razy na sekundę. Nie upieram się nad wykorzystaniem czujników optycznych aczkolwiek czujnik sharp GP2Y0A41SK0F byłby całkiem spoko. Nie wykluczam także czujników magnetycznych jednak czy osiągnę wymaganą czułość z odległości około 10 cm? Jaki magnes i jaki czujnik mogą spełniać takie wymagania? Maksymalny wymiar magnesu to około 2-3 cm szerokości i 10 cm długości.
  4. Potrzebuje pomocy. Mianowicie interesuje mnie pomiar przyspieszenie pewnego obiektu. Chciałbym to rozwiązać na zasadzie transoptorów odbiciowych lecz zakres działania powinien mieć większą odległość czujnika od obiektu. Obiektem jest obracające się aluminiowe ramie a czujnik może być oddalono o około 10 cm. Gotowe transoptory mają bardzo małą odległość działania wiec postanowiłem wykorzystać parę dioda - fototranzystor. Czy taka para https://botland.com.pl/analogowe-czujniki-odleglosci/1977-odbiornik-i-nadajnik-ir-liteon-940nm-para.html ma prawo działać w tym przypadku? Ramie ma kolor czarny lecz nie ma problemu z ewentualnym oklejeniem na biało. Ponadto czy jest sens zwiększenia czułości poprzez zastosowanie dwóch diod nadawczych? Nie interesuje mnie pomiar wartości analogowych tylko binarny sygnał pochodzący z odbicia. Może ktoś zna gotowe dedykowane rozwiązania? Częstotliwość pomiaru nie wiesza niż 500 Hz.
  5. To może doprecyzuje. Ma być to coś na kształt breloka, przywieszki, małego urządzenia które będzie przypisane do danej osoby. Gdy osoba wraz z tym układem zbliży się do bazy, wówczas następuje rozpoznanie takiego urządzenia w zasięgu i określona reakcja - np zwarcie styku. Najlepiej gdyby była identyfikacja obiektu, ale niekoniecznie. Zakładam, że będzie tylko 1 góra 2 małe urządzenia, które będą sporadycznie zbliżały się do bazy/centralki i wówczas nastąpi rozpoznanie i reakcja. Nie musi być autoryzacji, unikalności urządzenia, zakładam, że poziom bezpieczeństwa nie jest najwyższy. Oczywiście zasilanie bateryjne jak najbardziej wskazane. Zanim zacznę budować coś swojego chciałem zorientować się czy są takowe dostępne w handlu lecz nie mam pojęcia jak tego szukać, jakie to są urządzenia i gdzie znajdują zastosowanie.
  6. Witam, Poszukuje urządzenia lub zestawu urządzeń które pozwoli na wykrycie obecności innego urządzenia gdy to jest w pobliżu. Np baza, która zareaguje w określony sposób gdy zbliży się do niej jakiś czujnik. Zasięg max 5 m, nawet mniej. Ważne też aby czujnik/odbiornik był rozmiarów kieszonkowych. Czy zna ktoś takie rozwiązanie dostępne w handlu?
  7. Nie spodziewałem się tak obszernej i rzeczowej pomocy, jestem zaskoczony i niezmiernie wdzięczny:) Układ o któym mowa to C8051f120 od silicon labs. Pobrane dane nie są zewnętrzne lecz pochodzą z wewnętrznego przetwornika. Moim zadaniem jest tą funkcję zmodyfikować tak aby liczyć fft, a konkretnie daną harmoniczną. Uczę się asemblera stopniowo i tak naprawdę dopiero teraz poznaje mikrokontrolery. Jeszcze raz wielkie dzięki za naprawde pomocne odpowiedzi. Zapewne odezwę się z kolejnymi problemami. Pozdrawiam!
  8. Potrzebuje pomocy w analizie kodu dla 8051 od silicona w asm. Jest to problem natury dydaktycznej. Całe życie pracuje w c i nie znam ani trochę asemblera. Czy mógłby ktoś oświecić mnie w kilku kwestjach składniowych? Mianowicie: obl_20: movx A, @R0 mov MAC0AH, A mov MAC0BH, A inc R0 movx A, @R0 mov MAC0AL, A mov MAC0BL, A ; This line initiates the Multiply operation inc R0 djnz R3, obl_20 mov SFRPAGE, #CONFIG_PAGE cpl OBL_pin ret Czy dobrze kombinuje, że działa to tak: 1 do A (akumulatora???) przenosimy zawartość rejestru(?) R0 N 2 Następnie z A przepisujemy wartości do dwóch bajtów MAC ( mnożarki z 16 bitowej z dodawaniem ) 3 później zwiększamy R0 4. tak samo do kolejnych dwóch bajtów MAC W efekcie w rejsetrach MAC powinni być: MAC0AH = A MAC0AL= A MAC0BH = A MAC0BL = A Gdzie MAC0AH i MAC0AL to jedno 16 bitowe słowo, co powinno dać działanie : (256*A + 256*A) * (256*A + 256*A) ? A- wartość przepisana z rejestru R0. 6. następnie dekrementuj R3, lub skocz do obl_20 jeśli 0. Czyli po polsku for(R3=x, R3>0, R3--)? Nastomiast kompletnie nie czasje co mówi linia mov SFRPAGE, #CONFIG_PAGE Czy mogę liczyć na pomoc?
  9. Ok. szybkość zmian poznam badając pochodną, ale sygnał nie zmienia się pomiędzy wartościami od -1 do 1, lecz aplituda jest nieznana. Dla różnych wartości amplitudy będą różne pochodne dla tego samego kąta.
  10. Nie wiem czy to dobry dział, lecz szukam informacji na temat obliczeń, które wykonać się mają za pomocą układu stm32f4. Pierwsza sprawa, czy realny jest pomiar na 8 kanałach z częstotliwością próbkowania powiedzmy 32 próbki na okres? Ostatnio takie coś robiłem na atmedze i szczytem był pomiar na 2 kanałach z obliczaniem wartości skutecznej. Kolejna sprawa to właściwy problem. Mianowicie należy obliczyć przesunięcie fazowe między sygnałami na podstawie próbek. Nie wchodzi w grę szukanie przejścia przez zero i odmierzanie czasu. Czy istnieje algorytm obliczania tego na podstawie próbek w czasie rzeczywistym? Dodam, że sygnały są czysto sinusoidalne o jednakowej częstotliwości oraz nieznane są amplitudy.
  11. Ciąg dalszy poznawania STMa. Po udanym ogarnięciu SysTick i GPIO przyszedł czas na USART. Jako że to ustrojstwo operuje na napięciu 3,3V nie mam za bardzo jak przesyłać danych do konsoli - może max3232 rozwiąże problem, ale to już nie dziś, wymyśliłem sobie, że po prostu połączę piny Rx i Tx i to co wyślę natychmiast odbiorę i wyśietle sobie na LCD. Jak pomyślałem tak zrobiłem i jak zawsze nie działa. Na początku chciałbym bez wydziwnień z przerwaniami zrobić taki manewr. Może niedziała dlatego, że jest to niedopuszczalne a może dlatego, że coś źle ustawiam, więc zanim zacznę kombinować inne odbiorniki chciałbym aby ktoś sprawdził czy dobrze konfiguruję USART. #include <stm32f4xx_rcc.h> #include <stm32f4xx_gpio.h> #include <stm32f4xx_usart.h> #include <misc.h> #include "system_stm32f4xx.h" #include "hd44780.h" #include <stdio.h> int main(void) { SystemInit(); unsigned int a ; SystemCoreClockUpdate(); a = SystemCoreClock; if (SysTick_Config(SystemCoreClock/100 )) { while (1){}; } SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); LCD_Initialize(); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); RCC_AHB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx; USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USART_Cmd(USART1,ENABLE); while(1) { LCD_WriteText(" "); USART_SendData(USART1,1); int c=USART_ReceiveData(USART1); char tekst[10]; sprintf(tekst,"%d",c); LCD_GoTo(0,0); LCD_WriteText(tekst); } } czy taka konfiguracja USART jest wystarczająca?
  12. Problem rozwiązany. Dodałem biblioteke syscalls z repository->common ->C library
  13. Zwracam się z pewnym upierdliwym problemem. Mianowicie używam coocoxa do programowania stm32f4. Wszystko gra dopóki chcę użyć biblioteki standardowej. Mianowicie do konwersji zmiennej liczbowej na tekstową chcąc użyć funkcji itoa lub sprintf, kompilator zaczyna krzyczeć. #include <stm32f4xx_gpio.h> #include "system_stm32f4xx.h" #include <stdio.h> #include <stdlib.h> int main(void) { while(1) { int c=10; char tekst[10]; sprintf(tekst,"%d",c); } } Treść komunikatu: Obawiam się, że to błąd od strony linkera, co jest dla mnie nie do przeskoczenia, gdyż zawsze używałem jakiegoś IDE czy to dla avr czy dla stm, więc o linkerze wiem tylko tyle, że istnieje. Czy może ktoś mi pomóc w tej sytuacji?
  14. 1. Zasilam z transformatora 230/8 V -> mostek prostowniczy -> 7805 z kondensatorami 2x2000uF. Reszta połączeń jak na schemacie. 2. 10k. Ale to raczej nie ma znaczenia bo liczy się stosunek dzielnika. 3. Tak też zrobiłem. Problem rozwiązałem. Zbyt szybko dokonywane były kolejne pomiary. opóźnienie pomiędzy nimi rozwiązało problem.
  15. Panowie Kombinuje z pomiarem napięcia na potencjometrach z wykorzystaniem atmego32. 4 potencjometry podpięte do 4 kanałów ADC. Schemat: kod: ADMUX |= (1<<REFS0); ADCSRA |= (1<<ADEN) | (1<<ADPS1) |(1<<ADPS0) ; char tekst[30]; int a = pomiar_nastawy(0); int b = pomiar_nastawy(1); int c = pomiar_nastawy(2); int d = pomiar_nastawy(3); sprintf(tekst,"%d %d %d %d ",a,b,c,d); uart_puts(tekst); uint16_t pomiar_nastawy(uint8_t kanal) { ADMUX = (ADMUX & 0xF8)| kanal; ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); return ADC; } Problem w tym, ze gdy wszystkie potencjometry są skręcone na 0 to wszedzie są mierzone 0, a gdy wszystkie mają wartość VCC to jest 1023. Jednak gdy kręce tylko jednym, wówczas jego napięcie zmienia się istotnie, lecz nie w całym zakresie - ok od 0 do 950 bitów. Mało tego w na innych kanałach też rejestrowane jest napięcie. Przyjmują one wartości mniejsze i są to dość stabilne wartości. Czy orientuje się ktoś w czym może być problem? Nie sądze aby spadało napięcie źródła, bo na zasilaniu mam 2 kondensatory 2000uF, przez co po odłączeniu od napięcia atmega działa jeszcze kilka sekund.
  16. To już zmieniłem, systick teraz działa dobrze tylko problem się zmienił. Mianowicie sprzęt działa tyko na HSI. Różnica w czestotliwości wynosiła dokładnie 10,5 jak się okazuje, gdyż: Systick w konfuguracji miał podaną częstotliwość docelową PLL 168Mhz, a działał z częstotliwością HSI=16Mhz. Gdy wrzuciłem polecenie SYstemCoreClockUpdate, wówczas zmienna SystemCoreClock aktualizowała się do 16Mhz i już wszystkoo działało poprawnie na zegarze wewnętrznym. Tylko dlaczego nie działa inne taktowanie niż HSI?
  17. No racja, jest tak jak u ciebie. Już mi się to wszysko zlewa. Koniec końców nie potrafię już znaleźć sensownej przyczyny dlaczgo nie może uruchomić się nic innego poza HSI.
  18. void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif /* Reset the RCC clock configuration to the default reset state ------------*/ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset CFGR register */ RCC->CFGR = 0x00000000; /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset PLLCFGR register */ RCC->PLLCFGR = 0x24003010; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Disable all interrupts */ RCC->CIR = 0x00000000; #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ /* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/ SetSysClock(); /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } void SystemCoreClockUpdate(void) { uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFGR & RCC_CFGR_SWS; switch (tmp) { case 0x00: /* HSI used as system clock source */ SystemCoreClock = HSI_VALUE; break; case 0x04: /* HSE used as system clock source */ SystemCoreClock = HSE_VALUE; break; case 0x08: /* PLL used as system clock source */ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N SYSCLK = PLL_VCO / PLL_P */ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; if (pllsource != 0) { /* HSE used as PLL clock source */ pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); } else { /* HSI used as PLL clock source */ pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); } pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; SystemCoreClock = pllvco/pllp; break; default: SystemCoreClock = HSI_VALUE; break; } /* Compute HCLK frequency --------------------------------------------------*/ /* Get HCLK prescaler */ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; /* HCLK frequency */ SystemCoreClock >>= tmp; } static void SetSysClock(void) { /******************************************************************************/ /* PLL (clocked by HSE) used as System clock source */ /******************************************************************************/ __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; /* HCLK = SYSCLK / 1*/ RCC->CFGR |= RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK / 2*/ RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; /* PCLK1 = HCLK / 4*/ RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; /* Configure the main PLL */ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); /* Enable the main PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till the main PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; /* Select the main PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= RCC_CFGR_SW_PLL; /* Wait till the main PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } } Na rejestrach jeszcze nie znam się praktycznie wcale, więc nie umiem nic z tego wywnioskować. W każdym razie zmienna tmp w SystemCoreClockUpdate nie zmienia wartości. Jest zawsze 0. Zastanawia mnie jednak zapis tmp = RCC->CFGR & RCC_CFGR_SWS patrząc w delkaracje RCC_CFGR_SWS ona ma wartość przypisaną na sztywno 0, więc tmp będzie zawsze zero... Podmieniłem nawet treść pliku system_stm32f4xx.c na plik pobrany z strony stm z przykładami i bazą dla discovery i wciąż ta sama historia.
  19. To by się zgadzało. SysTickowi podaję na siłe taktowanie 168 Mhz, zaś system przełącza się na 16Mhz, co daje 10,5 raza mniejsze taktowania, stąd ponad 10 razy wolniej miga dioda co pisałem wcześniej:) Zaglądam do funkcji void SystemCoreClockUpdate(void) i tam ustawiłem na siłę tmp=0x08. Z takim ustawieniem musiał przełączyć się na PPL co w rezulatacie dało SYstemCoreClock =96 Mhz podczas debugowania. Co mnie troche dziwi bo nie wiem kompletnie skąd ta wartość. Aczkolwiek mimo to i tak system przełącza się na HSI, a 96 MHz jest tylko wartością zwracaną przez funkcję, która pełni rolę informacyjną, tak myślę. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ #define PLL_M 8 #define PLL_N 336 /* SYSCLK = PLL_VCO / PLL_P */ #define PLL_P 2 /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ #define PLL_Q 7 z stm32f4xx.h: #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ To są moje ustawienia. Czyli wniosek taki, że coś niedobrego jest z PPL lub kwarcem, gdyż nie chce się przełączyć na tą częstotliwość.
  20. Dobra, no to includuje sobie rzeczoną misc.h w pliku main. W misc.c widzę funkcje : void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) Domniemam więc, ze jest to funkcja konfiguracji źródła taktowania dla systic. No to idąc dalej ustawiam: SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); Teraz zdaje się ustawiłem źródło taktowania jako HCLK. sumarycznie spłodziłem taki kod: #include <stm32f4xx_rcc.h> #include <stm32f4xx_gpio.h> #include <misc.h> volatile int b; int main(void) { //SystemCoreClockUpdate(); unsigned int a = SystemCoreClock; GPIO_InitTypeDef GPIO_InitStructure; // Wlaczenie sygnalu taktujacego port D RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD , ENABLE); GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_12 | GPIO_Pin_14); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); // Wyzerowanie wyjscia PD14 GPIO_ResetBits(GPIOD, GPIO_Pin_14); // Ustawienie wyjscia PD12 GPIO_SetBits(GPIOD, GPIO_Pin_12); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); if (SysTick_Config(SystemCoreClock / 1000)) { while (1){}; // error } while(1){ } } void SysTick_Handler() { // volatile static int b; b++; if(b==500) { b=0; GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14); } // } Zasadniczo powinno to zwiększyć zmienną b co 0.001 s a co 0,5 s powinna być wykonana akcja zapisana w procedurze przerwania. Jednakże diody migają znacznie rzadzie. Obserwując miganie i nasłuchując tykanie zegarka na ścianie okazało się, że jest to ponad 10 razy dłużej niż 0,5 s i w dodatku nie jest ten czas pełną wielokrotnością. Jednym słowem diody migają z bliżej nieznaną częstotliwością. Czego jescze mi brakuje? Dodam, że gdy zapiszę: SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_[b]Div8[/b]) sytuacja nie zmienia się - częstotliwość migania jest niezmienna Tak zrobiłem i zauważyłem, że gdy umieszcze funkcje SystemCoreClockUpdate() to zmienna SYstemCoreClock przyjmuje wartość 16000000 zgodnie z: #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ Zaś bez tej funkcji SystemCoreClock = 168000000, czyli tyle ile ma byc. Wniosek taki, że ta funkcja nadpisuje to co wcześniej ustawiłem. Na razie nie chcę się w to zagłębiać, przymę to na wiarę, później będzie czas na grzebanie w źródle tych funkcji. edit: Dołożyłem SystemCoreClockUpdate i teraz jest ładnie tak jak trzeba ale.. SystemCoreClock przyjmuje wartość 16000000 a tego przecież nie chcę.
  21. Tak, nie tren screen, już poprawiłem. Dalej zaczynają się schody. Biblioteka jaką widze w repository to stm32f4xx_tim.h, lecz tam nigdzie nie widzę odwołań do jakiejkolwiek konfiguracji SysTic. Nie upieram się aż tak bardzo na ten licznik czasu, ale jeśli zaczynać od podstaw to myślę, że to jest elementarna sprawa.
  22. Panowie. Szukam odpowiedzi na wiele pytań, ale myślę, że takich jak ja jest ogrom. Mianowicie, zachciało mi się przesiąść z avr na jakieś arm. Wybór padł na STM32f4 na płytce discovery. Poczytałem to i tamto, troche artykułów, troche literatury i doszedłem do wniosku, że nie potrzebnie kupiłem płytkę z cortexem M4, raczej mogłem zacząć od M3. No ale skoro już mam, to niech zostanie, spróbuje z tym ruszyć. Jest mnustwo tutoriali na temat organizacji środowiska, lecz większość jest dla M3, choć postępując analogicznie napotkałem troche trudności, lecz w końcu się udało. To znaczy korzystam, a raczej próbuje korzystać, z CooCox, gdyż poszedł mi z kopyta bez najmniejszych problemów. Spodobało mi się to, że mogłem sobie wybrać jakie biblioteki chcę dorzucić, bez kombinowania z przenoszeniem wszelakich plików etc. Kożystając z tego poradnika: http://mikrokontroler.pl/content/coocox-coide-i-stm32f4discovery-%E2%80%93-jak-zacz%C4%85%C4%87 nauczyłem się mniej więcej działać na portach GPIO korzystając z API. Teraz czas na Timery i inne pierdoły. Jak na razie mam wyobrażenie tylko o modelu jaki jest w avr - tj. ustawiamy rejestry timera w main(), a na dole procedura obsługi przerwania. Teraz troche cieżko mi to przychodzi. Załóżmy, że chciałbym wykorzystać SysTick i przy przejściu przez 0 wykonać jakieś działanie (mignąć diodą czy cokolwiek). Niech będzie, że mam kod taki jak w tym tutorialu: #include <stm32f4xx_rcc.h> #include <stm32f4xx_gpio.h> void Delay(void) { volatile uint32_t i; for (i = 0; i != 0xFFFFF; i++); } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; // Wlaczenie sygnalu taktujacego port D RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD , ENABLE); GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_12 | GPIO_Pin_14); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); // Wyzerowanie wyjscia PD14 GPIO_ResetBits(GPIOD, GPIO_Pin_14); // Ustawienie wyjscia PD12 GPIO_SetBits(GPIOD, GPIO_Pin_12); while(1){ // Zmiana stanu wyjsc na przeciwny GPIO_ToggleBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14); // Czekaj Delay(); } } Pierwsza sprawa co z taktowaniem? Tam jest napisane, że w jednym z plików, należy zmienić watość 25 na 8, co uczyniłem. To wszystko? W poradnikach dla M3 często była funkcja RCC_config...A tutaj tylko dostosowanie do aktualnego kwarcu? Docelowo chciałbym aby while(1) był pusty a diody niech migają dzięki SysTick. Rozumiem, że trzeba go najpierw skonfigurować, a później umieścić procedure obsługi przerwania, tak? Czy wystarczy zaincludwana biblioteka "stm32f4xx_rcc"? Okno coocoxa wygląda tak: Czy może ktoś naprowadzić mnie na poprawne rozwiązanie mojego problemu? Jak opanuję to to przejdę do kolejnych peryferiów.
  23. Dziękuję za wyczerpujący opis mechanizmu. Ostatecznie okazuje się, że tak jak już napisałem najlepsze efekty daje próbkowanie z częstotliwością 801 Hz. OCR = 38 i preskaler = 256. Daje to 16,02 próbki na okres. Przy 256 bitach mam praktycznie równe 16 próbek i dziele przez 256 co mieści się w czasie. Aczkolwiek docelowo jest to troche mała szybkość próbkowania. Zakładam teraz, że wystarczy mi wartość skuteczna w postaci kwadratu lu bteż pierwiastka bez dzelenia pod nim. Przy takiej długości tablicy. Jeśli usunąbym którąś z tych czasochłonnych operacji to sądzę iż możnaby obrać większą prędkość a przede wszytkim dowolną długość tablicy, dla okrągłej dla okrągłej liczby próbek. Jeśli tylko zmienię funkcję pomiarową na typ uint32, oraz rms_u na uint32 to nie jest przekazywana żadna wartość z funkcji.
  24. Dobrałem timer tak aby przypadło..16 próbek na okres - preskaler 256, OCR = 38. Śmiesznie mało ale jak na razie działa to najlepiej z wszytkich prób. kolejne wyniki są bardzo zbieżne. Obrałem 256 próbek w tablicy gdyż na tyle pozwala pamięć a razrazem potęgi dwójki dzieli najszybciej. Przy szybszym próbkowaniu było lepiej gdy dla 52 próbek na okres tablica miala 260 elementów. Dokładna liczba elementów ma jednak spore znaczenie. W pętli głównej dokonuje porównania otrzymanych wartości z wartościami nastawczymi. Myślę sobię, że mógłbym nie dzielić wyniku przez liczbę próbek i porównywać wynik z wartością nastawczą przemnożoną przez liczbę próbek. Na jedno by wyszło a unikam dzielenia. Ale... kod wyjściowy: uint16_t pomiar_u(void) { static uint16_t tab_u[256]; static uint8_t indeks_u; float rms_u; static uint64_t suma_u; uint8_t b,c; PORTB &=~(1< wyslij_spi(0b00011000); b=wyslij_spi(0x00); c=wyslij_spi(0x00); PORTB|=(1< c=c; b=b&0x1F; indeks_u++;// if (indeks_u ==1023) indeks_u=0; suma_u -= (uint32_t)tab_u[indeks_u]*tab_u[indeks_u]; tab_u[indeks_u] = (uint16_t)256*b+c; suma_u += (uint32_t)tab_u[indeks_u]*tab_u[indeks_u]; rms_u= sqrt(suma_u/256); return (rms_u); } Wartość rms_u do któej przekazywany był wynik powinna teraz mieć inną wielkość. Wrzucam do niej pierwiastek sumy, która to jest 64 bitowa, więc pierwiastek powinien mieć max 32 bity. Obieram uint 32_t rms_u a całą funkcje robię również 32 bitową, gdyż taką wartość będzie zwracać. Usuwam dzielenie i rzutuję wynik pierwiastkowania na uint32. Otrzymałem taki twór: uint32_t pomiar_u(void) { static uint16_t tab_u[260]; static uint8_t indeks_u; uint32_t rms_u; static uint64_t suma_u; uint8_t b,c; PORTB &=~(1< wyslij_spi(0b00011000); b=wyslij_spi(0x00); c=wyslij_spi(0x00); PORTB|=(1< c=c; b=b&0x1F; indeks_u++;// if (indeks_u ==1023) indeks_u=0; suma_u -= (uint32_t)tab_u[indeks_u]*tab_u[indeks_u]; tab_u[indeks_u] = (uint16_t)256*b+c; suma_u += (uint32_t)tab_u[indeks_u]*tab_u[indeks_u]; rms_u= (uint32_t) sqrt(suma_u); return (rms_u); } I brak reakcji. Diody kontrolne nie świecą. Czy wniosek jest taki, że pierwiastek z 64 bitowej sumy nie zawsze musi być 32 bitowy?
×
×
  • Utwórz nowe...