前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TKM32F499高性能MCU评估板试用之万事开头难,先点个灯来压压惊!

TKM32F499高性能MCU评估板试用之万事开头难,先点个灯来压压惊!

作者头像
Mculover666
发布2020-07-16 15:06:08
7810
发布2020-07-16 15:06:08
举报
文章被收录于专栏:TencentOS-tinyTencentOS-tiny

如下图所示,评估板长这个样子:

TKM32F499深圳市好钜润科技有限公司发行的一款高性能单片机,以上图片是基于TKM32F499的一款评估板,可以看到评估板上的资源那是相当的丰富了,而且还是白菜价,到手价仅需88元,不得不说实在是香,香在哪呢?咱们看看特点就知道了。

1、特点

1、IPS全视角液晶屏,阳光下可视度高;

2、高分辨率800*480;

3、超大存储空间:16MB的FLASH及8MB的RAM,可以运行复杂的界面程序;

4、采用高性能TK499芯片,240MHz,带FPU,支持硬件浮点运算;

5、USB方式下载,可以用USB更新程序,图标及字库;

6、带WIFI模块,支持无线显示,利于接入IoT物联网

7、提供丰富外设:串口、SPI、GPIO、USB,SDIO、五向按键、3路LED灯;

8、性价比高,88元包含了高性能M4芯片,16M FLASH与8M RAM及高分辨率TFT屏, 可以直接片上编程,比串口屏灵活,速度更快;

这么强大的一个评估板,直接套在我们的产品上简直就是天然的优势,但不知道开发起来难度大不大?

根据官方对评估板的介绍,用户不需要关心环境设置以及路径设置,所有的一切,他们都帮我们配置好了,所以我们只需要拿到程序的工程文件,直接就可以开始编写代码,其它一些特殊的说明直接查看资料包即可。

2、开发平台

那这款芯片用什么平台来进行开发呢?

这是我们熟悉的Keil5,编程风格和STM32是几乎是一样的。

想要让芯片工作起来,去驱动连接的外设,首先我们得了解芯片的一些规格,比如系统框图、引脚排列和引脚说明、存储器映射表,了解了这些以后,我们再去结合芯片的Datasheet去查询相应的寄存器以及注意事项,最后完成我们产品功能的软件编写。

3、TKM32F499芯片架构

以下是TKM32F499芯片系统框图,系统框图能让我们快速了解这款芯片包含哪些模块单元,以便于我们开发产品时进行选型。

可以看到,芯片基于ARM-ContexM4 FPU架构,我们来简单了解下:

ARM Cortex-M4处理器是由ARM专门开发的最新嵌入式处理器,在M3的基础上强化了运算能力,新加了浮点、DSP、并行计算等。

ARM-ContexM4 FPU处理器则是在此架构基础上单精度浮点单元(FPU),能够高效率处理较为复杂的浮点运算,如电机闭环控制、PID算法、快速傅里叶变换等。

TKM32F499支持的功能还是非常多的,除了常规的STM32上有的功能,还加了一个特色模块,比如TK80.

4、TKM32F499芯片管脚及排列说明

5、TKM32F499存储器映射表

6、TKM32F499测评程序编写步骤及程序解读

玩任何一个板子,先点个灯,后面就好办了,官方资料包里第一个例程GPIO_LED是让评估板上的LED以固定的频率进行闪烁,我们来看下原理图:

由于例程里没有使用PWM去驱动LED,所以直接高低电平就可以驱动它进行工作了。管脚接在PD8这个位置。

既然和STM32的编程方式一样,那么肯定是以下的流程:

1、初始化并使能RCC时钟

2、GPIO模式配置及初始化

3、使用GPIO

TKM32F499,官方已经写好相应的开发库了,我们拿来即用即可,编写这个例程,一共需要用到库文件里四个API,分别是:

代码语言:javascript
复制
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用于配置系统的RCC时钟,只有时钟起来了,外设才能工作。打HAL_rcc.h可以看到,官方根据Datasheet已经写好了相应的地址。

这里我们要控制的外设是GPIOD,根据存储器映射图,我们可以看到GPIOD挂在AHB1总线下:

对应的,接下来看Datasheet关于RCC相关的章节关于这部分的描述:

我们需要把这个寄存器的第三位给使能了,那么GPIOD功能就可以正常使用了。

所以非常简单,我们只需要把这一位和RCC的AHB1外设时钟使能寄存器做一个或操作即可,来看看程序里是怎么写的:

代码语言:javascript
复制
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

追进该函数的RCC_AHBPeriphClockCmd源码实现:

代码语言:javascript
复制
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;
  }
}

这里首先使用断言函数assert_param检查参数是否有效,主要是检查是否为非法地址。

接下来判断NewState参数,如果是ENABLE ,则与RCC->AHB1ENR置位,否则清除该位,NewState参数其实是一个枚举。

代码语言:javascript
复制
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

那么RCC->AHB1ENR是啥呢?追进定义看看:

代码语言:javascript
复制
#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)

这是将一个地址强制转换成一个结构体,STM32里也是这么做的,我们看看对应的结构体:

代码语言:javascript
复制
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;

对应结构体的成员即为RCC的地址,如果想详细了解它的配置,可以查看手册时钟章节。

RCC_AHBPeriph_GPIOD是一个宏

对应的值是0x0000008,也就是(1 << 3),所以得出结论,把这个宏作为参数传递进RCC_AHBPeriphClockCmd这个函数,在第二个函数写上ENABLE即可完成GPIOD使能RCC时钟的初始化,真香!所以很容易可以写出以下代码完成GPIOD使能时钟的配置:

代码语言:javascript
复制
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

6.2 GPIO_Init

代码语言:javascript
复制
/**
* @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)

这个函数用户GPIO(通用功能I/O)功能的初始化,与RCC一样,程序里也是定义了操作GPIO相关的结构体GPIO_TypeDef,以下是对应的一些寄存器:

代码语言:javascript
复制
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;

详细可以看GPIO章节手册里对寄存器的描述:

对IO的管脚、速率、模式的设置,用的是GPIO_InitTypeDef这个结构体:

代码语言:javascript
复制
typedef struct
{
  uint32_t GPIO_Pin;
  GPIOSpeed_TypeDef GPIO_Speed;
  GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;

GPIO_Pin用于设置管脚,对应的也是相应的宏:

代码语言:javascript
复制
#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是用于IO速率的配置,对应的是一个枚举:

代码语言:javascript
复制
typedef enum
{
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz,
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

GPIO_Mode是针对IO的模式进行配置,对应的是一个枚举

代码语言:javascript
复制
typedef enum
{
GPIO_Mode_AIN = 0x0,  //模拟输入
GPIO_Mode_IN_FLOATING = 0x04, //浮空输入
GPIO_Mode_IPD = 0x28,  //下拉输入
GPIO_Mode_IPU = 0x48,  //上拉输入
GPIO_Mode_Out_OD = 0x14,//通用开漏输出
GPIO_Mode_Out_PP = 0x10,//通用推挽输出
GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出
GPIO_Mode_AF_PP = 0x18  //复用推挽输出
}GPIOMode_TypeDef;

在了解了以下知识点以后,针对LED管脚的配置,我们很快就能写出代码:

代码语言:javascript
复制
//1、定义GPIO初始化结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//2、初始化配置管脚
GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_8;
//3、初始化管脚速率
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//4、初始化管脚模式,配置为推挽输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//5、调用GPIO_Init完成IO的初始化
GPIO_Init(GPIOD, &GPIO_InitStructure);

6.3 GPIO_SetBits、GPIO_ResetBits

GPIO_SetBits和GPIO_ResetBits主要是对端口进行设置和清除,对应的是下面这个寄存器:

以下是两个函数的源代码:

代码语言:javascript
复制
/**
* @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;
}

根据功能描述,很容易可以写出下列代码:

代码语言:javascript
复制
//给GPIOD的第八位
GPIO_SetBits(GPIOD, GPIO_Pin_8); //PC8输出高电平,点亮LED
//清除GPIOD的第八位
GPIO_ResetBits(GPIOD, GPIO_Pin_8);//PD8输出低电平,熄灭LED

以下是该Demo的源代码:

代码语言:javascript
复制
/****************************************Copyright (c)****************************************************
**
**
**
**--------------File Info---------------------------------------------------------------------------------
** File name:			main.c
** modified Date:  		2017-6-20
** Last Version:		V0.1
** Descriptions:		  main 函数调用
**
** 好钜润科技,芯片事业部----深圳龙华应用分部
*********************************************************************************************************/
#include "HAL_conf.h"



/********************************************************************************************************
**函数信息 :int main (void)
**功能描述 :
**输入参数 :
**输出参数 :
********************************************************************************************************/

int main(void)
{
	uint32_t  i;
	GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO初始化结构体变量

	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

	//配置连接LED的GPIO为推挽输出模式
	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)//无限循环
	{
		GPIO_SetBits(GPIOD, GPIO_Pin_8); //PC8输出高电平,点亮LED
		for(i=0;i<2000000;i++);//延时
		
		GPIO_ResetBits(GPIOD, GPIO_Pin_8);//PD8输出低电平,熄灭LED
		for(i=0;i<2000000;i++);//延时
	}

}

7、TKM32F499程序编译与下载

7.1 程序编译

和STM32一样,程序编译直接点击Keil软件上的编译即可,如果程序没有错误则会生成对应的bin文件。

7.2 程序烧录

TK499 支持 U 盘方式下载,无需借助下载器,一根 USB 线就能下载。

方法一:五向按键向上推,同时按一下复位(注意,松手时,先松复位,再松五向按键),然后点一下 KEIL 的下载程序的按钮就可以下载了。KEIL 不会提示是否下载完成,听到退出 U 盘的“叮咚”声就可以了。下载完成一般可以自动运行,如果没运行,可以按一下复位或者断电再上电就可以运行。

方法二:向上推,同时按一下复位就会进入程序下载模式,同样的也会弹出一个 U 盘,把 KEIL 工程目录下生成的 bin 程序拖进 U 盘就行,如下图。

如果是芯片第一次使用,需要先烧录一个 Bootloader。方法是:把五向按键向左推,同时再按一下复位就进入了 Bootloader 下载模式(注意,松开按键时,先松复位,再松五向按键)。这时会弹出一个 TK499 的 U 盘,把开发包压缩包里的 TK499_Bootloader.bin拖进去就行。(一般情况下开发板已经是烧好 Bootloader,此步可省略)

Bootloader 是一个重要的文件,以后会不断升级 Bootloader,用它可以通过 USB下载图片及字库。

注意:2019.10.1 前发布的程序,一般没把 flash_download.exe 下载程序工具放进工程文件夹里,所以用不了方法一来下载。当然你要自己添加也是很容易的,把这个小工具放到工程目录下,然后复制下面两行命令进去就行。

代码语言:javascript
复制
flash_download
..//@L.bin TK499_V2

8、运行结果

LED以固定频率进行闪烁:

最后,感谢淘宝客服小姐姐多送了一块带触摸的开发板给我:

TKM32F499评估板例程及资料下载

代码语言:javascript
复制
链接:https://pan.baidu.com/s/1xujEO4vJ7i7UUK7v_fGNgw
提取码:g1y2
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Mculover666 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、特点
  • 2、开发平台
  • 3、TKM32F499芯片架构
  • 4、TKM32F499芯片管脚及排列说明
  • 5、TKM32F499存储器映射表
  • 6、TKM32F499测评程序编写步骤及程序解读
    • 6.1 RCC_AHBPeriphClockCmd
      • 6.2 GPIO_Init
        • 6.3 GPIO_SetBits、GPIO_ResetBits
        • 7、TKM32F499程序编译与下载
          • 7.1 程序编译
          • 7.2 程序烧录
          • 8、运行结果
          • TKM32F499评估板例程及资料下载
          相关产品与服务
          GPU 云服务器
          GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档