Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'STM32'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - roboty
    • Projekty - DIY
    • Projekty - DIY (początkujący)
    • Projekty - w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie
    • Kosz

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Znaleziono 72 wyników

  1. Po udanym projekcie robota "Copernicus" - w szeregowym łańcuchu kinematycznym 4DOF przyszedł czas na robota klasy delta, nazwanego "Astra", ponieważ ramiona układają się właśnie w gwiazdę Prototyp prezentowałem na targach Hobby 2019 na Międzynarodowych Targach Poznańskich, generalnie nie ma nic rewolucyjnego - zasilacz 36V, 3 silniki NEMA17 z przekładniami planetarnymi, przeguby kulkowe firmy Igus® (serdecznie dziękuję), zerowanie - krańcówki, eżektor, ssawka, w pierwszej wersji - Arduino Mega, teraz to już Discovery F429 z wyświetlaczem LCD (wyświetlam na nim koordynaty, chciałbym też obsługiwać dotyk, ale dodanie biblioteki do obsługi dotyku kłóci się ze sterowaniem silnikami krokowymi ). Aktualnie, robot potrafi wykonać proste zadanie pick&place Projekt cały czas ewoluuje (określiłbym postęp na 60%), mam zamontowaną RPi 3B+ z kamerką, chciałbym dodać podajnik obrotowy, rozpoznawać kolor krążków i układać do określonych pojemników, a na koniec pudełeczko z posortowanymi elementami pneumatycznie wysunąć - chyba, że komuś przychodzi na myśl coś lepszego? (ale, żeby z wykorzystaniem pneumatyki, mam do dyspozycji dużo różnych siłowników i kilka chwytaków ), z góry mówię, że znam aplikację taśmociągu i systemu wizyjnego Podziękowania składam również dla Kolegi @Eukaryota za pomoc i inspirację Pozdrawiam
  2. Witam, muszę zaimplementować odczyt temperatury z czujnika DHT11 poprzez STM32F103RB i wysyłać to poprzez USART(9600b/s). Korzystam z DWT_delay aby mieć opóźnienie w us do inicjalizacji DHT. Problem polega na tym, że mikroprocesor pobiera dane tylko raz i zawiesza się. USART obsługuje przerwania i jest zaimplementowany na buforze kołowym(piny domyślnie PA2-PA3). Dodatkowo mam wyświetlacz 7-segmentowy i docelowo chce na nim wyświetlać dane ( podpięcia PA0-PA1,PA4-PA8) z czujnika(PA9). Po resecie z watchdoga/czarnego buttona na nowo pobrane są dobre dane. W załączniku podsyłam program main z CubeIDE. ProjectMain.zip
  3. Poniższe pytanie zostało wydzielone z kursu: https://forbot.pl/forum/topic/10506-kurs-stm32-f1-hal-8-bezposredni-dostep-do-pamieci/ Witam W zadaniu 8.1 wyniki z copy_cpu() i copy_dma() mam jednakowe i są następujące: Bufor zrodlowy: 536873560 Bufor docelowy: 536873592 Jak widać, wartości są różne. W ogóle wyświetlam wartości src_buffer i dst_buffer za pomocą printf. Jakiego formatu używać do wyświetlania liczb typu uint8_t albo uint16_t, bo %d zwraca ostrzeżenia.
  4. Witam, Jestem początkującym w programowaniu STM32F103. Do tej pory programowałem Microchip PIC 8 bitowe w asm i C. Zakupiłem zestaw STM32F103 Nucleo i uczę się programowania z kursu, jest bardzo ciekawy i pomocny. Zgodnie z kursem uruchomiłem UART, przetwornik ADC na DMA, przerwanie na TIM2 z częstotliwością 4kHz, PWM 12kHz. W przerwaniu przepisuję wartość z przetwornika ADC (po przeskalowaniu od 0 - 1000) i zmieniam wypełnienie PWM. Pojawia się problem z przebiegiem PWM. Proszę o pomoc w rozwiązaniu problemu. Pozdrawiam. Jurek /** ****************************************************************************** * @file main.c * @author Ac6 * @version V1.0 * @date 01-December-2013 * @brief Default main function. ****************************************************************************** */ #include <stdio.h> #include <stdint.h> #include "stm32f10x.h" #include <math.h> #define ADC_CHANNELS 2 TIM_OCInitTypeDef channel; // PWM volatile uint32_t timer_ms = 0; uint16_t adc_value[ADC_CHANNELS]; volatile int32_t PID; volatile uint16_t PID_PWM; volatile uint32_t old_adc_0, old_adc_1; void SysTick_Handler() { if (timer_ms) timer_ms--; } void TIM2_IRQHandler() { if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); GPIO_SetBits(GPIOA, GPIO_Pin_5); PID = (adc_value[0] / 4); PID_PWM = PID; channel.TIM_Pulse = PID_PWM; TIM_OC1Init(TIM4, &channel); GPIO_ResetBits(GPIOA, GPIO_Pin_5); //if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5)) //GPIO_ResetBits(GPIOA, GPIO_Pin_5); //else //GPIO_SetBits(GPIOA, GPIO_Pin_5); } } void delay_ms(int time) { timer_ms = time; while (timer_ms); } void send_char(char c) { while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, c); } int __io_putchar(int c) { if (c=='\n') send_char('\r'); send_char(c); return c; } int main(void) { //int8_t i; GPIO_InitTypeDef gpio; USART_InitTypeDef uart; DMA_InitTypeDef dma; ADC_InitTypeDef adc; TIM_TimeBaseInitTypeDef tim; // Timer 2 NVIC_InitTypeDef nvic; // Timer 2 //TIM_OCInitTypeDef channel; // PWM RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); GPIO_StructInit(&gpio); gpio.GPIO_Pin = GPIO_Pin_5; gpio.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &gpio); //*** konfiguracja pinow UART gpio.GPIO_Pin = GPIO_Pin_2; gpio.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &gpio); gpio.GPIO_Pin = GPIO_Pin_3; gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &gpio); //*** //*** PWM wyjscia gpio.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &gpio); //*** USART_StructInit(&uart); uart.USART_BaudRate = 115200; USART_Init(USART2, &uart); USART_Cmd(USART2, ENABLE); //*** ustawienie wejsc przetwornika A/D gpio.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; gpio.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &gpio); //*** //*** ustawienie DMA do odczytu wejsc przetwornika A/D DMA_StructInit(&dma); dma.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma.DMA_MemoryBaseAddr = (uint32_t)adc_value; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dma.DMA_DIR = DMA_DIR_PeripheralSRC; dma.DMA_BufferSize = ADC_CHANNELS; dma.DMA_Mode = DMA_Mode_Circular; DMA_Init(DMA1_Channel1, &dma); DMA_Cmd(DMA1_Channel1, ENABLE); //*** ADC_StructInit(&adc); adc.ADC_ScanConvMode = ENABLE; adc.ADC_ContinuousConvMode = ENABLE; adc.ADC_NbrOfChannel = ADC_CHANNELS; adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_Init(ADC1, &adc); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 2, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); SysTick_Config(SystemCoreClock / 1000); // *** Timer4 jako PWM //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_TimeBaseStructInit(&tim); tim.TIM_ClockDivision = 0; tim.TIM_RepetitionCounter = 0; tim.TIM_CounterMode = TIM_CounterMode_Up; tim.TIM_Prescaler = 5 - 1; tim.TIM_Period = 1000 - 1; TIM_TimeBaseInit(TIM4, &tim); //*** //*** ustawienia kanalow PWM TIM_OCStructInit(&channel); channel.TIM_OCMode = TIM_OCMode_PWM1; channel.TIM_OutputState = TIM_OutputState_Enable; channel.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //channel.TIM_Pulse = PID_PWM; //TIM_OC1Init(TIM4, &channel); channel.TIM_Pulse = 200; TIM_OC2Init(TIM4, &channel); channel.TIM_Pulse = 500; TIM_OC3Init(TIM4, &channel); channel.TIM_Pulse = 900; TIM_OC4Init(TIM4, &channel); TIM_Cmd(TIM4, ENABLE); //*** //*** Timer 2 TIM_TimeBaseStructInit(&tim); tim.TIM_CounterMode = TIM_CounterMode_Up; tim.TIM_Prescaler = 640 - 1; tim.TIM_Period = 25 - 1; TIM_TimeBaseInit(TIM2, &tim); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE); nvic.NVIC_IRQChannel = TIM2_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); //*** while (1) { //GPIO_SetBits(GPIOA, GPIO_Pin_5); //printf("ADC%d = %d\n", 0, adc_value[0]); //printf("A = %d (%.3fV)\n", PID); //channel.TIM_Pulse = PID_PWM; //TIM_OC1Init(TIM4, &channel); printf("%d\n",PID); //GPIO_ResetBits(GPIOA, GPIO_Pin_5); delay_ms(1); } }
  5. Dzień dobry, Pojawił się u mnie niedawno problem, uruchomiłem dwa wejścia ADC z pomocą DMA - podłączyłem do nich zwykłe potencjometry, działały one poprawnie lecz przy grzebaniu w hardware mogłem podpiąć napięcie wyższe niż 3,3 V i nagle przetworniki pokazują jedynie maksymalną wartość, a gdy zamienię kable zasilające potencjometr to pokazują wartość minimalną. Czy jest to możliwe, że załatwiłem tym sposobem przetwornik ADC? napięcie mogło wynosić około 3,5 V, potencjometry działają poprawnie. Korzystam z płytki rozwojowej STM32F103C8T6, załączam dodatkowo rysunek z połączeniem potencjometrów oraz projekt CubeIDE asdas.rar
  6. Cześć! Jako że już po sezonie to postanowiłem opisać tu moją i mateuszm konstrukcję. Robot powstał w ramach rekrutacji do koła naukowego robotyków KoNaR i debiutował na Robotic Arenie 2015. Był to nasz debiut w konstruowaniu robotów, ponieważ wcześniej żaden z nas tego nie robił. Mechanika Głównym założeniem mechaniki robota było wykorzystanie w pełni maksymalnej dopuszczalnej masy oraz skupienie jej w podstawie. W osiągnięciu tego celu pomógł nam projekt Autodesk Inventor, w którym to został wykonany szczegółowy projekt robota uwzględniający wszystkie drobne elementy mechaniczne. Podstawa robota została wykonana z trzech elementów: - ostrze z węglika spiekanego - płytka stalowa 3mm - płytka górna, 2mm, która łączyła dwa elementy wymienione wyżej W płytkach zostały wycięte otwory, w których następnie umieszczone były małe, okrągłe płytki z czujnikami białej linii. Stal była cięta laserowo oraz później frezowana. Napęd robota stanowiły znane i lubiane silniczki Pololu HP z przekładnią 50:1 przykręcone bezpośrednio do podstawy za pomocą dedykowanych mocowań. Podpięte do elektroniki były przy pomocy złączy ARK co umożliwiło ich łatwy demontaż w celach serwisowych. Obudowa robota została wykonana z laminatu 1mm. Na obudowie znajduje się nazwa robota oraz nasze imiona i nazwiska. Obudowa mocowana jest do podstawy za pomocą śrub, a jej elementy są do siebie lutowane. Dach robota wykonaliśmy z 2 mm przeźroczystego szkła akrylowego. Finalnie robot mierzy w najwyzszym miejscu 33,7 milimetra od podstawy do dachu, a od podłoza do dachu 37,2. Jego podstawa ma wymiary 98,9 mm na 99,6 mm. Masa waha się od 490 do 499g w zależności jak bardzo nakarmimy robota przed zawodami Elektronika Priorytetem projektu robota była jego dobra konstrukcja mechaniczna, w wyniku czego wymiary płytki z elektroniką były z góry narzucone. Elektronika została zaprojektowana w programie KiCad po zaimportowaniu wymiarów przeznaczonych na nią z programu Inventor. Elektronika robota dzieli się na dwie płytki: główną, która znajduje się tuż nad podstawą robota oraz dodatkowej, na której umieściliśmy włącznik zasilania, interfejs komunikacyjny oraz złącze na moduł startowy. Płytki połączone zostały ze sobą taśmą FFC. Mała płytka widoczna na zdjęciu nad płytką główną służy nam jako podstawka pod akumulator LiPo 7.4V, którym zasilamy robota. Sercem naszego robota został mikroprocesor STM32F1. Wybór tej rodziny wynikał z łatwości ich programowania przez początkujących. Czujniki odległości wykorzystane w robocie to znane i lubiane cyfrowe Sharpy 40cm. Umieściliśmy je 4, dwa z przodu oraz po jednym na bokach. Na czujniki białej linii użyliśmy dwa KTIRy 0711S. Jak wcześniej wspomniałem zostały one umieszczone na małych płytkach, które umieściliśmy w wycięciach w podstawie. Na sterowniki silników wybraliśmy dwa, podwójne mostki H TB6612. Zostały one dobrane ze względu na ich dobrą wydajność prądową, co umożliwiło nam skuteczne wysterowanie silników Pololu bez obawy o to, że przy pełnym zwarciu mostki ulegną uszkodzeniu. Płytki zostały wykonane metodą termotransferu oraz wyfrezowane za pomocą Dremela i pilników ręcznych. Software Kod robota został napisany w środowisku System Workbench for STM32 (SW4STM32) z użyciem generatora kodu konfiguracyjnego STM32CubeMX. Program podzielony był na dwie sekwencje: startową i walki. W pierwszej ustawiana była konfiguracja algorytmu robota oraz dostępne były funkcje testu czujników (widoczny na zdjęciu poniżej - cztery czerwone diody, które odpowiadały za pokazanie aktualnego stanu czujników) oraz czyszczenia kół (drobna funkcja pomocnicza ustawiająca małą prędkość na kołach). Sekwencja walki załączała się po otrzymaniu przez robota sygnału startowego z modułu. Większa część algorytmu walki opierała się na prostych if-ach z odpowiednio dobranymi nastawami silników w każdym przypadku, co okazało się wystarczające w większości starć. Następnie zostały dodane pewne udoskonalenia, o których już rozpisywać się nie będę Osiągnięcia - II miejsce Robomaticon 2016 - I miejsce Robotic Tournament 2016 - III miejsce Festiwal Robotyki Cyberbot 2016 - II miejsce [Minisumo] oraz I miejsce [Minisumo Deathmatch] Trójmiejski Turniej Robotów 2016 - II miejsce Opolski Festiwal Robotów 2016 - I miejsce Robotic Day 2016 [Praga] A poniżej kilka filmów z udziałem robota: 2Weak4U vs Hellfire 2Weak4U w Wiedniu 2Weak4U vs Dzik 2Weak4U vs Shevron (chyba) 2Weak4U w Deatmatchu [Rzeszów] 2Weak4U vs Szwagier Pozdrawiam i do zobaczenia w następnym sezonie, Aleksander
  7. Witajcie Realizuję komunikację pomiędzy mikroprocesorem STM32F411RE (NUCLEO) a modułem SIM800L. Wykorzystuję do tego interfejs UART. Inicjalizuję go poprzez bibliotekę HAL'a. Samą wymianę danych postanowiłem zrobić ręcznie, odwołując się bezpośrednio do rejestrów UART. Poniżej funkcja inicjalizacyjna: void uart_init(uint32_t baud) { uart_gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10; //TX RX uart_gpio.Mode = GPIO_MODE_AF_PP; uart_gpio.Alternate = GPIO_AF7_USART1; uart_gpio.Speed = GPIO_SPEED_HIGH; uart_gpio.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA,&uart_gpio); usart.Instance = USART1; usart.Init.BaudRate = baud; usart.Init.Parity = USART_PARITY_NONE; usart.Init.StopBits = USART_STOPBITS_1; usart.Init.WordLength = USART_WORDLENGTH_8B; usart.Init.Mode = USART_MODE_TX_RX; HAL_USART_Init(&usart); } Sama komunikacja odbywa się w funkcji "sim_reception", w przerwaniu od timera mikroprocesora. #define SIM_TX_BUF_SIZE 32 #define SIM_RX_BUF_SIZE 32 volatile unsigned char sim_tx_buf[SIM_TX_BUF_SIZE]; volatile unsigned char sim_rx_buf[SIM_RX_BUF_SIZE]; volatile unsigned char sim_tx_len = 0; volatile unsigned char sim_rx_len = 0; enum { handshake, hdsh_resp }; volatile uint8_t sim_states = handshake; #define SIM_HNDSHK "AT\r\n" void sim_reception(void) { //RX //if Receiver not empty flag is set and we have space in rx buffer, we read byte while(USART1 -> SR & USART_SR_RXNE) { if(sim_rx_len < SIM_RX_BUF_SIZE) sim_rx_buf[sim_rx_len++] = USART1 -> DR; //after reading byte we increment buffer length else break; } //TX //if Transmitter empty flag is set and we have data in tx buffer, we send byte while(USART1 -> SR & USART_SR_TXE) { if(sim_tx_len != 0) { USART1 -> DR = sim_tx_buf[0];//send one byte sim_byte_up(sim_tx_buf); //shift one byte up } else break; } switch(sim_states) { case handshake: sim_tx_buf_put(SIM_HNDSHK); sim_states = hdsh_resp; break; case hdsh_resp: break; default: sim_states = handshake; break; } } Na razie chcę wysłać tylko jedno polecenie i odczytać odpowiedź modułu SIM800L. Krótko opiszę nadawanie, które działa bez zarzutu. Wywołuję funkcję "sim_tx_buf_put", która napełnia bufor komendą "SIM_HNDSHK", zdefiniowaną wyżej za pomocą #define. Funkcja bada ile miejsca mamy w buforze i czy wystarczy go jeszcze dla nowego polecenia. Jeśli tak to wstawia je bajt po bajcie i zwiększa odpowiednio zmnienną "sim_tx_len". Nie będe wstawiał kodu tej funkcji, ponieważ działa ona bardzo dobrze, nie mam z nią problemu. Wyżej w kodzie widać, że jest badany stan flagi "Transmitter Empty", gdy się ona pojawi i w buforze Tx są dane przystępuje się do wysyłania danych bajt po bajcie. Po każdym wysłanym bajcie wywoływana jest funkcja "sim_byte_up", która przesuwa bajty bufora "o jeden w górę", czyli sim_tx_buf[0] = sim_tx_buf[1], sim_tx_buf[1] = sim_tx_buf[2] itd. oraz zmniejsza wartość "sim_tx_len" o jeden, następnie wysyłany jest kolejny bajt i tak do opróżnienia bufora. Nadajnik działa jak należy, co pokazuje screenshot z analizatora stanów logicznych. Po wysłaniu wiadomości "AT\r\n" moduł SIM800L odsyła odpowiedź. Zatem flaga "Receiver Not Empty" powinna zostać aktywowana, bufor Rx jest pusty, tak więc coś powinno zostać zapisane w buforze. Jednak nic takiego się nie dzieje. Screenshoty z debugowania. W buforze Rx pojawia się tylko jeden bajt o wartości 127. Dalszych procedur odbioru nawet nie opracowałem, bo skoro w buforze odbiorczym nic nie ma... Nie bardzo wiem z czym jest związany ten problem, próbowałem wyprowadzić Tx i Rx we wszystkich możliwych konfiguracjach, jednak zawsze jest tak samo, nadajnik wysyła bez żadnego problemu a odbiornik nie może nic odczytać. Jeśli ktoś ma jakiś pomysł co może być przyczyną problemu i jak to rozwiązać to byłbym bardzo wdzięczny za pomoc Pozdrawiam mw
  8. Dzień dobry, Piszę program do swojego mikrokontrolera STM32F303VCT6, który wysyła sygnał sinusoidalny na rampie do sterowania laserem. Dodatkowo, ten sam mikrokontroler mierzy napięcie na fotodetektorze oraz mnoży te dwa sygnały - sinusoidalny i odbierany. Do tej pory wygląda na to, że wszystko działa. Potrzebuję jednak zaimplementować jeszcze filtr dolnoprzepustowy, który po wymnożeniu tych dwóch sygnałów, przefiltruje mi sygnał tak, aby na innym pinie skonfigurowanym pod przetwornik cyfrowo-analogowy "obetnie" mi żądane częstotliwości. Szukając w internecie implementacji takiego filtra nie uzyskałem satysfakcjonującej mnie odpowiedzi. Czy ktoś mógłby dokładnie wyjaśnić jak to zrobić? A może jest jakaś tego typu funkcja przy wykorzystaniu bibliotek HAL? Z góry dziękuję za pomoc!
  9. To mój pierwszy post na forum więc witam wszystkich Chociaż czytelnikiem jestem już od dawna;p Posiadam płytkę stm32f411re i próbuję przetestować akcelerometr jak w tytule(Był dołączony do kursu STM32F1). Do pomocy korzystałem z obu kursów STM32: F4 (HAL) oraz Kurs F1. Próbowałem już różnych konfiguracji interfejsu, różnych pinów itp. jednak ciągle nie mogę nawet odczytać rejestru WHO_AM_I. Konfiguracja I2C: static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } Adres układu: #define LSM303D_ADDR (0x3a << 1) (Próbowałem też 0x3c oraz opcji bez przesunięcia bitowego) Pętla główna: while (1) { HAL_I2C_Mem_Read(&hi2c1, LSM303D_ADDR, 0x0f, 1, &who_am_i, 1, 100); } Gdzie 0x0f to adres rejestru WHO_AM_I z dokumentacji zamieszczonej w kursie, a &who_am_i to adres zmiennej globalnej typu uint_8t. Dokumentacja LSM303D Układ zmontowany poprawnie, SDA i SCL podpinam pod piny ustawione w Cube, dodatkowo masa i 3v3 do Vin. Oczekiwana wartość rejestru to wg dokumentacji 0x49, jednak śledzenie zmiennej w STMStudio zawsze wskazuje 0. Zaznaczę jeszcze, że próbowałem też odczytywać konkretne wartości z akcelerometru po uprzedniej konfiguracji, ale nigdy nie zadziałało. Zakładam więc, że jest jakiś podstawowy problem z komunikacją układów, dlatego chcę zacząć od poprawnego odczytu who_am_i. Dajcie znać, jeśli czegoś brakuje w opisie. Dzięki.
  10. Mam teraz problem z ostatnim zadaniem. Wprawdzie mam inna plytke (stm32f303re) lecz poza innym maksymalnym taktowaniem zegara wydaje mi sie ze nie ma roznicy w wykorzystywanych funkcjach. Zmienilem odpowiednio wartosci prescaler. Tak wygladają wartości zmiennych: Zmienia sie tylko wartość Duty zaś reszta pozostaje niezmienna. KOd kopiowalem z pliku wprowadzajac potrzebne zmiany. I co najbardziej ciekawe wartości zaczynaja sie zmieniac gdy dotkne niektorych miejsc na plytce (np. styki piny do ktorych sa przypisane timery, ale nie tylko). Wartości zatrzymuje sie wtedy na przykladowo takich liczbach. Wyniki te poza procentem wypelnienia wydaja sie nawet poprawne, lecz ta jedna wartosc nie reaguje wogole na zmiany polozenia pokretla enkodera. Przede wszystkim nie mam pojecia dlaczego niektore miejsca reaguja na dotyk. Jesli to moze pomóc w rozwiazaniu tej zagadki moge zaznaczyc te punkty.
  11. Aktualnie pracuję nad tym kursem: https://forbot.pl/blog/kurs-stm32-f4-5-pomiar-napiecia-adc-dma-stmstudio-id13099 tylko na plytce stm32f303re Znalazłem w dokumentacji mikrokontrolera dane do przeliczania wyniku na stopnie celsjusza, nie wiem czy błąd jest w danych czy w czymś innym ale temperatura znacznie odbiega od tej jaka powinna wyjść według kursu. U mnie jest 40 stopni zas wedlug kursu powinna byc chyba zblizona do temperatury otoczenia. Czy ktos moze mi sprawdzic czy znalazlem poprawne dane i napisalem dobrze kod? Największe wątpliwości mam co do maksymalnego napiecia zasilania. Poniżej zamieszczam screeny ze znalezionymi danymi oraz kod.
  12. Chcę napisac program ktory bedzie zaswiecal stopniowo diode a nastepnie ja gasil w czasie 4s. Znalazlem w reference manual takie informacje na temat przerwania SysTick: więc ustawilem zegar procesora takim taktowaniem jak jest opisane Obliczylem rowniez ze aby dioda zaswiecala sie cyklicznie w czasie 4s trzeba aktualizowac stannapiecia PWM co 40cyklow przerwań, zas timer ustawilem tak aby sygnal PWM przyjmowal 100 wartosci posrednich. Po odpaleniu programu w debugerze wyskakuje mi jakis błąd ktorego nawet nie wiem jak interpretować. Zamieszczam rowniez kod, ktos moze bedzie wiedzial w czym jest problem. main.rar https://forbot.pl/blog/kurs-stm32-f4-8-zaawansowane-funkcje-licznikow-id13473 Robie ten kurs tylko na innym mikrokontrolerze, STM32F303re
  13. Cześć! od wielu dnia(tak) walczę z tym, co na AVRkach można było zrobić w 5 minut z notą katalogową. A mowa o multipleksowaniu wejść przetwornika ADC. Chciałbym w dodatku wykorzystać przerwania bądź DMA. Procek na jakim pracuję to STM32F030F4. W tym momencie konfiguracja wygląda jak na załączonym screenie. Natomiast kod wygląda tak: W sekcji UC(usercode) 2 mam dopisany start: /* USER CODE BEGIN 2 */ HAL_ADC_Start_IT(&hadc); /* USER CODE END 2 */ Natomiast w sekcji PFP dopisałem taką funkcję: /* USER CODE BEGIN PFP */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ reading[0] = HAL_ADC_GetValue(&hadc); } /* USER CODE END PFP */ Efekt? Nic nie działa. Odczyt z przetwornika to wciąż 0. Kiedy robiłem to pollingiem w pętli while, funkcja GetValue zwracała naprzemiennie(ale bez ładu) wyniki z 3 potencjometrów. Natomiast to słaba metoda. jak to ugryźć? Dodam, że w F0 jedyną metodą jest opcja ScanMode.
  14. Próbował może ktoś korzystać z STM32CubeIDE? Zgodnie z tym opisem to jest All-in-one. Czyli może w końcu wszystko działa tak jak powinno?
  15. Witam! Pewnie problem na zasadzie początkującego użytkownika STM32 ale co poradzę - wystąpił ! Mianowicie, mam podłączone 3 przyciski do STM32F103CBT6, przyciski podłączone z rezystorem pull-up i poprzez kondensator filtrujący. W procesorze włączony również pull-up na wejściu od przycisku. Reakcja na wciśnięcie (zbocze opadające) miała być uruchamiana z wykorzystaniem przerwań zewnętrznych. I tu pojawia się problem bo o ile program nie zajmuje się czymś innym albo tylko jakimiś drobnymi rzeczami to wszystko jest w porządku - reakcja następuje od razu. Jeśli tylko zacznę np. więcej rzeczy wyświetlać na OLEDzie to reakcja następuje losowo. Wszystkie przerwania mają priorytety i grupy ustawione na 0. Dodam, że sprawdzałem na oscyloskopie czy występują jakiekolwiek drgania styków - zbocze opadające jest gładziutkie, nie ma możliwości, ze tu coś jest nie halo. Program pisany w HALu tak jak w kursie Forbota. Jeśli będzie potrzeba to dodam listing. Dodatkowo również w ten sam sposób uruchomione są przerwania z zewnętrznego urządzenia i tam wszystko śmiga, no a na przyciskach nie chce - ciekawe. Proszę o jakieś sugestie co to może być, czy ktoś się z czymś spotkał.
  16. Cześć. Mam mały problem z modułem MPU9250, a konkretniej AK8963 (Magnetometr). Odczyt wartości zmierzonych przez akcelerometr i żyroskop nie sprawiły mi większych problemów i wszystko działa prawidłowo. Sprawa skomplikowała się kiedy zechciałem odczytać wartości zmierzone przez magnetometr. Ogólnie komunikacja z magnetometrem działa prawidłowo (WHO_AM_I itd.). Problem polega na tym, że po odczytaniu wartości z rejestrów HXL, HXH... cały czas otrzymuję wartość -1 dla każdej osi. Fragment kodu z inicjalizacją magnetometru: MPU9250_Error_code MPU9250_Magnetometer_Configuration(I2C_HandleTypeDef *I2Cx, struct MPU9250 *DataStructure) { uint8_t Byte_temp = 0x00; uint8_t Bytes_temp[3] = {0}; DataStructure->Magnetometer_addres = 0x0C << 1; // Case 2: Disable the I2C master interface Byte_temp = 0x00; if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Device_addres, MPU9250_USER_CTRL, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } // Case 3: Enable the bypass multiplexer Byte_temp = 0x02; if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Device_addres, MPU9250_INT_PIN_CFG, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } // Case 1: Is device connected ? if( HAL_I2C_IsDeviceReady(I2Cx, DataStructure->Magnetometer_addres, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } // Case 2: Who am i test if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_WIA, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Init_FAIL; } if( Byte_temp != 0x48 ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Init_FAIL; } // Case 4: Setup to fuse ROM access mode and 16-bit output Byte_temp = 0x1F; if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } HAL_Delay(100); // Case 5: Read from the fuse ROM sensitivity adjustment values if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_ASAX | 0x80, 1, Bytes_temp, 3, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } DataStructure->Magnetometer_ASAX = ( ( (Bytes_temp[0] - 128) * 0.5 ) / 128 ) + 1; DataStructure->Magnetometer_ASAY = ( ( (Bytes_temp[1] - 128) * 0.5 ) / 128 ) + 1; DataStructure->Magnetometer_ASAZ = ( ( (Bytes_temp[2] - 128) * 0.5 ) / 128 ) + 1; // Case 6: Reset to power down mode Byte_temp = 0x00; if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } // Case 7: Enable continuous mode 2 and 16-bit output Byte_temp = 0x16; if( HAL_I2C_Mem_Write(I2Cx, DataStructure->Magnetometer_addres, MPU9250_CNTL1, 1, &Byte_temp, 1, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Magnetometer_Config_FAIL; } HAL_Delay(100); return MPU9250_Magnetometer_Config_OK; } Fragment kodu z odczytaniem zmierzonych wartości: MPU9250_Error_code MPU9250_Read_Magnetometer(I2C_HandleTypeDef *I2Cx, struct MPU9250 *DataStructure) { uint8_t Bytes_temp[7] = { 0x00 }; if( HAL_I2C_Mem_Read(I2Cx, DataStructure->Magnetometer_addres, MPU9250_HXL | 0x80, 1, Bytes_temp, 7, 1000) != HAL_OK ) { //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); return MPU9250_Read_Magnetometer_FAIL; } DataStructure->Magnetometer_X = Bytes_temp[0] | Bytes_temp[1] << 8; DataStructure->Magnetometer_Y = Bytes_temp[2] | Bytes_temp[3] << 8; DataStructure->Magnetometer_Z = Bytes_temp[4] | Bytes_temp[5] << 8; return MPU9250_Read_Magnetometer_OK; }
  17. Hej, robiłem tą część kursu na płytce NUCLEO-F334R8 i mam problem z odczytem temperatury. W UserManual znalazłem takie wartości: AVG_slop = 0,0043 V25 = 1,43 https://www.st.com/resource/en/datasheet/stm32f334k4.pdf Rozdzial 6.3.23: Pomiar ADC zwraca mi wartosc w okolicach 1360, co daje wynik ok -77C... 0_o Czujnik zepsuty czy cos robie nie tak?
  18. Tradycyjna kostka do gry jest prosta w budowie, tania ale ma pewne wady. Potrafi potoczyć się w trudno dostępne miejsce. Kolejna wada jest hałas przez nią wytwarzany oraz fakt, że potrafi wpaść na planszę gry i przewrócić pionki. Wad tych pozbawiona jest kostka elektroniczna. W Internecie można znaleźć wiele konstrukcji, wszystkie jakie widziałem wyświetlają wynik losowania na diodach LED. Prezentowana konstrukcja posiada nowoczesny wyświetlacz OLED co pozwala na wyświetlanie różnorodnych grafik. Ponadto może zastąpić cztery kostki o praktycznie dowolnej liczbie liczbie ścian. Kostka została zbudowana na mikrokontrolerze STM32F103RBT8, który można znaleźć na płytkach STM32 NUCLEOSTM32-NUCLEO i innych dostępnych w Botlandzie . Można użyć taniej płytki "Blue pill". Prototyp został zamontowany na dedykowanej do tego PCB. Do wyświetlania grafiki służy kolorowy wyświetlacz OLED o rozdzielczości 96x64 np OLED 0,96". Grafika jest zapisana na karcie SD, dzięki czemu łatwo ją zmienić. Karta jest umieszczona w gnieździe podobnym do Gniazago karty SD z wyrzutnikiem tyle, że bez wyrzutnika. Na PCB przewidziano miejsce na pamięć DataFlash ale w prototypie nie jest ona używana. Jej przeznaczeniem była możliwość skopiowania grafiki z karty pamięci do DataFlash skąd mogą one bardzo szybko być wyświetlane na OLEDzie. Czas odczytu grafik z karty SD jest stosunkowo długi ale wystarczający do wyświetlania statycznych obrazów. Jeśli miałyby być wyświetlane grafiki (np. podczas losowania) to wykorzystanie DataFlasch będzie konieczne. Jak to działa? Naciśnięcie przycisku SET, wybudza mikrokontroler. Program sprawdza, czy reset spowodowany jest włączeniem zasilania czy wybudzeniem. Jeśli włączeniem zasilania wybiera kostkę numer 1 (na karcie SD można umieścić grafiki czterech kostek, każda do 250 ścian) ponadto inicjalizuje generator pseudolosu (ziarno). Jeżeli reset był wywołany wybudzeniem, ustawiana jest ostatnio używana kostka. W kolejnym kroku, przeszukiwane są pliki graficzne, na podstawie których, wiadomo ile ścian ma każda z czterech kostek. Po przeszukaniu plików pojawia się napis „Gotowy do gry” albo „SD Error” jeśli nie wykryto karty lub wymaganych plików graficznych. Przyciskami UP, DOWN, LEFT, RIGHT, można wybrać jedną z kostek, SET uruchamia losowanie. W czasie losowania, zależnie od tego czy znajduje się grafika reprezentująca wybraną kostkę (w prototypie „Orzeł czy reszka” i „Ruletka”) czy nie (w prototypie kostka 6 ścian, kostka 12 ścian), wyświetlana jest grafika lub migający ekran. Po zwolnieniu przycisku SET, po sekundzie, pojawia się wylosowana ściana kostki. Bezczynność przez dwie minuty spowoduje przejście kostki w stan uśpienia. Program został napisany w KEIL uV 5, zajmuje 31kB FLASH, 18kB RAM więc można go skompilować darmową wersją programu. Przy pisaniu softu, wspomagano się programem CubeMX. Program w dużej mierze korzysta z HAL tylko nieliczne fragmenty operują bezpośrednio na rejestrach mikrokontrolera. W pamięci mikrokontrolera stworzono bufor na dane wyświetlacza. Wszystkie operacje graficzne są wykonywane na nim, po czym wysyłana z wykorzystaniem DMA. Dzięki temu, transmisja zajmuje ok 12ms, w efekcie grafika na ekranie pojawia się niezauważalnie szybko. Zawartość karty SD stanową pliki graficzne w formacie BMP zapisane są w głównym katalogu. Nazwy plików kolejnych kostek zaczynają się od liter a, b, c, d. Cyfra za nazwą informuje o numerze ściany. Pierwsza kostka 6 ścian będzie wymagała plików: "a1.bmp" ... "a6.bmp". Ruletka to pliki:" b1.bmp" … "b37.bmp". Jeśli w czasie losowania ma pojawiać się grafika należy dodać plik z sufiksem 00, np.: "a00.bmp", "b00.bmp". Grafika w formacie BMP powinna mieć wymiary 94x64 piksele. Głębia kolorów 24-bit, bez kompresji. Grafika może mieć inne wymiary, jeśli będzie za duża, to zostanie obcięta, jeśli za mała, nie wypełni całego wyświetlacza. Do tworzenia /obróbki grafik w prototypie korzystano z Windows'owego Paint'a i programu IrfanView. W załączniku archiwum z programem i schemat. Kostka12.zip Protel Schematic.pdf
  19. Witam, Dopiero zaczynam przygodę z STM32. Mój problem polega na tym, że nie wiem za bardzo jak zapisać cały ciąg znaków do znaku końca lini w buforze mikrokontrolera. Wiem, że trzeba wykorzystać do tego tablicę, ale jak to zrobić to nie mam większego pojęcia. Jeśli ktoś może mi to wytłumaczyć będę wdzięczny.
  20. Cześć, to już któryś z kolei kurs na forbocie, który mi przypadł do gustu - przyjemny i wytłumaczony od deski do deski. Ja jednak używam płytki blue pill i mam problem z STM Studio - nie mogę nawiązać połączenia. Otrzymuję dwa komunikaty, jeden za drugim: "Error opening target connection" oraz "Failure opening connection with target". Zarówno ST-Link Utility jak i żaden debugger nie ma nawiązanego połączenia z płytką a jednak problem z połączeniem występuje. Używam ST-Link v2 i już w ST-Link utility miałem problem. O ile na początku wszystko działało bez problemu - połączenie z płytką i jej zaprogramowanie, tak już na drugi dzień wystąpił problem z połączeniem. Teraz po wybraniu Target -> Connect, muszę przez około 3 sekundy trzymać wciśnięty przycisk RESET na płytce i dopiero po jego zwolnieniu następuję połączenie, natomiast po zaprogramowaniu połączenie zostaje zerwane, mimo że program został poprawnie wgrany. Próbowałem powyższej metody w STM Studio, jednak wtedy, po zwolnieniu przycisku RESET, wyrzuca komunikat: "Acquisition stopped after 10 consecutive communication errors.". Dodam, że próbuję wgrać program odczytujący temperaturę z wbudowanego czujnika temperatury a konfiguracja w Cube odbyła się oczywiście pod mój mikrokontroler. Wszystkie narzędzia są zaktualizowane do najnowszej wersji, firmware w ST-Linku też. Ktoś się spotkał z podobnym problemem?
  21. Witam, Ostatnio zauważyłem problem podczas wgrywania programu dla mikrokontrolera STM32F429. Problem objawia się następująco: -Tworzę nowy projekt -> zapisuje, builduje, (nie ma błędów) -> wgrywam program poprzez Utility (wybierając plik z rozszerzeniem HEX) -> działa. - Biorę ten sam projekt i wprowadzam pewne modyfikacje (np. zmieniam częstotliwość w CUBE, wybieram inny pin itp, generalnie drobne zmiany) -> zapisuje, builduje (nie ma błędów) -> wgrywam, i niestety bez powodzenia. Załączam screena z Utility po nieudanej próbie wgrania kodu. Doszedłem do tego, że raczej wina leży po stronie Workbencha i niepoprawnie utworzonego pliku z rozszerzeniem HEX (plik ten jest praktycznie pusty, sprawdziałem go notatnikiem), ponieważ gdy chcę wgrać inny projekt wówczas wszystko działa poprawnie. Próbowałem odinstalować oprogramowanie i zainstalować od nowa. Nie pomogło. Czy ktoś spotkał się z czymś takim?
  22. Mam takie zapytanie bo uwaliłem stm i potrzebuje wymienić na nowy, które adresy pamięci są ważne żeby zrobić kopie 1:1? 0x0000 0000 - 0x0001 0000 i 0x0800 0000 - 0x0801 0000 czy coś jeszcze??
  23. Witam. Tworzę prostą aplikację pod Stm32CubeIDE z użycie kontrolera STM32F303 (z wbudowanym FPU). Trafiłem na dziwne problemy kiedy próbowałem użyć sprintf z włączonym wsparciem dla %f. Za każdym razem zamiast poprawnie sformatowanej liczby dostawałem bardzo długi ciąg cyfr. Znalazłem nawet na githubie jakąś inną implementację sprintf i to znowu często zamiast poprawnej wartości zwracało mi 0.00. W końcu okazało się, że problem jest z va_arg: void test(const char* format, ...) { va_list va; va_start(va, format); double arg1 = va_arg(va, double); char buf[102]; sprintf(buf, "a %.2f", arg1); va_end(va); } test("format", 0.1234); Zatrzymuje kod na linii z va_arg i widzę, że to zwraca głupoty. Obszedłem to przy pomocy takiego dziwnego rozwiązania: uint64_t doubleBinary = va_arg(va, uint32_t) | ((uint64_t)va_arg(va, uint32_t) << 32); double arg = *(double*)&doubleBinary; I tu dostaje poprawną wartość. Ale potem mam taki fragment (to z tego sprintf): static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) { {... tu jakiś kod...} } //i wywołanie: uint64_t doubleAsInt = va_arg(va, uint32_t) | ((uint64_t)va_arg(va, uint32_t) << 32); double doubleAsDouble = *(double*)&doubleAsInt; idx = _ftoa(out, buffer, idx, maxlen, doubleAsDouble, precision, width, flags); format++; No i na tym _ftoa znowu jest problem bo zamiast wejść do procedury to kod wpada mi do: Default_Handler: Infinite_Loop: b Infinite_Loop Próbowałem wyłączyć FPU i skompilować wszystko na software. va_arg nadal nie działa ale nie ma tego crasha przy _ftoa. Potem uruchomiłem ten sam program pod starym EmBitz (GCC w wersji 5) i tam wszystko wydaje się działać bezbłędnie (na tyle na ile udało mi się sprawdzić). Przy czym te projekty nie są identycznie (mój kod jest taki sam ale to co jest generowane przez środowisko już na pewno nie). Ma ktoś pomysł jak to debugować i o co może chodzić? Nie jestem w tym specjalnie zaawansowany i skończyły mi się już pomysły. W internecie znalazłem jakieś szczątkowe informacje, że double ma 8 bajtów i z tym jest jakiś problem (niestety bez konkretów więc nic mi to nie dało).
  24. Dzień dobry wszystkim. Po około miesiącu używania STM32L053R8 postanowiłem ułatwić sobie życie za pomocą STM32CubeMX i migrować z SW4STM32 na TrueSTUDIO. Niestety TrueSTUDIO nie chciało ze mną współpracować, a co gorsza projekty, które pierwotnie działały w SW4STM32 po całej tej operacji odmówiły posłuszeństwa. Magistrala USART zaczęła działać w niezrozumiały dla mnie sposób, tj aby terminal odczytał dane poprawnie musiał mieć ustawiony baud_rate_term ~= baud_rate_uC/2. np(uC 115200 - term 57600 lub 56000) Dwie rzeczy, które zmieniałem w międzyczasie to: a) aktualizacja ST Link v2 do V2.J34.M25 b) konfiguracja PLL w STM32CubeMX Załączam screeny z konfiguracji oraz fragmenty kodu. Jeżeli był już taki post to przepraszam , ale nawet nie wiedziałem jakimi słowami klucz go szukać, i dziękuję z góry za każdą pomoc. Inicjalizacja UARTu: void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspInit 0 */ /* USER CODE END USART2_MspInit 0 */ /* USART2 clock enable */ __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; GPIO_InitStruct.Alternate = GPIO_AF4_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE END USART2_MspInit 1 */ } } Transmisja: void uart_write_line(UART_HandleTypeDef *huart, char *str) { HAL_UART_Transmit(huart, str, strlen(str), 1000); HAL_UART_Transmit(huart, "\r\n", 2, 1000); }
  25. Witam, moze odrazu do rzeczy. Chcial bym podlaczyc termistor ktory bedzie zasilany napieciem 5V. Czytalem ze STM32 dzialaja na logice 3,3V. Wiec tu moje pytanie czy nie spale uC przez to ze dam napiecie bliskie 5V na ADC tego kontrolera. Mysle tez nad konwerterem logicznym lub prostym dzielnikiem napiecie by wrazie potrzeby zmniejszyc napiecie. Moze ktos ma inne pomysly, jakies rady co to ADC STM32? Z gory dzieki. Pozdrawiam
×
×
  • Utwórz nowe...