Merhaba uzun zamandır cevabını aradığım bir problem vardı CoIDE de. sprintf komutu float tanımlamalarda çalışmıyordu.
hem çözümü buldum hemde Usart1 ile ilgili bir çalışma yaptım.
Önce CoIde ile alakalı problemi çözelim. Bunun için projeye eklediğimiz iki dosyada değişiklik yapacağız.
CoIde ile yeni bir proje oluşturup işlemcimizi seçtikten sonra (stm32f100RB) , repository penceresinden C Library, CMSIS Core, CMSIS Core dosyalarının seçelim.
Bazı blog ve forumlarda retarget printf dosyasınında eklenmesini istesede biz bunu yapmayacağız. Bir sonraki basamak ise aynı pencerenin Others sekmesinde RCC,GPIO,FLASH ve USART ın seçilmesi gerekiyor. USART ı seri iletişim yapacağımız için seçiyoruz.
Hata ile ilgili olarak il yapacağımız değişiklik startup_stm32f10x_md_vl.c dosyasında olacak.
dosyada geçen
1 2 3 4 |
/*----------Stack Configuration-----------------------------------------------*/ #define STACK_SIZE 0x00000100 /*!< Stack size (in Words) */ __attribute__ ((section(".co_stack"))) unsigned long pulStack[STACK_SIZE]; |
kod blogunu
1 2 3 4 |
/*----------Stack Configuration-----------------------------------------------*/ #define STACK_SIZE 0x00000300 /*!< Stack size (in Words) */ __attribute__ ((section(".co_stack"))) unsigned long pulStack[STACK_SIZE]; |
ilr değişmesi si gerekir.
ikinci işlemimiz ise yine aynı dosyada
1 |
(void *)&pulStack[STACK_SIZE-1], /*!< The initial stack pointer |
kodunun
1 |
(void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), /*!< The initial stack pointer */ |
değiştirmektir. Bu dosya ile işlemimiz bitti. Kaydedip kapatmak vakti gelmiştir.
Değişiklik yapacağımız diğer dosya syscalls.c dosyası.
1 2 3 4 |
int _write(int file, char *ptr, int len) { return len; } |
kod blogunu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int _write( int file, char *ptr, int len ) { int txCount; (void)file; for ( txCount = 0; txCount < len; txCount++) { USART_SendData(USART1, ptr[txCount]); //Don't forget to include "stm32f10x_usart.h" /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { } } return len; } |
ile değişmek gerekiyor. Değiştirme işlemini yaptıktan sonra artık printf fonksiyonunu kullanarak USART1 den veri gönderebilir, sprintf ile dizileri doldurabiliriz. (tanımda garip oldu)
USART la ilgili programımıza gelecek olursak. yukardaki düzenlemeleri yaptıktan sonra kodları yapıştırıp çalıştırınız. Projede sadece TX kullanılmıştır. GPIOA.9 dan bilgiler gönderilmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
#include "stm32f10x.h" #include "stm_lib/inc/stm32f10x_gpio.h" #include "stm_lib/inc/stm32f10x_rcc.h" #include "stm_lib/inc/stm32f10x_flash.h" #include "stm_lib/inc/stm32f10x_usart.h" #include <stdio.h> void SetSysClockTo24(void) { int i; RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); for(i=0;i<0x000FFFF;i++); FLASH_SetLatency(FLASH_Latency_0); RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div1); /* PLLCLK = (8MHz/2) * 6 = 24 MHz */ RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE,RCC_PREDIV1_Div1); RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3); RCC_PLLCmd(ENABLE); /* Enable PLL */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while (RCC_GetSYSCLKSource() != 0x08) { } RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); } /***************************************************************************//** * @brief Init USART1 ******************************************************************************/ void ConfigUSART() { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* Enable GPIOA clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* Configure USART1 Rx (PA10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Tx (PA9) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART1 configured as follow: - BaudRate = 9600 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control disabled (RTS and CTS signals) - Receive and transmit enabled - USART Clock disabled - USART CPOL: Clock is active low - USART CPHA: Data is captured on the middle - USART LastBit: The clock pulse of the last data bit is not output to the SCLK pin */ USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void USART_puts(USART_TypeDef* USARTx, volatile char *s){ while(*s){ // wait until data register is empty while( !(USARTx->SR & 0x00000040) ); USART_SendData(USARTx, *s); *s++; } } int main(void) { SetSysClockTo24(); ConfigUSART(); while(1) { char dizi[10]; sprintf (dizi,"flt: %4.4fn", 1.4142135); USART_puts(USART1,dizi); printf("flt: %4.4fn", 1.4142135); } } |