TKM32F499 high-performance MCU evaluation board trial, everything is difficult at the beginning, let's turn on a light first to calm down! - Tencent Cloud Developer Community - Tencent Cloud

Content

As shown in the figure below, the evaluation board looks like this:

TKM32F499 Shenzhen Hao Jurun Technology Co., Ltd. issued a high-performance microcontroller. The above picture is an evaluation board based on TKM32F499. You can see that the resources on the evaluation board are quite rich, and it is also very cheap, with a price of only 88 yuan. It is really cost-effective. Where is the value? Let's take a look at the features to find out.

1. Characteristics

  1. IPS full-view LCD screen, high visibility under sunlight;

2、High resolution 800*480;

3、Large storage space: 16MB of FLASH and 8MB of RAM, capable of running complex interface programs;

4、Adopt high-performance TK499 chip, 240MHz, with FPU, supporting hardware floating-point operation;

  1. USB download, you can use USB to update programs, icons, and fonts;

6、Equipped with WIFI module, supports wireless display, conducive to connecting to IoT Internet of Things

7、Provide rich peripherals: serial port, SPI, GPIO, USB, SDIO, five-way buttons, 3 LED lights;

8、High cost performance, 88 yuan includes high-performance M4 chip, 16M FLASH and 8M RAM, and high-resolution TFT screen, can be programmed directly on the chip, more flexible than serial screen, and faster speed;

This powerful evaluation board, directly integrated into our product, is a natural advantage, but I wonder if it will be difficult to develop?

According to the official introduction to the evaluation board, users do not need to worry about environment settings and path settings. Everything has been configured for us, so we just need to get the project files of the program and can start writing code directly. For other specific instructions, simply refer to the information package.

2. Development Platform

What platform is used to develop this chip?

This is our familiar Keil5, the programming style is almost the same as STM32.

To make the chip work and drive the connected peripherals, first we need to understand some specifications of the chip, such as system block diagram, pin arrangement and pin description, memory mapping table. After understanding these, we then combine the chip's Datasheet to look up the corresponding registers and notes, and finally complete the software development for our product functionality.

3. TKM32F499 Chip Architecture

Here is the system block diagram of the TKM32F499 chip, the system block diagram allows us to quickly understand which module units are included in this chip, so that we can make selections when developing products.

You can see that the chip is based on the ARM-ContexM4 FPU architecture, let's briefly understand:

ARM Cortex-M4 processor is the latest embedded processor developed by ARM, which enhances computational capabilities based on M3, and adds features such as floating-point, DSP, and parallel computing.

ARM-ContexM4 FPU processor is based on this architecture with a single-precision floating-point unit (FPU), which can efficiently handle more complex floating-point operations, such as motor closed-loop control, PID algorithm, fast Fourier transform, etc.

The TKM32F499 supports many functions, in addition to the regular features found on the STM32, it also includes a special module, such as the TK80.

4. TKM32F499 chip pin and arrangement instructions

5. TKM32F499 Memory Mapping Table

6. TKM32F499 Evaluation Program Writing Steps and Program Interpretation

Play with any board, first turn on a light, and then it will be easier. The first example GPIO_LED in the official data package makes the LED on the evaluation board blink at a fixed frequency. Let's take a look at the schematic diagram:

Since PWM is not used in the routine to drive the LED, driving it directly with high and low levels can make it work. The pin is connected to position PD8.

Since the programming method is the same as STM32, it must be the following process:

  1. Initialize and enable RCC clock

2、GPIO mode configuration and initialization

3、Using GPIO

TKM32F499, the official development library has been written, we can use it directly. To write this routine, a total of four APIs from the library are needed, which are:

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin);

6.1 RCC_AHBPeriphClockCmd

RCC_AHBPeriphClockCmd is used to configure the RCC clock of the system. Only when the clock is up, can the peripherals work. By checking HAL_rcc.h, you can see that the official has already written the corresponding addresses according to the Datasheet.

Here we need to control the external device GPIOD. According to the memory map, we can see that GPIOD is connected to the AHB1 bus:

Correspondingly, next, look at the section in the Datasheet regarding RCC for the description of this part:

We need to enable the third bit of this register so that the GPIOD function can be used normally.

So it's very simple, all we need to do is perform a logical OR operation on this bit and the RCC's AHB1 peripheral clock enable register, let's see how it's written in the program:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

The source code implementation of chasing into the function RCC_AHBClockCmd:

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    RCC->AHB1ENR |= RCC_AHBPeriph;
  }
  else
  {
    RCC->AHB1ENR &= ~RCC_AHBPeriph;
  }
}

Here, the assert_param assertion function is first used to check the validity of the parameters, mainly to check for invalid addresses.

Next, judge the NewState parameter. If it is ENABLE, set RCC->AHB1ENR; otherwise, clear that bit. The NewState parameter is actually an enumeration.

typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

So what is RCC->AHB1ENR? Let's trace the definition:

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< SRAM base address in the bit-band region */
#define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
#define RCC_BASE              (AHB1PERIPH_BASE + 0x3800)
#define RCC                 ((RCC_TypeDef *) RCC_BASE)

This is to force a address into a structure, STM32 also does this, let's take a look at the corresponding structure:

typedef struct
{
  __IO uint32_t CR;            /*!< RCC clock control register,                   Address offset: 0x00 */
  __IO uint32_t PLLCFGR;       /*!< RCC clock configuration register,             Address offset: 0x04 */
  __IO uint32_t CFGR;          /*!< RCC clock configuration register,             Address offset: 0x08 */
  __IO uint32_t CIR;           /*!< RCC clock interrupt register,                 Address offset: 0x0C */
  __IO uint32_t AHB1RSTR;      /*!< RCC AHB peripheral clock register,            Address offset: 0x10 */
  __IO uint32_t AHB2RSTR;      /*!< RCC AHB peripheral clock register,            Address offset: 0x14 */
  __IO uint32_t APB1RSTR;      /*!< RCC AHB peripheral clock register,            Address offset: 0x18 */
  __IO uint32_t APB2RSTR;      /*!< RCC AHB peripheral clock register,            Address offset: 0x1C */
  __IO uint32_t AHB1ENR;       /*!< RCC AHB peripheral clock register,            Address offset: 0x20 */
  __IO uint32_t AHB2ENR;       /*!< RCC AHB peripheral clock register,            Address offset: 0x24 */
  __IO uint32_t APB1ENR;       /*!< RCC APB1 peripheral clock enable register,    Address offset: 0x28 */
  __IO uint32_t APB2ENR;       /*!< RCC APB1 peripheral clock enable register,    Address offset: 0x2C */
  __IO uint32_t BDCR;          /*!< RCC Backup domain control register,           Address offset: 0x30 */
  __IO uint32_t CSR;           /*!< RCC clock control & status register,          Address offset: 0x34 */
  __IO uint32_t PLLLCDCFGR;   /*!< RCC clock configuration register 2,           Address offset: 0x38 */
  __IO uint32_t PLLDCKCFGR;       /*!< RCC clock configuration register 3,           Address offset: 0x3C */
} RCC_TypeDef;

The member corresponding to the structure is the address of the RCC. If you want to understand its configuration in detail, you can refer to the Clock section of the manual.

RCC_AHBPeriph_GPIOD is a macro

The corresponding value is 0x0000008, which is (1 << 3), so the conclusion is that by passing this macro as a parameter to the RCC_AHBPeriphClockCmd function, writing ENABLE in the second function will complete the initialization of enabling the RCC clock for GPIOD, awesome! Therefore, it is very easy to write the following code to configure the clock for enabling GPIOD:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

6.2 GPIO_Init

/**
* @brief  Initializes the GPIOx peripheral according to the specified
*   parameters in the GPIO_InitStruct.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
*   contains the configuration information for the specified GPIO
*   peripheral.
* @retval : None
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

This function initializes the GPIO (General Purpose I/O) functionality, similar to RCC, the program also defines a structure GPIO_TypeDef for operating GPIO-related functions. The following are some corresponding registers:

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
       uint32_t RESERVED;
  __IO uint32_t AFRL;
  __IO uint32_t AFRH;
  __IO uint32_t CRH_EXT;
  __IO uint32_t BSRR_EXT;
  __IO uint32_t AFRH_EXT;
} GPIO_TypeDef;

You can see the detailed description of the registers in the GPIO chapter manual:

When setting the pins, speed, and mode of IO, use the GPIO_InitTypeDef structure:

typedef struct
{
  uint32_t GPIO_Pin;
  GPIOSpeed_TypeDef GPIO_Speed;
  GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;

GPIO_Pin is used to set the pin, corresponding to the respective macro:

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /* Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /* Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /* Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /* Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /* Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /* Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /* Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /* Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /* Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /* Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /* Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /* Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /* Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /* Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /* Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /* Pin 15 selected */
#define GPIO_Pin_16              ((uint32_t)0x010000)  /* Pin 16 selected */
#define GPIO_Pin_17              ((uint32_t)0x020000)  /* Pin 17 selected */
#define GPIO_Pin_18              ((uint32_t)0x040000)  /* Pin 18 selected */
#define GPIO_Pin_19              ((uint32_t)0x080000)  /* Pin 19 selected */
#define GPIO_Pin_20              ((uint32_t)0x100000)  /* Pin 20 selected */
#define GPIO_Pin_21              ((uint32_t)0x200000)  /* Pin 21 selected */
#define GPIO_Pin_22              ((uint32_t)0x400000)  /* Pin 22 selected */
#define GPIO_Pin_23              ((uint32_t)0x800000)  /* Pin 23 selected */
#define GPIO_Pin_All             ((uint32_t)0xFFFFFF)  /* All pins selected */

GPIO_Speed is used to configure the IO speed rate, corresponding to an enumeration:

typedef enum
{
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz,
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

GPIO_Mode is used to configure the mode of the IO, corresponding to an enumeration

typedef enum
{
GPIO_Mode_AIN = 0x0,  //Analog input
GPIO_Mode_IN_FLOATING = 0x04, //Floating input
GPIO_Mode_IPD = 0x28,  //Pull-down input
GPIO_Mode_IPU = 0x48,  //Pull-up input
GPIO_Mode_Out_OD = 0x14,//General purpose open-drain output
GPIO_Mode_Out_PP = 0x10,//General purpose push-pull output
GPIO_Mode_AF_OD = 0x1C, // Alternate function open-drain output
GPIO_Mode_AF_PP = 0x18  //Alternate function push-pull output
}GPIOMode_TypeDef;

After understanding the following key points, we can quickly write code for the configuration of LED pins:

//1. Define GPIO initialization structure variable
GPIO_InitTypeDef GPIO_InitStructure;
//2. Initialize and configure pins
GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_8;
//3. Initialize pin speed
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//4. Initialize pin mode, configure as push-pull output mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//5. Call GPIO_Init to complete IO initialization
GPIO_Init(GPIOD, &GPIO_InitStructure);

6.3 GPIO_SetBits, GPIO_ResetBits

GPIO_SetBits and GPIO_ResetBits are mainly used to set and clear ports, corresponding to the following register:

The following is the source code for two functions:

/**
* @brief  Sets the selected data port bits.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bits to be written.
*   This parameter can be any combination of GPIO_Pin_x where
*   x can be (0..15).
* @retval : None
*/
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  if(GPIO_Pin>GPIO_Pin_15)GPIOE->BSRR_EXT=GPIO_Pin>>16;
 	else
  GPIOx->BSRR = GPIO_Pin;
}
/**
* @brief  Clears the selected data port bits.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bits to be written.
*   This parameter can be any combination of GPIO_Pin_x where
*   x can be (0..15).
* @retval : None
*/
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BRR = GPIO_Pin;
}

Based on the functional description, it is very easy to write the following code:

//For the eighth bit of GPIOD
GPIO_SetBits(GPIOD, GPIO_Pin_8); //Output high level at PC8, light up LED
//Clear the eighth bit of GPIOD
GPIO_ResetBits(GPIOD, GPIO_Pin_8);//Output low level at PD8, turn off LED

The following is the source code of this demo:

/****************************************Copyright (c)****************************************************
**
**
**
**--------------File Info---------------------------------------------------------------------------------
** File name:            main.c
** modified Date:        2017-6-20
** Last Version:        V0.1
** Descriptions:          main function call
**
** 好钜润科技,芯片事业部----深圳龙华应用分部
*********************************************************************************************************/
#include "HAL_conf.h"
/********************************************************************************************************
**Function Information: int main (void)
**Function Description:
**Input Parameters:
**Output Parameters:
********************************************************************************************************/
int main(void)
{
 uint32_t  i;
 GPIO_InitTypeDef GPIO_InitStructure;//Define GPIO initialization structure variable

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

 //Configure the GPIO connected to the LED as push-pull output mode
 GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_8;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_Init(GPIOD, &GPIO_InitStructure);
 while(1)//Infinite loop
 {
     GPIO_SetBits(GPIOD, GPIO_Pin_8); //PC8 outputs high level, lights up LED
     for(i=0;i<2000000;i++);//Delay

GPIO_ResetBits(GPIOD, GPIO_Pin_8);//PD8 outputs low level, turn off LED for(i=0;i<2000000;i++);//delay

}

7. TKM32F499 Program Compilation and Download

7.1 Program Compilation

Just like STM32, you can compile the program by directly clicking on the compile button in the Keil software. If there are no errors in the program, it will generate the corresponding bin file.

7.2 Program Burning

TK499 supports downloading via USB flash drive, no need for a downloader, just use a USB cable to download.

Method 1: Push the five-way button upwards, press the reset button once (note that when releasing, release the reset button first, then release the five-way button), and then click the download button of the KEIL program to start the download. KEIL will not prompt whether the download is complete, just listen for the 'ding' sound of exiting the USB drive. The download is usually automatically executed. If it doesn't run, you can press the reset button once or power off and then power on to run it.

Method 2: Push up, press the reset button once to enter the program download mode, a USB flash drive will also pop up, drag the bin program generated in the KEIL project directory into the USB flash drive, as shown in the figure below.

If it is the first time using the chip, you need to burn a Bootloader first. The method is: push the five-way button to the left, then press the reset button again to enter the Bootloader download mode (note that when releasing the button, release the reset button first, then release the five-way button). At this time, a TK499 U disk will pop up, just drag the TK499_Bootloader.bin from the development package compression package into it (in general, the development board has already burned the Bootloader, this step can be omitted)

Bootloader is an important file, and Bootloader will be continuously upgraded in the future. It can be used to download images and fonts via USB.

注意:2019.10.1 Before the program released, the flash_download.exe download tool is generally not placed in the project folder, so method one cannot be used for downloading. Of course, it is very easy to add it yourself, just put this small tool in the project directory, and then copy and paste the following two lines of commands.

flash_download
..//@L.bin TK499_V2

8. Run Results

LED flashes at a fixed frequency:

Finally, thank you to the Taobao customer service lady for sending me an extra touch development board:

TKM32F499 Evaluation Board Sample Code and Documentation Download

Link: https://pan.baidu.com/s/1xujEO4vJ7i7UUK7v_fGNgw
Extraction code: g1y2
Summary
The article introduces a high-performance microcontroller, TKM32F499, developed by Shenzhen Hao Jurun Technology Co., Ltd. The evaluation board based on TKM32F499 is rich in features and affordable at only 88 yuan. It includes an IPS LCD screen, large storage space, a high-performance TK499 chip, USB downloading, WiFi module, and various peripherals. Development is simplified as the environment and paths are pre-configured. Development is done using Keil5, similar to STM32. The article explains the TKM32F499 chip architecture, pin layout, memory mapping, and provides a step-by-step guide for writing evaluation programs. The example program blinks an LED using GPIO functions. The RCC_AHBPeriphClockCmd function is used to configure the system's RCC clock. The article includes code snippets and explanations for enabling the GPIOD peripheral clock. The article also discusses the ARM Cortex-M4 FPU architecture and the features of the TKM32F499 chip.