Strona 1 z 1
STM32F103 UART na rejestrach
: piątek 11 lis 2016, 20:57
autor: StaryAnoda
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 */
#endifNataomiast 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;
}
}
Re: STM32F103 UART na rejestrach
: piątek 11 lis 2016, 21:26
autor: ps19
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_ */
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 18:34
autor: StaryAnoda
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
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 18:52
autor: ps19
1.Jak masz Zewnętrzny kwarc (8Mhz) to ustaw 1 jak wewnętrzny kwarc to ustaw 0 w
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;
}
}
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 18:56
autor: StaryAnoda
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.
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 19:13
autor: dambo
a ja o co innego zapytam - jaka przejściówka między STMem, a kompem?
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 19:26
autor: StaryAnoda
FT232, próbowałem również na tej która siedzi na Nucleo.
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 19:32
autor: dambo
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
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 19:52
autor: StaryAnoda
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:
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 20:01
autor: ps19
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); //RXDorzuć 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;
Re: STM32F103 UART na rejestrach
: sobota 12 lis 2016, 20:09
autor: dambo
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