顯示具有 Keil 標籤的文章。 顯示所有文章
顯示具有 Keil 標籤的文章。 顯示所有文章

2016年3月8日 星期二

[STM32] 如何取到STM32 MCU的Serial ID


unsigned int serial_id[3];

serial_id[0] = *((unsigned int *)0x1FFFF7E8));
serial_id[1] = *((unsigned int *)0x1FFFF7EC));
serial_id[2] = *((unsigned int *)0x1FFFF7F0));

Reference:
[1] http://www.keil.com/forum/58081/read-unique-id/

2013年11月29日 星期五

[FreeRTOS] FreeRTOS 移植到 STM32F407Discovery

Porting FreeRTOS最快的方法,就是利用FreeRTOS官網提供DemoCode來改,不過因為DemoCode所使用的STM32 Driver都是比較舊的,而且程式碼又較複雜,所以還是整理一份比較乾淨的版本,掌握度會比較高。
  • FreeRTOS (使用STM32F407)
    圖一
    圖一是FreeRTOS Source目錄架構,這個資料夾是FreeRTOS的核心。而要使用FreeRTOS有幾個重點要注意,
    • Complier
      路徑:Source\portable\{ComplierVersion}\{CPU}\port.c
      • Complier : RVDS(Keil) or GCC
      • CPU : (ARM_CA9/ARM_CM3/ARM_CM4F)

    • MemoryManagement
      路徑:Source\MemMang\heap_X.c
      • X:heap有四個版本
    • FreeRTOSConfig.h
      路徑: Demo\{MCU}\FreeRTOSConfig.h
      • MCU: 這個檔案是根據MCU來設定,通常直接拿DemoCode的來用,不過還是要根據MCU的硬體來設定,所以我選用Demo\CORTEX_M4F_STM32F407ZG-S\FreeRTOSConfig.h
  • STM32 Driver
    • STM32F4xx_StdPeriph_Driver
      此資料夾是STM32的周邊Driver,通常會使用最新版,而我習慣使用GPIO來改。
    • Peripheral_Examples此資料夾是STM32的Demo程式,我習慣使用GPIO來做修改。
  • Porting
  • 圖二
    圖二為程式的目錄架構和要Import的檔案,而接下來就是如何讓FreeRTOS跟STM32綁在一下,有三個重要function需要介接
    • vPortSVCHandler();
    • xPortPendSVHandler();
    • xPortSysTickHandler(); 
    介接這三個Function,以下提供兩個方法
    • 1. 修改 startup_stm32f4xx.s
      將紅色框框的部分加入到startup_stm32f4xx.s
    圖三
    • 2. 修改FreeRTOSConfig.h將紅色框框的部分加入到FreeRTOSConfig.h (如果Complier時,發生multiply defined,記得把它助解,通常會是stm32f4xx_it.c檔案裡)
    圖四
    完成以上步驟,大致上就已經完成Porting部分,接下就是用他啦摟,

    #include "stm32f10x.h"
    #include "FreeRTOS.h"
    #include "task.h"

    void vTask( void *pvParameters )
    {  
        portTickType xLastWakeTime = xTaskGetTickCount();
       
        while(1)
        {
            // do something
            vTaskDelayUntil( &xLastWakeTime, ( 500 / portTICK_RATE_MS ) );
        }
    }

    int main ()
    {
        xTaskCreate( vTask, ( signed portCHAR * ) "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
        vTaskStartScheduler();

        while(1);
    }
  • Note
    Reference [4]
    是已經Porting FreeRTOS for STM32F407-Discovery

Reference:
[1] FreeRTOS 
[2] STM32F4 入門教學:FreeRTOS 移植
[3] STM32 Driver 
[4] DemoCode - STM32F407VG-FreeRTOS

2013年11月26日 星期二

[STM32] 如何使用Keil內建函數,printf & scanf

printf & scanf 在嵌入式系統來說,都是一個非常好用但奢侈的功能,但為了加速開發時程,往往不會希望花太多時間重寫一個這樣的功能,所以最容易的方式就是直接用。當然要使用這兩個函數必須指定要輸出/輸入到哪個地方,而最常被拿來使用的,就是USART了。在Keil上只要設定以下幾個部分: (以下使用Polling方式)
  • Use MicroLIB
    [Project] -> Options for Target ... -> [Target] -> [Use MicroLIB] 
圖一
  • Implement PUTCHAR_PROTOTYPE & GETCHAR_PROTOTYPE
  • #include <stdio.h>
    #define USART_TYPE        USART1

    #ifdef __GNUC__
      #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
      #define GETCHAR_PROTOTYPE int __io_getchar(void)
    #else
      #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
      #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
    #endif /* __GNUC__ */

    // Implement
    PUTCHAR_PROTOTYPE
    {
      /* Write a character to the USART */
      USART_SendData(USART_TYPE, (u8) ch);

      /* Loop until the end of transmission */
      while(USART_GetFlagStatus(USART_TYPE, USART_FLAG_TXE) == RESET);
      return ch;
    }

    GETCHAR_PROTOTYPE
    {
       /* Loop until the end of receive */
       while(USART_GetFlagStatus(USART_TYPE, USART_FLAG_RXNE) == RESET);
     
       /* Read a character to the USART */
       return (USART_ReceiveData(USART_TYPE));

    }

  • 主程式 initial usart & 直接使用printf & scanf
  • #include<stdio.h>

    int main()
    {
            uint8_t data;
            USART_Init(); // 注意,記得要啟動要導向裝置
            while(1) {
                   scanf("%c\n",&data);
                   printf("Data = %c",data);
            }
    }

Reference:
[1] 在MDK使用printf&scanf

2013年11月3日 星期日

[Keil] 解決Keil使用JLink Debug,無法取得變數值(<not in scope>)

圖一
今天使用JLink Debug時,在main function發生如上圖的狀況,Keil Debug無法正常顯示變數的值,不管是data還是data1都一樣。最後發現了,只要是在main function運作的變數,雖然不知道原因是甚麼,不過可以使用以下的方式解決方法:

1. 設定Complier Mode成Level 0
[Options for Target]->[C/C++]->Optimization[Level0 (-O0)]

2. 不要直接main function取值,把它導到另一個function底下

如下圖二,即可取得變數的值。

圖二
3.若再不行,那把儲存的變數改成陣列
uint8_t data[2] = {0x00};
data[0] = 0x21;