Skocz do zawartości

dejmieno

Użytkownicy
  • Zawartość

    75
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    2

Wszystko napisane przez dejmieno

  1. Witam, Usiluje polaczyc sie z ekspanderem pinow IO MCP23S08-E/P poprzez SPI. Czy myslicie ze kod jest dobry? Jesli tak tzn. ze problem jest gdzies w polaczeniu ekspandera. Jak widac ponizej probuje zapalic diode led pod pinem GP0 ekspandera. #include <avr/io.h> #include <util/delay.h> void init_spi(void); void transfer_data(uint8_t data); int main(void) { init_spi(); transfer_data(0x40); transfer_data(0x00); transfer_data(~0x01); transfer_data(0x40); transfer_data(0x0A); transfer_data(0x01); while (1) { } } void init_spi(void) { DDRB = (1 << 3) | (1 << 5); SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); } void transfer_data(uint8_t data) { SPDR = data; while(!(SPSR & (1 << SPIF) )); }
  2. Na codzien programuje w jezykach wysokiego poziomu Java & Kotlin, wiec pewne elementy z C ktore normalnie zalatwia Garbage Collector musze ogarnac. Ale w sumie mozna bardzo wiele sie nauczyc. Ok, wykorzystalem funkcje free, tylko teraz pytanie czy powinienem przekazac tablice czy & referencje do tablicy? Czy tablica domyslnie nie jest przekazywana jako referencja? Rozumiem ze po wywolaniu free to normalne ze we wskazniku wskazniku sa jakies dane poniewaz tylko zwolnilem pamiec a wskaznik nadal wskazuje na jakis blok pamieci tylko ze pusty? Dobrze rozumiem?
  3. Ta funkcja przyjmuje tablice ( w praktyce jest to tablica buffor ) i tworzy podtablice o danym rozmiarze. Tylko teraz nie wiem czy taka praktyka nie spowoduje wycieku pamieci? Teraz sobie mysle ze jednak NULL jest nie wystarczajacy bo przeciez tylko nullujemy wskaznik ale zalokowany blok pamieci pozostaje prawda? getSubArray jest wykonywany w petli i zastanawiam sie czy przy ktoryms cyklu nie wylecie OutOfMemory. Zastanawiam sie czy przed kazdym wywolaniem getSubArray nie powinienem wywolac free(&subarray)?
  4. Witam, Chcialem sie was zapytac, czy ta funkcja jest poprawna? Czy takie rozwiazanie nie bedzie powodowac wyciekow pamieci? Czy rozmiar tablicy jest dobrze alokowany? char * subarray; char buffor[30]; uint8_t bufforElementsNumber = 0; char * getSubArray(int size, char array[]) { subarray = NULL; subarray = malloc(sizeof(char) * size); for (int i = 0; i < size; i++) { subarray[i] = array[i]; } return subarray; }
  5. "Okazuje się, że timer TIM4 udostępnia wyjścia PWM na pinach PB6, PB7, PB8 oraz PB8," Wkradł się chochlik ma być "PB8 oraz PB9" .
  6. Przerwanie zapinasz na event CHANGE co oznacza że funkcja f_przerw wywoła Ci się dwa razy, w momencie wciśnięcia przycisku i w momencie puszczenia przycisku. Spróbuj zmienić typ eventu na FALLING.
  7. Ok, doczytałem rozdział Clock Generation i okazało się, że korzystałem ze wzoru dla Asynchronous Normal mode, a w trybie SPI należy korzystać ze wzoru Synchronous Master Mode. Dzięki za pomoc .
  8. Ehhh ale gafa... Dzięki teraz działa. Nie wiem jak mogłem to przeoczyć. Tak, przy okazji jak na postawie wartości w rejestrze UBRR0 obliczyć długość trwania bitu? Czytam książkę "Język C dla mikrokontrolerów AVR" i tam autor podaje przykład na sterowanie diodami WS2812 poprzez UART. UBRR0=49; //Dla 16 MHz daje to czas trwania bitu równy 6,25 us, a bajtu 50 us Ale skąd taka wartość? Jak on to obliczył? Chciał uzyskać baud rate na poziomie 160000, alewedług kalkulatorów na internecie żeby uzyskać taki baud rate należy ustawić rejestr UBBR0 na 5.
  9. Poprawiłem post jakieś 5 minut temu . Problem z wykrywaniem został rozwiązany. Tak jak pisałem wyżej, dane nie pojawiają się na konsoli. Podczas wpisywania wartości do konsoli na konwerterze świeci się lampka TRANSMIT. Niestety lampka RECEIVE się nie świeci.
  10. Cześć, Mam problem z wysłaniem danych do PC poprzez moduł USART. Korzystam z konvertera USB - TTL. Podłączenie: GND - do masy RXD - do pinu PD1 mikrokontrolera (TXD) F_CPU=16000000 Korzystam z programu TerraTerm i na konsoli nie pojawiają się żadne dane. Gdy wpisuję coś do konsoli to miga dioda TRANSMIT na konwerterze. Niesetety dane z kontrolera nie są wysyłane. Czy ktoś wie gdzie może być problem? Z góry dziękuję za pomoc. Kod poniżej: #include <avr/io.h> #include <util/delay.h> void uart_9600() { #define BAUD 9600 #include <util/setbaud.h> UBRR0L = UBRRL_VALUE; UBRR0H = UBRRH_VALUE; #if USE_2X UCSR0A |= 1 << U2X0; #else UCSR0A &= ~(1 << U2X0); #endif } void usart_init() { uart_9600(); UCSR0C |= UCSZ00 | UCSZ01; UCSR0B |= TXEN0; } void usart_send(uint8_t data) { while(!(UCSR0A & (1 << UDRE0))); UDR0 = data; } int main(void) { usart_init(); while (1) { usart_send(123); } }
  11. Cześć dzami97. Rozczytałem dokumentacje i okazuje się że HAL domyślnie zaraz po resecie ustawia taktowanie szyn AHB i APB z wewnętrznego oscylatora HSI którego częstotliwość wynosi 8MHZ. Żeby wycisnąć 64MHZ należy skonfigurować prescaler HSI na 2 i mnożnik pętli PLL na 16 dzięki czemu uzyska się częstotliwość 64MHZ. Poniżej wklejam kod konfiguracji: Ostrzegam, że w STM32F1 jestem początkujący i sama konfiguracja może nie być doskonała, ale ogólnie wszystko działa . RCC_OscInitTypeDef osc; osc.OscillatorType = RCC_OSCILLATORTYPE_HSI; osc.HSEState = RCC_HSE_OFF; osc.HSIState = RCC_HSI_ON; osc.HSICalibrationValue = 16; osc.PLL.PLLState = RCC_PLLSOURCE_HSI_DIV2; osc.PLL.PLLMUL = RCC_PLL_MUL16; HAL_RCC_OscConfig(&osc); RCC_ClkInitTypeDef clk; clk.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; clk.AHBCLKDivider = RCC_SYSCLK_DIV1; clk.APB1CLKDivider = RCC_HCLK_DIV2; clk.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_2); SystemCoreClockUpdate(); HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  12. Witam, Usiłuję odpalić pasek programowalnych diod led, używając kontroller STM32F1. W programie wykorzystuję PWM i DMA do wysyłania bitów do kontrolera taśmy. Małymi kroczkami idę do przodu ciągle rozwiązując jakiś problem. Mój aktualny efekt pracy można zobaczyć na obrazku w załączniku. Jak widać wszystkie ledy świecą tak jak chciałem. Tylko niestety kolory się nie zgadzają. Według danych które wysyłam wszystkie powinny być zielone. Tylko pierwsza dioda świeci jak należy. Bardzo proszę o pomoc w dostrojeniu timera. Naprowadzenie gdzie może być problem. Poniżej kod programu. Moduł timera: #include "timers/tim4.h" #include "stm32f10x.h" void Init_TIM4() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); GPIO_InitTypeDef gpio; GPIO_StructInit(&gpio); gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Pin = GPIO_Pin_8; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio); TIM_TimeBaseInitTypeDef tim; TIM_TimeBaseStructInit(&tim); tim.TIM_CounterMode = TIM_CounterMode_Up; tim.TIM_Period = 64 - 1; TIM_TimeBaseInit(TIM4, &tim); TIM_OCInitTypeDef channel; TIM_OCStructInit(&channel); channel.TIM_OCMode = TIM_OCMode_PWM1; channel.TIM_OutputState = TIM_OutputState_Enable; channel.TIM_Pulse = 0; channel.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM4, &channel); } DMA i reszta programu: #include "stm32f10x.h" #include "timers/tim4.h" #define BUFFER_SIZE 24 volatile uint16_t src_buffer[BUFFER_SIZE] = {52, 52, 52, 52, 52, 52, 52, 52, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22}; void send_data() { DMA_SetCurrDataCounter(DMA1_Channel1, BUFFER_SIZE); DMA_Cmd(DMA1_Channel1, ENABLE); TIM_Cmd(TIM4, ENABLE); while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); TIM_Cmd(TIM4, DISABLE); DMA_Cmd(DMA1_Channel1, DISABLE); DMA_ClearFlag(DMA1_FLAG_TC1); } int main(void) { Init_TIM4(); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_InitTypeDef dma; DMA_StructInit(&dma); dma.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR3; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryBaseAddr = (uint32_t)src_buffer; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_BufferSize = BUFFER_SIZE; dma.DMA_M2M = DMA_M2M_Disable; dma.DMA_DIR = DMA_DIR_PeripheralDST; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_Init(DMA1_Channel1, &dma); TIM_DMACmd(TIM4, TIM_DMA_CC1, ENABLE); for (int i = 0; i < 8; i++) { send_data(); } while (1) { } }
  13. Aha, czyli wnioskuję, że najlepiej będzie uczyć się HAL i CMSIS. LL można sobie chyba darować.
  14. Mam pytanie co do konfiguracji SystemCoreClock. Dlaczego ustawiamy SystemCoreClock na 8Mhz a w kursie z STD Periph ustawialiśmy taktowanie na 64Mhz? Czyżby HAL ustawiał domyślne taktowanie zegara? -- edit Ok, rozczytałem się co nieco na ten temat w dokumentacji i dowiedziałem się że procesor może posiadać taktowania z kilku źródeł np. HSI czyli taktowanie z wewnętrznego zegara 8Mhz, lub może być taktowany z wewnętrznego źródła z pętlą PLL. Czyli jeśli dobrze rozumiem to w STL domyślnie konfiguruje multiplication factor - 8 dla wewnętrznego zegara i dzięki temu otrzymujemy taktowanie 64Mhz. Pytanie dlaczego HAL tego nie robi? Czy dobrze kombinuję?
  15. No tak faktycznie jak podejrzałem kod przykładowej procedury z LL to w środku znajduje się tylko operacja na jednym rejestrze. W sumie dobrze to wygląda. Rozumiem, że można miksować HAL i LL?
  16. Zapoznałem się z CubeMX, ale generowany kod jest paskudny (zresztą jeszcze nie widziałem narzędzia które generowałoby ładny kod). Zresztą, przecież sam HAL bardzo skraca kod i jakoś nie widzę potrzeby korzystania z CubeMX. Nie wiem o co wszystkim chodzi z SPL... co jest z tą biblioteką nie tak? O co chodzi z tym LL? Rozumiem, że jest to biblioteka trochę bardziej niskopoziomowa niż HAL? Ściągnąłem sobie example, ale na pierwszy rzut oka nie wygląda to jak biblioteka niskopoziomowa. Warto się tego uczyć, korzysta się z tego w ogóle?
  17. A ciekawi mnie jeszcze jak sprawa wygląda w kontekście programowania zawodowego mikrokontrolerów. Czy stawia się bardziej na wydajność i pisanie na rejestrach? Czy podobnie jak w branży języków wysokopoziomowych stawia się na szybkość developmentu, czystość kodu i co za tym idzie korzysta się z bibliotek jak HAL, generatorów kodu CubeMX?
  18. @GAndaLF dzięki wielkie za rade . Postanowiłem, że będę się uczył StdPeriph ponieważ jest bliżej sprzętu i powoli będę migrować na rejestry. Na początek sterowanie GPIO i małymi kroczkami powoli do przodu . W ramach lekcji z ADC już część sterowania GPIO zrobiłem na rejestrach, ale kod wygląda dość brzydko . Masz jakieś rady co do dobrych praktyk żeby kod wyglądał ładnie i czytelnie przy rejestrach? Mój aktualny kod wygląda tak: #include "stm32f10x.h" #include "usart/usart.h" #include "adc/adc.h" #include <stdio.h> #define LED_1 GPIO_ODR_ODR8 #define LED_2 GPIO_ODR_ODR6 void LED1_GPIOC_PIN8_OUT_PP_2MHZ() { GPIOC->CRH &= ~( GPIO_CRH_CNF8_1 | GPIO_CRH_CNF8_0 | GPIO_CRH_MODE8_0); GPIOC->CRH |= GPIO_CRH_MODE8_1; } void LED2_GPIOC_PIN6_OUT_PP_2MHZ() { GPIOC->CRL &= ~( GPIO_CRL_CNF6_1 | GPIO_CRL_CNF6_0 | GPIO_CRL_MODE6_0); GPIOC->CRL |= GPIO_CRL_MODE6_1; } int main(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); USART2_Init(); ADC_InitModule(); LED1_GPIOC_PIN8_OUT_PP_2MHZ(); LED2_GPIOC_PIN6_OUT_PP_2MHZ(); while (1) { uint16_t conv1 = ADC_GetValue(0); uint16_t conv2 = ADC_GetValue(1); if (conv1 > conv2) { GPIOC->ODR = 0; GPIOC->ODR |= LED_1; } else { GPIOC->ODR = 0; GPIOC->ODR |= LED_2; } } } PS. super blog.
  19. Witam, Ktoś może wie dlaczego strcmp nie działa? Czy jest jakaś możliwość że Tera Term wysyła mi jakieś dziwne rzeczy i dlatego compare nie działa? int bufferSize = 0; char commandBuffer[3]; while (1) { if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE)) { commandBuffer[bufferSize] = USART_ReceiveData(USART2); bufferSize++; } if (bufferSize >= 3) { if (strcmp(commandBuffer, "L1T") == 0) GPIO_SetBits(GPIOB, LED_1); else if (strcmp(commandBuffer, "L1O") == 0) GPIO_ResetBits(GPIOB, LED_2); bufferSize = 0; } }
  20. A możecie mi podać jakiś sprawdzony sposób jak skutecznie uczyć się STMa? Podczas nauki AVR człowiek uczy się korzystać z rejestrów więc przy okazji uczy się architektury i jak działa ta "hulajnoga". A w przypadku STM32, niby coś się umie zakodzić za pomocą HAL jednak gorzej ze znajomością architektury i jak działa STM32. Macie jakiś sprawdzony sposób na wejście w świat STM32 i żeby przy okazji poznać trochę wnętrze tych procków?
  21. Czyli rozumiem, że nawet jeśli ogarniacie mocniejsze układy STM32, Rassbery Pi to nadal znajdujecie zastosowanie dla 8 bitowców?
  22. Cześć, Od kilku tygodni uczę się programować mikroprocesory STM32F1 a w przyszłości zamierzam zabrać się dodatkowo za Rassbery Pi. Chciałem zapytać się was czy warto w takiej sytuacji uczyć się programować 8 bitowce? Jak to wygląda u was? Czy nadal korzystacie z 8 bitowców? Dodam jeszcze, że chcę się uczyć nie tylko pod kątem hobbystycznym, ale również zawodowym. Może kiedyś chciałbym zmienić branże z Javy na mikrokontrolery.
  23. Dzięki za pomoc. Ostatecznie zrobiłem filtr RC i wszystko śmiga.
  24. Aha, potraktować to jak drgania styków w przyciskach. Rozumiem, że proste rozwiązanie programowe, żeby odczekać kilka ms aż zakłócenia ustaną odpada, ponieważ _delay_ms nie ma wpływu na przerwania? Czyli pozostaje filtr RC.
  25. Witam, Posiadam taki cyfrowy czujnik dźwięku https://botland.com.pl/mikrofony-i-detektory-dzwieku/6638-czujnik-dzwieku-cyfrowy-5v.html. Chciałem za jego pomocą zrobić światełka sterowane klaśnięciami jednak na początek chciałem wypróbować działanie czujnika. Oto mój kod: Ogólnie czujnik działa jednak czasami objawia się niechciane zachowanie w stylu po klaśnięciu w dłonie dioda tylko mignie, włączy się i wyłączy, lub na odwrót. Podejrzewam, że mikrokontroler wykrywa kilkukrotnie zbocze narastające i przełącza led. Czy jest jakiś sposób, aby to jakoś odfiltrować, czy muszę się z tym pogodzić? int main(void) { DDRB = 0xFF; DDRD = 0x00; MCUCR |= (1 << ISC01 | ISC00); GICR |= (1 << INT0); sei(); while (1) { } } ISR (INT0_vect) { // zmiana stanu led PORTB ^= 0x01; }
×
×
  • Utwórz nowe...