Skocz do zawartości

Rogal

Użytkownicy
  • Zawartość

    21
  • Rejestracja

  • Ostatnio

Reputacja

17 Dobra

O Rogal

  • Ranga
    2/10
  • Urodziny 27.07.1989

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Warszawa
  • Zainteresowania
    lotnictwo
  • Zawód
    pilot samolotu

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Cześć, Właśnie kończę mój pierwszy mały projekt i zastanawiam się czy ewentualnie kwalifikowałby się do rabatu. Nic wyszukanego - podlewaczka do roślin. Mikrokontroler atmega8a. Czujniki wilgotności gleby, napięcia zasilania i nasłonecznienia. W projekcie jest m.in. sterowanie pompą za pomocą PWM, timer taktowany kwarcem zegarkowym, usypianie mikrokontrolera i dość zawiła logika działania tego wszystkiego (na maszynie stanów). Mogę opublikować schemat z eagla (nie gwarantuje, że w 100% poprawny - dopiero się ucze) oraz kod.
  2. Hej, Wrzucam zadania domowe. W zadaniach 9.1 oraz 9.2 kolejność podłączenia diod do wyjść ekspandera może być trochę nieintuicyjna - są w kolejności 3, 0, 1, 2. We wszystkich zadaniach zdecydowałem się na dodatkowe buforowanie rejestrów OLAT i IODIR ekspandera w pamięci mikrokontrolera. Zapisy do tych buforów jak i bezpośrednio do mniej używanych rejestrów ekspandera zrealizowałem za pomocą przesunięć bitowych trochę tak jak w AVR. /*Zadanie domowe 9.1 Podłącz do ekspandera kilka diod świecących np.: 4 i napisz program, który pozwala na włączanie i wyłączanie diod poprzez wysyłanie odpowiednich komend sterujących przez UART (np. 1on, 1off).*/ /*Terminal New Line character has to be set to LF*/ #include "stm32f1xx.h" #include <string.h> #define RX_BUFFER_SIZE 10 //String size + 1 #define MCP_IODIR 0x00 #define MCP_IPOL 0x01 #define MCP_GPINTEN 0x02 #define MCP_DEFVAL 0x03 #define MCP_INTCON 0x04 #define MCP_IOCON 0x05 #define MCP_GPPU 0x06 #define MCP_INTF 0x07 #define MCP_INTCAP 0x08 #define MCP_GPIO 0x09 #define MCP_OLAT 0x0a #define MCP_GPIO_0 0 #define MCP_GPIO_1 1 #define MCP_GPIO_2 2 #define MCP_GPIO_3 3 #define MCP_GPIO_4 4 #define MCP_GPIO_5 5 #define MCP_GPIO_6 6 #define MCP_GPIO_7 7 SPI_HandleTypeDef spi; UART_HandleTypeDef uart; void send_string(char* s){ HAL_UART_Transmit(&uart, (uint8_t*)s, strlen(s), 1000); } void mcp_write_reg(uint8_t addr, uint8_t value){ uint8_t tx_buff[] = { 0x40, addr, value }; HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); HAL_SPI_Transmit(&spi, tx_buff, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); } int main(void){ SystemCoreClock = 8000000; HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); /*PA5 AS SCK + PA7 AS MOSI*/ GPIO_InitTypeDef inout; inout.Pin = GPIO_PIN_5 | GPIO_PIN_7; inout.Mode = GPIO_MODE_AF_PP; inout.Pull = GPIO_NOPULL; inout.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &inout); /*PA6 AS MISO*/ inout.Pin = GPIO_PIN_6; inout.Mode = GPIO_MODE_AF_INPUT; HAL_GPIO_Init(GPIOA, &inout); /*PC0 AS CS (SS)*/ inout.Pin = GPIO_PIN_0; inout.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(GPIOC, &inout); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); /*PIN PA2 AS TX (ALTERNATE)*/ inout.Mode = GPIO_MODE_AF_PP; inout.Pin = GPIO_PIN_2; inout.Pull = GPIO_NOPULL; inout.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &inout); /*PIN PA3 AS RX (ALTERNATE)*/ inout.Mode = GPIO_MODE_AF_INPUT; inout.Pin = GPIO_PIN_3; HAL_GPIO_Init(GPIOA, &inout); /*UART2 CONFIG*/ uart.Instance = USART2; uart.Init.BaudRate = 115200; uart.Init.WordLength = UART_WORDLENGTH_8B; uart.Init.Parity = UART_PARITY_NONE; uart.Init.StopBits = UART_STOPBITS_1; uart.Init.HwFlowCtl = UART_HWCONTROL_NONE; uart.Init.OverSampling = UART_OVERSAMPLING_16; uart.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&uart); /*SPI CONFIG*/ spi.Instance = SPI1; spi.Init.Mode = SPI_MODE_MASTER; spi.Init.NSS = SPI_NSS_SOFT; spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; spi.Init.Direction = SPI_DIRECTION_2LINES; spi.Init.CLKPhase = SPI_PHASE_1EDGE; spi.Init.CLKPolarity = SPI_POLARITY_LOW; spi.Init.DataSize = SPI_DATASIZE_8BIT; spi.Init.FirstBit = SPI_FIRSTBIT_MSB; spi.Init.TIMode = SPI_TIMODE_DISABLE; spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; spi.Init.CRCPolynomial = 7; HAL_SPI_Init(&spi); __HAL_SPI_ENABLE(&spi); /*VARIABLES*/ uint8_t EndOfTransmissionFlag = 0; char str[RX_BUFFER_SIZE] = ""; uint8_t i = 0; uint8_t mcp_olat_buff = 0; uint8_t mcp_iodir_buff = 255; memset(str, 0, strlen(str)); //Clearing string buffer mcp_iodir_buff &= ~(1<<MCP_GPIO_0) & ~(1<<MCP_GPIO_1) & ~(1<<MCP_GPIO_2) & ~(1<<MCP_GPIO_3); mcp_write_reg(MCP_IODIR, mcp_iodir_buff); while (1){ if(__HAL_UART_GET_FLAG(&uart, UART_FLAG_RXNE) == SET){ HAL_UART_Receive(&uart, (uint8_t*)str + i, 1, 1000); send_string(str + i); //Terminal echo if(str[i] == '\n'){ str[i] = 0; i = 0; EndOfTransmissionFlag = 1; } else{ i++; } } if (EndOfTransmissionFlag == 1) { if (strcmp(str, "on 1") == 0) { send_string("1 ON\n"); mcp_olat_buff |= 1<<MCP_GPIO_3; } if (strcmp(str, "off 1") == 0) { send_string("1 OFF\n"); mcp_olat_buff &= ~(1<<MCP_GPIO_3); } if (strcmp(str, "on 2") == 0) { send_string("2 ON\n"); mcp_olat_buff |= 1<<MCP_GPIO_0; } if (strcmp(str, "off 2") == 0) { send_string("2 OFF\n"); mcp_olat_buff &= ~(1<<MCP_GPIO_0); } if (strcmp(str, "on 3") == 0) { send_string("3 ON\n"); mcp_olat_buff |= 1<<MCP_GPIO_1; } if (strcmp(str, "off 3") == 0) { send_string("3 OFF\n"); mcp_olat_buff &= ~(1<<MCP_GPIO_1); } if (strcmp(str, "on 4") == 0) { send_string("4 ON\n"); mcp_olat_buff |= 1<<MCP_GPIO_2; } if (strcmp(str, "off 4") == 0) { send_string("4 OFF\n"); mcp_olat_buff &= ~(1<<MCP_GPIO_2); } mcp_write_reg(MCP_OLAT, mcp_olat_buff); EndOfTransmissionFlag = 0; memset(str, 0, strlen(str)); //Clearing buffer } if(str[10] != 0){ i = 0; memset(str, 0, strlen(str)); //Clearing buffer send_string("\n"); } } } /*Zadanie domowe 9.2 Wykorzystaj podłączenie z zadanie 9.1 i stwórz licznik Johnsona. Do układu podłącz dodatkowo potencjometr, którym będzie można regulować prędkość pracy licznika (w tym celu użyj ADC).*/ #include "stm32f1xx.h" #define MCP_IODIR 0x00 #define MCP_IPOL 0x01 #define MCP_GPINTEN 0x02 #define MCP_DEFVAL 0x03 #define MCP_INTCON 0x04 #define MCP_IOCON 0x05 #define MCP_GPPU 0x06 #define MCP_INTF 0x07 #define MCP_INTCAP 0x08 #define MCP_GPIO 0x09 #define MCP_OLAT 0x0a #define MCP_GPIO_0 0 #define MCP_GPIO_1 1 #define MCP_GPIO_2 2 #define MCP_GPIO_3 3 #define MCP_GPIO_4 4 #define MCP_GPIO_5 5 #define MCP_GPIO_6 6 #define MCP_GPIO_7 7 SPI_HandleTypeDef spi; ADC_HandleTypeDef adc; uint32_t read_adc(){ HAL_ADC_Start(&adc); HAL_ADC_PollForConversion(&adc, 1000); return HAL_ADC_GetValue(&adc); } void mcp_write_reg(uint8_t addr, uint8_t value){ uint8_t tx_buff[] = { 0x40, addr, value }; HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); HAL_SPI_Transmit(&spi, tx_buff, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); } int main(void){ SystemCoreClock = 8000000; HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_ADC1_CLK_ENABLE(); /*PA5 AS SCK + PA7 AS MOSI*/ GPIO_InitTypeDef inout; inout.Pin = GPIO_PIN_5 | GPIO_PIN_7; inout.Mode = GPIO_MODE_AF_PP; inout.Pull = GPIO_NOPULL; inout.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &inout); /*PA6 AS MISO*/ inout.Pin = GPIO_PIN_6; inout.Mode = GPIO_MODE_AF_INPUT; HAL_GPIO_Init(GPIOA, &inout); /*PC0 AS CS (SS)*/ inout.Pin = GPIO_PIN_0; inout.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(GPIOC, &inout); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); /*PA0 AS ANALOG INPUT*/ inout.Pin = GPIO_PIN_0; inout.Mode = GPIO_MODE_ANALOG; inout.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &inout); /*SPI CONFIG*/ spi.Instance = SPI1; spi.Init.Mode = SPI_MODE_MASTER; spi.Init.NSS = SPI_NSS_SOFT; spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; spi.Init.Direction = SPI_DIRECTION_2LINES; spi.Init.CLKPhase = SPI_PHASE_1EDGE; spi.Init.CLKPolarity = SPI_POLARITY_LOW; spi.Init.DataSize = SPI_DATASIZE_8BIT; spi.Init.FirstBit = SPI_FIRSTBIT_MSB; spi.Init.TIMode = SPI_TIMODE_DISABLE; spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; spi.Init.CRCPolynomial = 7; HAL_SPI_Init(&spi); __HAL_SPI_ENABLE(&spi); /*ADC CLOCK CONFIG*/ RCC_PeriphCLKInitTypeDef adc_clk; adc_clk.PeriphClockSelection = RCC_PERIPHCLK_ADC; adc_clk.AdcClockSelection = RCC_ADCPCLK2_DIV8; HAL_RCCEx_PeriphCLKConfig(&adc_clk); /*ADC CONFIG*/ adc.Instance = ADC1; adc.Init.ContinuousConvMode = DISABLE; adc.Init.ExternalTrigConv = ADC_SOFTWARE_START; adc.Init.DataAlign = ADC_DATAALIGN_RIGHT; adc.Init.ScanConvMode = ADC_SCAN_DISABLE; adc.Init.NbrOfConversion = 1; adc.Init.DiscontinuousConvMode = DISABLE; adc.Init.NbrOfDiscConversion = 1; HAL_ADC_Init(&adc); HAL_ADCEx_Calibration_Start(&adc); /*ADC MULTIPLEXER CONFIG*/ ADC_ChannelConfTypeDef adc_ch; adc_ch.Channel = ADC_CHANNEL_0; adc_ch.Rank = ADC_REGULAR_RANK_1; adc_ch.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(&adc, &adc_ch); /*VARIABLES*/ uint8_t mcp_olat_buff = 0; uint8_t mcp_iodir_buff = 255; uint8_t carry = 0; //carry flag uint32_t period = 0; mcp_iodir_buff &= ~(1<<MCP_GPIO_0) & ~(1<<MCP_GPIO_1) & ~(1<<MCP_GPIO_2) & ~(1<<MCP_GPIO_3); mcp_write_reg(MCP_IODIR, mcp_iodir_buff); while (1){ if (mcp_olat_buff & (1<<MCP_GPIO_2)){ carry = 1; } else { carry = 0; } if (mcp_olat_buff & (1<<MCP_GPIO_1)){ mcp_olat_buff |= (1<<MCP_GPIO_2); } else { mcp_olat_buff &= ~(1<<MCP_GPIO_2); } if (mcp_olat_buff & (1<<MCP_GPIO_0)){ mcp_olat_buff |= (1<<MCP_GPIO_1); } else { mcp_olat_buff &= ~(1<<MCP_GPIO_1); } if (mcp_olat_buff & (1<<MCP_GPIO_3)){ mcp_olat_buff |= (1<<MCP_GPIO_0); } else { mcp_olat_buff &= ~(1<<MCP_GPIO_0); } if (carry == 1){ mcp_olat_buff &= ~(1<<MCP_GPIO_3); } else { mcp_olat_buff |= (1<<MCP_GPIO_3); } mcp_write_reg(MCP_OLAT, mcp_olat_buff); period = read_adc() / 5; if (period < 30){ period = 30; } HAL_Delay(period); } } Zadanie 9.3 zrobiłem nieco inaczej niż MaciejZyskowski. Obyło się bez użycia przerwań a zliczanie zmienia kierunek od razu po zmianie stanu wejścia ekspandera. Przy okazji wyeliminowałem opóźnienia w tym zadaniu. Podobnie można było zrobić w 9.2. /*Zadanie domowe 9.3 Skonfiguruj jeden pin ekspandera jako wejście, a pozostałe jako wyjścia, do których podłączone będą diody świecące. Stan diod powinien wizualizować wyjście licznika binarnego, którego kierunek pracy określany ja za pomocą stanu panującego na jedynym wejściu ekspandera.*/ #include "stm32f1xx.h" #define MCP_IODIR 0x00 #define MCP_IPOL 0x01 #define MCP_GPINTEN 0x02 #define MCP_DEFVAL 0x03 #define MCP_INTCON 0x04 #define MCP_IOCON 0x05 #define MCP_GPPU 0x06 #define MCP_INTF 0x07 #define MCP_INTCAP 0x08 #define MCP_GPIO 0x09 #define MCP_OLAT 0x0a #define MCP_GPIO_0 0 #define MCP_GPIO_1 1 #define MCP_GPIO_2 2 #define MCP_GPIO_3 3 #define MCP_GPIO_4 4 #define MCP_GPIO_5 5 #define MCP_GPIO_6 6 #define MCP_GPIO_7 7 #define PERIOD 100 SPI_HandleTypeDef spi; void mcp_write_reg(uint8_t addr, uint8_t value){ uint8_t tx_buff[] = { 0x40, addr, value }; HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); HAL_SPI_Transmit(&spi, tx_buff, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); } uint8_t mcp_read_reg(uint8_t addr){ uint8_t rx_buff[3]; uint8_t tx_buff[] = { 0x41, addr, 0xff }; HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(&spi, tx_buff, rx_buff, 3, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); return rx_buff[2]; } int main(void){ SystemCoreClock = 8000000; HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_SPI1_CLK_ENABLE(); /*PA5 AS SCK + PA7 AS MOSI*/ GPIO_InitTypeDef inout; inout.Pin = GPIO_PIN_5 | GPIO_PIN_7; inout.Mode = GPIO_MODE_AF_PP; inout.Pull = GPIO_NOPULL; inout.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &inout); /*PA6 AS MISO*/ inout.Pin = GPIO_PIN_6; inout.Mode = GPIO_MODE_AF_INPUT; HAL_GPIO_Init(GPIOA, &inout); /*PC0 AS CS (SS)*/ inout.Pin = GPIO_PIN_0; inout.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init(GPIOC, &inout); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET); /*SPI CONFIG*/ spi.Instance = SPI1; spi.Init.Mode = SPI_MODE_MASTER; spi.Init.NSS = SPI_NSS_SOFT; spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; spi.Init.Direction = SPI_DIRECTION_2LINES; spi.Init.CLKPhase = SPI_PHASE_1EDGE; spi.Init.CLKPolarity = SPI_POLARITY_LOW; spi.Init.DataSize = SPI_DATASIZE_8BIT; spi.Init.FirstBit = SPI_FIRSTBIT_MSB; spi.Init.TIMode = SPI_TIMODE_DISABLE; spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; spi.Init.CRCPolynomial = 7; HAL_SPI_Init(&spi); __HAL_SPI_ENABLE(&spi); /*VARIABLES*/ uint8_t mcp_olat_buff = 0; uint8_t mcp_iodir_buff = 255; uint32_t last_incremented = 0; mcp_iodir_buff &= ~(1<<MCP_GPIO_0) & ~(1<<MCP_GPIO_1) & ~(1<<MCP_GPIO_2) & ~(1<<MCP_GPIO_3) & ~(1<<MCP_GPIO_4) & ~(1<<MCP_GPIO_5) & ~(1<<MCP_GPIO_6); mcp_write_reg(MCP_IODIR, mcp_iodir_buff); mcp_write_reg(MCP_GPPU, (1<<MCP_GPIO_7)); while (1){ if(last_incremented + PERIOD <= HAL_GetTick()){ last_incremented = HAL_GetTick(); if((mcp_read_reg(MCP_GPIO) & (1<<MCP_GPIO_7)) == 0){ if(mcp_olat_buff == 0){ continue; } else { mcp_olat_buff -= 1; } } else { if(mcp_olat_buff == 127){ continue; } else{ mcp_olat_buff += 1; } } } mcp_write_reg(MCP_OLAT, mcp_olat_buff); } }
  3. Zastanawiam się co w sytuacji gdy dajmy na to kupiłem na allegro niedziałający monitor. Zdjąłem obudowę, zrobiłem recap używając do tego cyny z ołowiem i nagle monitor zaczął działać. Mogę go komuś podarować albo odsprzedać?
  4. Pierwsze co mi przyszło do głowy to różnica napięć, STM32 jest na 3,3V a UNO na 5V. Może konwerter poziomów logicznych by pomógł? Dodatkowo można by się zastanowić z którego UARTa korzysta ST zaprogramowany w ten sposób. Nigdy nie programowałem tych mikrokontrolerów tak jak Arduino. Programując go w ten sposób, możesz odczytać dane na PC podłączonym przez USB z płytką? Spróbuj podłączyć do PA2 zamiast PA9.
  5. Póki co nie wymyśliłem nic innego niż odbieranie bajt po bajcie. Zadanie 5.2: #include <string.h> #include "stm32f1xx.h" #define RX_BUFFER_SIZE 4 //String size + 1 UART_HandleTypeDef uart; void send_string(char* s){ HAL_UART_Transmit(&uart, (uint8_t*)s, strlen(s), 1000); } int main(void){ SystemCoreClock = 8000000; HAL_Init(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART2_CLK_ENABLE(); GPIO_InitTypeDef inout; /*PIN PA2 AS TX (ALTERNATE)*/ inout.Mode = GPIO_MODE_AF_PP; inout.Pin = GPIO_PIN_2; inout.Pull = GPIO_NOPULL; inout.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &inout); /*PIN PA3 AS RX (ALTERNATE)*/ inout.Mode = GPIO_MODE_AF_INPUT; inout.Pin = GPIO_PIN_3; HAL_GPIO_Init(GPIOA, &inout); /*PA6 AS RED - 1*/ inout.Mode = GPIO_MODE_OUTPUT_PP; inout.Pin = GPIO_PIN_6; HAL_GPIO_Init(GPIOA, &inout); /*PA7 AS YELLOW - 2*/ inout.Mode = GPIO_MODE_OUTPUT_PP; inout.Pin = GPIO_PIN_7; HAL_GPIO_Init(GPIOA, &inout); /*PA9 AS GREEN - 3*/ inout.Mode = GPIO_MODE_OUTPUT_PP; inout.Pin = GPIO_PIN_9; HAL_GPIO_Init(GPIOA, &inout); /*UART2 CONFIG*/ uart.Instance = USART2; uart.Init.BaudRate = 115200; uart.Init.WordLength = UART_WORDLENGTH_8B; uart.Init.Parity = UART_PARITY_NONE; uart.Init.StopBits = UART_STOPBITS_1; uart.Init.HwFlowCtl = UART_HWCONTROL_NONE; uart.Init.OverSampling = UART_OVERSAMPLING_16; uart.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&uart); /*VARIABLES*/ uint8_t EndOfTransmissionFlag = 0; char str[RX_BUFFER_SIZE]; uint8_t *ptr = (uint8_t *)str; uint8_t i = 0; memset(str, 0, strlen(str)); //Clearing buffer while(1){ if(__HAL_UART_GET_FLAG(&uart, UART_FLAG_RXNE) == SET){ uint8_t value; HAL_UART_Receive(&uart, &value, 1, 1000); *(ptr + i) = value; send_string(&str[i]); i++; if(i == RX_BUFFER_SIZE - 1){ i = 0; EndOfTransmissionFlag = 1; send_string("\r\n"); } } if (EndOfTransmissionFlag == 1) { if (strcmp(str, "on1") == 0) { send_string("RED ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); } if (strcmp(str, "of1") == 0) { send_string("RED OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); } if (strcmp(str, "on2") == 0) { send_string("YELLOW ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } if (strcmp(str, "of2") == 0) { send_string("YELLOW OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); } if (strcmp(str, "on3") == 0) { send_string("GREEN ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); } if (strcmp(str, "of3") == 0) { send_string("GREEN OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); } EndOfTransmissionFlag = 0; memset(str, 0, strlen(str)); //Clearing buffer } } } Ok, znalazłem trochę czasu i udało mi się zrobić odbieranie wielu bajtów na raz, zmiany w kodzie: (...) /*VARIABLES*/ char str[RX_BUFFER_SIZE] = ""; while (1) { memset(str, 0, strlen(str)); //Clearing buffer if (__HAL_UART_GET_FLAG(&uart, UART_FLAG_RXNE) == SET) { HAL_UART_Receive(&uart, (uint8_t *) str, 3, 1000); send_string(str); send_string("\r\n"); } if (strcmp(str, "on1") == 0) { send_string("RED ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); } if (strcmp(str, "of1") == 0) { send_string("RED OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET); } if (strcmp(str, "on2") == 0) { send_string("YELLOW ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); } if (strcmp(str, "of2") == 0) { send_string("YELLOW OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET); } if (strcmp(str, "on3") == 0) { send_string("GREEN ON\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); } if (strcmp(str, "of3") == 0) { send_string("GREEN OFF\r\n"); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); } } (...)
  6. Wchodzi ale też z niej wychodzi - otrzymałeś 2 komunikaty o otwartym oknie bez indykacji, że program wszedł do pętli pomiędzy nimi. To powinno wyglądać tak, że masz 1 komunikat o otwartym oknie a później tylko, że program jest w pętli. To co wyżej napisał Belferek ma dla mnie dużo sensu warto by było to sprawdzić przed dalszą diagnozą. Na późniejszym etapie nauki można by było się pokusić o filtr RC na tym przycisku. https://forbot.pl/blog/czym-jest-filtr-rc-jak-dziala-i-co-warto-o-nim-wiedziec-id40448
  7. Drgania styków? Jak na moje to program nie wpada w tą pętle while, można to sprawdzić dodając tam jakiś println z napisem np. "jestem w pętli while" i zobaczyć czy się wyświetli i jak tak to w jakich sytuacjach.
  8. Tak się zastanawiam. Czy w przypadku każdego stanu konieczne jest ustawianie go na nowo jeżeli nie zostały spełnione warunku do przejścia do kolejnego stanu (instrukcja w blokach else)? when S0 => if(not DPSwitch(0)) = '1' then Stan <= S1; end if; Przetestowałem coś takiego i działa ale czy są jakieś inne względy z powodu, których w każdym stanie powinien znaleźć się blok else z określeniem aktualnego stanu ponownie na ten sam stan w którym już i tak się znajduje?
  9. Na pewno jest tak jak mówisz ale dopiero muszę do tego dojść. Arduino jeszcze dałbym rade sobie skonfigurować do swoich potrzeb programując bity w atmedze ale na ESP to w sumie nie wiem jak to zrobić. Pisząc wczorajszy komentarz chodziło mi bardziej o zestaw funkcji dostarczone przez arduino niż o samą płytkę. A ja bym chociaż jeden program w kursie chciał zobaczyć na VSC.
  10. Jakiś czas programowałem AVRy w atmel studio i mi w arduino brakuje delikatnie niższego poziomu. Nawet nie chodzi mi o jakieś wstawki w ASM tylko bardziej właśnie o dokładną konfiguracje timerow, adc, uart etc, także podział projektu na pliki. Wiem, że generalnie kompilator zrobi robotę i pewnie w 99% bede mial to czego potrzebuje no ale taki przywilej hobbysty, że mogę się rozdwodzic nad prescalerem adc i sleep mode żeby osiągnąć lepsze rezultaty a nie tylko wystarczające. Oczywiście na obecnym etapie w modulach ESP to ciesze się, że w ogóle wiem jak wgrać program :)
  11. Ano tak właśnie jest. W trakcie ćwiczenia pisałem swój własny ucf na podstawie dokumentacji i wszystko mi działało jak powinno ale porównując później pliki z tym z kursu faktycznie zauważyłem, że są piny na odwrót. Wszystko jest zgodne z logiką tego co napisałeś. Najpierw bit zerowy(najmłodszy bit) jest ustawiany na 6 bicie a później to co jest na 6 bicie jest ustawiane na zerowym i tak w kółko. Przypuszczam, że chodziło Ci o inny efekt i wtedy bity powinieneś łączyć tak: 0 & 7 & 6 & 5 & 4 & 3 & 2 & 1 o ile rejestr ma się przesuwać w prawo albo 6 & 5 & 4 & 3 & 2 & 1 & 0 & 7 jeżeli w lewo. Oczywiście można to zrobić krócej - tak jak jest napisane w kursie ale może rozbicie tego na pojedyncze bity faktycznie jest lepsze pod względem dydaktycznym.
  12. DP8 na płytce jest opisany jako 1 (P70) na schemacie ale animacje w kursie są poprawne. Jak ktoś chce mieć na innych przełącznikach to trzeba zmienić w ucf DP[0] na P58 i DP[1] na P59. Przetestowałem u mnie i działa. Błąd opisu na płytce tudzież schemacie - tam gdzie na płytce jest 8 to powinno być 1, tam gdzie 7 to 2 etc.
  13. Cześć, Sorry, że odpowiadam tak późno ale czytam forum w miarę własnych postępów. Zacznijmy od pojemności kondensatorów. Kondensator o pojemności 1uF jest bardziej pojemny od 10 nF. 1 uF to 10^-6F a 10nF to 10^-8F. "u" to mikro (10^-6) a "n" to nano (10^-9). Drugą sprawą jest kwestia rezystora. Chodzi o generowanie sygnału o bardzo konkretnej częstotliwości tak aby sygnał podstawowy podawany na buzzer zmieniał się w słyszalnej dla ludzi częstotliwości. Wystarczy to podstawić do wzoru z poprzedniej lekcji. f = 1 / (2,2 * C * R) = 1 / (2,2 * 1uF * 100kR) =~4,5 Hz tj. zmiana tonu buzzera następuje prawie 5 razy na sekundę. Pytanie do projektanta układu czy dobierał rezystor do kondensatora czy kondensator do rezystora ponieważ możemy dowolnie zmieniać (w zakresie dostępnych części) obydwie te wartości. W sumie ciekawi mnie czy większy kondensator ma tu wpływ na np. lepszą stabilność działania układu. Duży rezystor ma dodatkową zaletę ograniczającą pobór prądu układu... pytanie jak nisko można zejść z pojemnością kondensatora (i jak wysoko z rezystancją opornika) aby to wszystko dalej działało. Twoja modyfikacja wprowadziła zmiany tonu buzzera ponad 4500 razy na sekundę - to dokładnie taka sama częstotliwość co sygnału podstawowego. Nie wiem jak dokładnie układ powinien zachować się w tej sytuacji ale tak częste zmiany tonu na pewno nie są do wychwycenia przez człowieka.
  14. Jak podłączasz koszyk do płytki stykowej? Jeżeli za pomocą przewodów koszyka to wkładając jedną baterie do koszyka na dwie nie zamykasz obwodu (jest przerwa bo baterie w koszyku są połączone szeregowo) dlatego w tej konfiguracji nie da się jej sprawdzić. Musisz albo wsadzić tam dwie baterie albo poszukać koszyka na jedną albo przyłożyć przewody bezpośrednio do zacisków tej konkretnej baterii. Rezystor 10 kR wydaje się trochę za duży bo z prawa Ohma: U/R = I czyli ~1,5 / 10 000 = 0,00015 A = 0,15 mA. To za mały prąd aby zaobserwować spadek napięcia pod obciążeniem. Najmniejszy rezystor jaki miałem pod ręką to 100 R i w jego przypadku prąd płynący przez niego powinien wynieść ok 15 mA - nie dużo ale dało się odróżnić baterie rozładowaną od dobrej. Dobra nie zanotowała żadnego spadku a rozładowanej napięcie spadło o ok. 0,1 V. Taka bateria powinna móc dać ponad 15 mA także pewnie warto zastosować mniejszy rezystor i wtedy wyniki będą bardziej spektakularne ale to lepiej żeby ktoś inny się wypowiedział. Miernik możesz przyłożyć np. do zacisków baterii albo do nóżek rezystora.
×
×
  • Utwórz nowe...