STM32F103 UART na rejestrach

Wszystko o co chcesz zapytać na temat mikrokontrolerów ARM firmy STMicroelectronics: problemy z pisaniem programu, problemy sprzętowe, niejasności w DS czy AN itp.
StaryAnoda

STM32F103 UART na rejestrach

Postautor: StaryAnoda » piątek 11 lis 2016, 20:57

Cześć

Mam kłopot wykonuję ćwiczenia według ksiażki dostępnej na portalu Elektroda. Chodzi o cykl STM32 bez bibliotek SPL. Próbuję uruchomić Uart mam problem z wysyłaniem danych. Dane są wysyłane ale terminal wyświetla krzaki. Dodam, że analizator stanów logicznych w trybie autoband wykrywa poprawnie wysyłane dane. Mikrokontroler jest taktowany czestotliwością 8 Mhz. Pin PA9 to TX

W pliku system_stm32f10x.c

Kod: Zaznacz cały

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
#else
#define SYSCLK_FREQ_HSE    HSE_VALUE
/* #define SYSCLK_FREQ_24MHz  24000000 */
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
/* #define SYSCLK_FREQ_72MHz  72000000 */
#endif


Nataomiast kod pliku main.c :

Kod: Zaznacz cały

#include <stm32f10x.h>
#include "stm32f1xx_it.h"

int main (void)
{


   RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;

//   GPIOA -> CRH &= ~GPIO_CRH_CNF10_1;
//   GPIOA -> CRH |=  GPIO_CRH_CNF10_0;

   GPIOA -> CRH |= GPIO_CRH_MODE9_0;
   GPIOA -> CRH |= GPIO_CRH_CNF9_1;
   GPIOA -> CRH &= ~GPIO_CRH_CNF9_0;

   SysTick_Config(8000000/1000);

   USART1 -> BRR = (8000000/9600);
   USART1 -> CR1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;

   NVIC_EnableIRQ(USART1_IRQn);
   while(1)
   {
      Delay_ms(500);
      USART1 -> DR = 222;
   }
}

ps19
Newb
Newb
Posty: 56
Rejestracja: poniedziałek 05 paź 2015, 22:27
Lokalizacja: Opole
Kontaktowanie:

Re: STM32F103 UART na rejestrach

Postautor: ps19 » piątek 11 lis 2016, 21:26

Maim zdaniem masz coś namieszane w pliku od zegarów - sprawdź na tym:

Co do konfiguracji to zmieniasz tylko 0/1 pliku .h CLOCK_SOURCE

Plik system_stm32f10x.c

Kod: Zaznacz cały

#include <stdint-gcc.h>

#include <stm32f10x.h>
#include "system_stm32f10x.h"

void SystemInit(void)
{
   //source http://www.freddiechopin.info/
   // set all ports to input with pull-down
   GPIOA->CRL = 0x88888888;
   GPIOA->CRH = 0x88888888;
   GPIOA->ODR = 0;
   GPIOB->CRL = 0x88888888;
   GPIOB->CRH = 0x88888888;
   GPIOB->ODR = 0;
   GPIOC->CRL = 0x88888888;
   GPIOC->CRH = 0x88888888;
   GPIOC->ODR = 0;
   GPIOD->CRL = 0x88888888;
   GPIOD->CRH = 0x88888888;
   GPIOD->ODR = 0;
   GPIOE->CRL = 0x88888888;
   GPIOE->CRH = 0x88888888;
   GPIOE->ODR = 0;
   
   RCC->APB1ENR |= RCC_APB1ENR_PWREN;
   RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN
         | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; //enable PORTS (A,B,C,D) and AFIO
         
#if CLOCK_SOURCE == 1
   pll_start(CRYSTAL, CPU_FREQUENCY); //external clock is used
#endif
#if CLOCK_SOURCE == 0
   internal_clock(CPU_FREQUENCY); //internal clock is used
#endif
}

void flash_latency(uint32_t frequency)
{
   //source http://www.freddiechopin.info/
   uint32_t wait_states;
   
   if (frequency < 24000000ul) wait_states = 0; //0 wait states for core speed below 24MHz
   else if (frequency < 48000000ul) wait_states = 1; //1 wait state for core speed between 24MHz and 48MHz
   else wait_states = 2; //2 wait states for core speed over 48MHz
         
   FLASH->ACR |= wait_states;            // set the latency
}

/*------------------------------------------------------------------------*//**
 *
 * Configure and enable PLL to achieve some frequency with some crystal.
 * Before the speed change Flash latency is configured via flash_latency(). PLL
 * parameter mul is based on both function parameters. The PLL is set up,
 * started and connected. APB1 clock ratio is set to 1:2 (max freq = 36MHz)
 *
 * \param [in] crystal is the frequency of the crystal resonator connected to the
 * STM32F103RB
 * \param [in] frequency is the desired target frequency after enabling the PLL
 *
 * \return real frequency that was set
 *
 * Function flash_latency, pll_start, SystemInit from http://www.freddiechopin.info/ moded by ps19
 */

uint32_t pll_start(uint32_t crystal, uint32_t frequency)
{
   //source http://www.freddiechopin.info/
   uint32_t mul;
   
   RCC->CR |= RCC_CR_HSEON; //enable HSE clock
   flash_latency(frequency); //configure Flash latency for desired frequency
         
   mul = frequency / crystal; // PLL multiplier calculation
   if (mul > 16) mul = 16; // max PLL multiplier is 16
   frequency = crystal * mul;
   
   RCC->CFGR |= ((mul - 2) << 18) | RCC_CFGR_PLLSRC | RCC_CFGR_ADCPRE_DIV6 | RCC_CFGR_PPRE1_DIV2;   //configuration of PLL: HSE x (mul), APB1 clk = /2
         
   while (!((RCC->CR) & RCC_CR_HSERDY));   //wait for stable clock
      
   RCC->CR |= RCC_CR_PLLON; //enable PLL
   while (!((RCC->CR) & RCC_CR_PLLRDY)); //wait for PLL lock
      
   RCC->CFGR |= RCC_CFGR_SW_PLL; //change SYSCLK to PLL
   while (((RCC->CFGR) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); //wait for switch
      
   return frequency;
}

void internal_clock(uint32_t frequency)
{
   //Written by ps19
   uint32_t mul;
   
   RCC->CR |= RCC_CR_CSSON | RCC_CR_HSION;
   
   flash_latency(frequency); // configure Flash latency for desired frequency
         
   mul = frequency / 8000000UL; // PLL multiplier calculation
   if (mul > 16) mul = 16;   // max PLL multiplier is 16
   frequency = 8000000UL * mul;
   
   RCC->CFGR &= ~RCC_CFGR_PLLSRC; // HSI/2 as source for PLL
   RCC->CFGR |= ((mul - 2) << 18) | RCC_CFGR_PPRE1_DIV2; //APB1/2
   while (!((RCC->CR) & RCC_CR_HSIRDY)); //wait for stable HSI clock
   RCC->CR |= RCC_CR_PLLON; //enable PLL
   while (!((RCC->CR) & RCC_CR_PLLRDY)); //wait for PLL lock
   RCC->CFGR |= RCC_CFGR_SW_PLL; //change SYSCLK to PLL
   while (((RCC->CFGR) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); //Wait until PLL will be work as clock source
}

void gpio_pin_cfg(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value)
{
   //source http://www.freddiechopin.info/
   volatile uint32_t *cr_ptr;
   uint32_t cr_value;
   
   cr_ptr = &port_ptr->CRL;   //configuration of pins [0,7] is in CRL
         
   if (pin >= 8)    //is pin in [8; 15]?
   {            //configuration of pins [8,15] is in CRH
      cr_ptr++;   //advance to next struct element CRL -> CRH
      pin -= 8;   //crop the pin number
   }
   
   cr_value = *cr_ptr;   //localize the CRL / CRH value
         
   cr_value &= ~((3 | 3 << 2) << (pin * 4));//clear the MODE and CNF fields (now that pin is an analog input)
   cr_value |= (mode_cnf_value << (pin * 4));//save new MODE and CNF value for desired pin
         
   *cr_ptr = cr_value;   //save localized value to CRL / CRL
}


Plik system_stm32f10x.h:

Kod: Zaznacz cały

#ifndef SYSTEM_STM32F10X_H_
#define SYSTEM_STM32F10X_H_

#include "stm32f10x.h"

void gpio_pin_cfg(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value);
uint32_t pll_start(uint32_t crystal, uint32_t frequency);
void flash_latency(uint32_t frequency);
extern void SystemInit(void);
void internal_clock(uint32_t frequency);

#define CLOCK_SOURCE 1 //External source == 1; Internal source == 0;

#if CLOCK_SOURCE == 1
#define CRYSTAL 8000000
#define CPU_FREQUENCY 72000000
#endif
#if CLOCK_SOURCE == 0
#define CPU_FREQUENCY 64000000
#endif

#endif /* SYSTEM_STM32F10X_H_ */

StaryAnoda

Re: STM32F103 UART na rejestrach

Postautor: StaryAnoda » sobota 12 lis 2016, 18:34

Cześć

Podmieniłem te pliki:
Jedynie to kompilator krzyczał o funkcję :

Kod: Zaznacz cały

void gpio_pin_cfg(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value);

Więc chwilowo ją usunąłem.
Konfiguracja zegara wygląda tak:

Kod: Zaznacz cały

#define CLOCK_SOURCE 1 //External source == 1; Internal source == 0;

#if CLOCK_SOURCE == 1
#define CRYSTAL 8000000
#define CPU_FREQUENCY 16000000
#endif
#if CLOCK_SOURCE == 0
#define CPU_FREQUENCY 16000000
#endif


Plik main.c wygląda tak:

Kod: Zaznacz cały

#include <stm32f10x.h>
#include "stm32f1xx_it.h"

int main (void)
{


   RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;

//   GPIOA -> CRH &= ~GPIO_CRH_CNF10_1;
//   GPIOA -> CRH |=  GPIO_CRH_CNF10_0;

   GPIOA -> CRH |= GPIO_CRH_MODE9_0;
   GPIOA -> CRH |= GPIO_CRH_CNF9_1;
   GPIOA -> CRH &= ~GPIO_CRH_CNF9_0;

   SysTick_Config(16000000/1000);

   USART1 -> BRR = (16000000/9600);
   USART1 -> CR1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;

   NVIC_EnableIRQ(USART1_IRQn);
   while(1)
   {
      Delay_ms(500);
      USART1 -> DR = 222;
   }
}

__attribute__((interrupt)) void USART1_IRQHandler (void)
{
   if(USART1 -> SR & USART_SR_RXNE)
   {
      USART1 -> SR &=~USART_SR_RXNE;
      uint16_t tmp;
      tmp = USART1 ->DR;
      USART1 ->DR = tmp+1;
   }
}


I tak analizator stanów logicznych jest w stanie bez problemu przeanalizować tą transmisję bez opcji autoband. Ustawiona prędkość 9600 taka jak w programie:
Screenshot (27).png


Natomiast PUTTY ustawiony w taki sposób:
Screenshot (31).png


Wyświetla takie śmieci:
Screenshot (30).png
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

ps19
Newb
Newb
Posty: 56
Rejestracja: poniedziałek 05 paź 2015, 22:27
Lokalizacja: Opole
Kontaktowanie:

Re: STM32F103 UART na rejestrach

Postautor: ps19 » sobota 12 lis 2016, 18:52

1.Jak masz Zewnętrzny kwarc (8Mhz) to ustaw 1 jak wewnętrzny kwarc to ustaw 0 w

Kod: Zaznacz cały

#define CLOCK_SOURCE

2. Podaj z putty Session->Logging to tam ustawiasz Baudrate i kanał.
3.I moja propozycja kodu - zmieniłem tylko te 16000000 nie wiem skąd wzięte na definicje - bo po co zmieniać program w 5 miejscach i dodałem includa z system_stm32f10x

Kod: Zaznacz cały

#include <stm32f10x.h>
#include "stm32f1xx_it.h"
#include "system_stm32f10x.h"

int main (void)
{
   RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;

//   GPIOA -> CRH &= ~GPIO_CRH_CNF10_1;
//   GPIOA -> CRH |=  GPIO_CRH_CNF10_0;

   GPIOA -> CRH |= GPIO_CRH_MODE9_0;
   GPIOA -> CRH |= GPIO_CRH_CNF9_1;
   GPIOA -> CRH &= ~GPIO_CRH_CNF9_0;

   SysTick_Config(CPU_FREQUENCY/1000);

   USART1 -> BRR = (CPU_FREQUENCY/9600); //pobierane z plik system_stm32f10x.h
   USART1 -> CR1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;

   NVIC_EnableIRQ(USART1_IRQn);
   while(1)
   {
      Delay_ms(500);
      USART1 -> DR = 222;
   }
}

__attribute__((interrupt)) void USART1_IRQHandler (void)
{
   if(USART1 -> SR & USART_SR_RXNE)
   {
      USART1 -> SR &=~USART_SR_RXNE;
      uint16_t tmp;
      tmp = USART1 ->DR;
      USART1 ->DR = tmp+1;
   }
}

StaryAnoda

Re: STM32F103 UART na rejestrach

Postautor: StaryAnoda » sobota 12 lis 2016, 18:56

Mam zewnętrzny kwarc. Zresztą na wewnętrzym też takie same objawy martwi mnie to, że na analizatorze widać dane a w terminalu nie. Czy mógłby mi ktoś jeszcze jedną rzecz sprawdzić czy na pewno pin TX dobrze ustawiłem może tu jest problem.

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: STM32F103 UART na rejestrach

Postautor: dambo » sobota 12 lis 2016, 19:13

a ja o co innego zapytam - jaka przejściówka między STMem, a kompem?
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

StaryAnoda

Re: STM32F103 UART na rejestrach

Postautor: StaryAnoda » sobota 12 lis 2016, 19:26

FT232, próbowałem również na tej która siedzi na Nucleo.

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: STM32F103 UART na rejestrach

Postautor: dambo » sobota 12 lis 2016, 19:32

no jeśli analizator to poprawnie rozpoznaje to nie mam pomysłu, a zrób w pętli wysyłanie różnych znaków i to od 0 do 255 i zobacz co się stanie wtedy
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

StaryAnoda

Re: STM32F103 UART na rejestrach

Postautor: StaryAnoda » sobota 12 lis 2016, 19:52

No coś się wyjaśniło dodałem taki kawałek kodu:

Kod: Zaznacz cały

   
for(i = 0; i <= 255; i++)
{
Delay_ms(10);
USART1 -> DR = i;
}

while(1)
{

}


I tak wyniki na analizatorze:

Screenshot (34).png


I coś się zaczęło pojawiać na PUTTYm:
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

ps19
Newb
Newb
Posty: 56
Rejestracja: poniedziałek 05 paź 2015, 22:27
Lokalizacja: Opole
Kontaktowanie:

Re: STM32F103 UART na rejestrach

Postautor: ps19 » sobota 12 lis 2016, 20:01

Może w systemie masz skopane ustawienie portu COM ?

Przywróć domyślne w Panel Sterowania->Menedżer Urządzeń Odszukaj tam port COM->Właściwości i tam gdzie ustawiasz baud itp daj domyślne.

Do ustawienia portu użyj funkcji gpio_pin_config tutaj masz przyklad:

Kod: Zaznacz cały

   gpio_pin_cfg(GPIOA, 9, GPIO_MODE_AF_PP_2MHZ); //TX
   gpio_pin_cfg(GPIOA, 10, GPIO_MODE_IN_FLOATING); //RX


Dorzuć to do pliku system_stm32.....h

Kod: Zaznacz cały

typedef enum
{
   /* Push-Pull */
   GPIO_MODE_OUT_PP_2MHZ = 2,
   GPIO_MODE_OUT_PP_10MHZ = 1,
   GPIO_MODE_OUT_PP_50MHZ = 3,
   /* Open-Drain */
   GPIO_MODE_OUT_OD_2MHZ = 6,
   GPIO_MODE_OUT_OD_10MHZ = 5,
   GPIO_MODE_OUT_OD_50MHZ = 7,
   /* Push-Pull */
   GPIO_MODE_AF_PP_2MHZ = 10,
   GPIO_MODE_AF_PP_10MHZ = 9,
   GPIO_MODE_AF_PP_50MHZ = 11,
   /* Open-Drain */
   GPIO_MODE_AF_OD_2MHZ = 14,
   GPIO_MODE_AF_OD_10MHZ = 13,
   GPIO_MODE_AF_OD_50MHZ = 15,
   /* Analog input (ADC) */
   GPIO_MODE_IN_ANALOG = 0,
   /* Floating digital input. */
   GPIO_MODE_IN_FLOATING = 4,
   /* Digital input with pull-up/down (depending on the ODR reg.). */
   GPIO_MODE_INPUT_PULL = 8
} GpioMode_t;

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: STM32F103 UART na rejestrach

Postautor: dambo » sobota 12 lis 2016, 20:09

ok, no to zobacz jakie znaczki są widoczne dla kompa jako kody ASCII, nie wiem co może być nie tak, ale baudrate wygląda na ok
Nowy blog o tematyce embedded -> https://www.embedownik.pl/


Wróć do „ARM STMicroelectronics”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 5 gości