Keil(For STM32) 安装,配置,工程创建,下载,调试

Update Record

VersionDateAuthorDescription
1.0.02019-07-12WintrueCreate

1 Install&Configuration

1.1 Package

官网 https://www.keil.com/download/product/ 提供了MDK-Arm免费下载
作者这里使用了5.23版本的MDK。

1.2 Install

双击安装包,进行安装前的准备,遇到下图选择同意。
双击安装包,进行安装前的准备,遇到下图选择同意。
安装路径选择,作者直接默认全部安装在C盘。
在这里插入图片描述
客户信息只需格式正确即可。
在这里插入图片描述
安装过程中,会自动请求安装一些驱动,若在不知该驱动为什么服务的话,一律选择安装即可。
在这里插入图片描述在这里插入图片描述
安装完成则会弹出下面界面,不用选择Show Release Notes,直接Finish。
在这里插入图片描述

1.3 License 安装

打开keil—>File —>License Management进行license安装,复制CID,使用CID得到LIC 填入LIC,点击Add LIC,关闭窗口。
在这里插入图片描述
第一次打开keil,会弹出设备包安装工具(若没弹出看下一步),点击OK,该工具在线安装需要等待片刻,左边会加载完整安装目录。
在这里插入图片描述
如果无意关了该界面或者未弹出,可以在直接打开keil,点击如下指示的图标。
在这里插入图片描述
加载完毕后选择我们需要的芯片(这里为STMicroelectronics —>STM32F1 Series—>STM32F103 —>STM32F103RB)。然后找到DFP文件进行安装(这里为STM32F1xxDFP)
在这里插入图片描述在这里插入图片描述
至此安装过程完毕,打开keil。

在这里插入图片描述

2 Start a New Project

2.1 New Project

进入keil后如下所示。
在这里插入图片描述
开始新建一个工层,打开project —>New uVersion Project。
在这里插入图片描述
选择合适的文件夹保存工程,注意新建工程不会新建根目录,该文件夹会被完全占用。

在这里插入图片描述
保存后,选择芯片

在这里插入图片描述
OK之后会出现库配置,在这里选择的话,既不用配置复杂的启动文件,分组,头文件,宏定义等,而且功能十分强大,包含了大量的库文件,而且还有依赖校验功能帮助使用者选择合适的库文件。

在这里插入图片描述
如下,为一个一个简单的模板工程配置了必须的CMSIS中的CORE,Device中的Startup和StdPeriph Drivers文件夹下的所有文件,这些库文件在工程进行中也可以更改,也可以在工程完成后去掉不必要的库,节省Flash空间。

在这里插入图片描述
加入好库文件的工程如下

在这里插入图片描述
然后把我们自己的,工程必须的main.c文件加入进去。首先新建一个空白main.c文件。

在这里插入图片描述
保存在项目文件夹下一个合适的地方(作者保存在了工程根目录下)。

在这里插入图片描述
然后还需要将main.c 文件加入到工程,直接右击Target选择Manage Project items…,进入管理界面

在这里插入图片描述
如下为管理界面,其中三个栏目下的内容皆可自由编辑。

在这里插入图片描述
我们把main.c添加到Target 1的Source Group 1中,直接点击Add Files。


添加进去后,如下所示。需要注意的是,以后添加进工程的任何c文件皆需要这一步来添加进来,多的话可以在Group栏目下多分几个组。而头文件只需要加入路径即可,操作方法在后面会提及。

在这里插入图片描述然后,工程还需要一些配置。如下点击该图标进入配置界面。

在这里插入图片描述
首先,将Target栏中的晶振频率改为8.0MHz。

在这里插入图片描述

然后在Output栏下,点击上面框中按钮可以配置编译生成的文件存放于何处,可以不用配置,勾选生成HEX文件,此文件可以使用各种通用烧录软件给芯片下载程序。在此教程中不涉及该文件的使用。

在这里插入图片描述
可以看到生成目标文件的文件夹默认在根目录的Objects文件夹下。

在这里插入图片描述
然后,进行调试和烧录的配置,我们使用的调试工具为ST-LINK V2,在Debug栏下选择如下。

在这里插入图片描述
Utilities栏下可以选择烧录方式,我们可以不用配置其他工具,直接使用keil就好。配置如下。

在这里插入图片描述
然后进入如下所示的Settings(和Utilities栏中的是相同的)

在这里插入图片描述
确认调试工具是否正常,如下为连接正常,不同调试工具的序列号可能不一样,Port一定要选择SW,MAX不能选择太大。

在这里插入图片描述
接着进入另一个选项页,记得勾选Reset and Run。这样下载后会自动开始运行程序。

在这里插入图片描述
其他可以使用默认配置,如果有需要则按需要进入再配置。另外,新添加的头文件需要在C/C++一栏下添加路径。

在这里插入图片描述
如下建立并选择路径。整个项目的宏定义也在C/C++一栏下添加,

在这里插入图片描述

2.2 Build Project

在刚才建立的main.c中添加以下内容:

#include "stm32f10x_gpio.h"
void delay(vu32 nCount)
{
  vu32 index = 0; 
  for(index = (34000 * nCount); index != 0; index--)
  {
  }
}
void GPIOB_Set(uint16_t pin){
	GPIO_InitTypeDef  GPIO_InitStructure;
  /* Enable the GPIO Clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
  /* Configure the GPIO pin */
  GPIO_InitStructure.GPIO_Pin = pin;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
int main(void){
	GPIOB_Set(GPIO_Pin_0);
	while(1){
	GPIO_SetBits(GPIOB, GPIO_Pin_0);
	delay(300);
	GPIO_ResetBits(GPIOB, GPIO_Pin_0);
	delay(100);
	}
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

该文件的作用是让开发板的测试灯[PB0]一长一短的进行闪烁,启动部分代码在工程建立的时候就已经配置了(Startup中的汇编文件),程序开始的地方并不是main函数,而是启动文件,启动好后程序的入口才开始转入main函数。

保存后,点击build 图标或者选择project —> build,如果已经build过了,可以选择rebuild
在这里插入图片描述
如果出现如下信息,则说明编译链接均正常无误,可以进行下一步。

在这里插入图片描述

3 Debug&Flash

3.1 Debug

如下所示,点击该按钮进入调试模式,退出时同样点击该按钮。

在这里插入图片描述
如下图所示,keil自带的调试工具具有强大的功能,可以进行单步调试,同步汇编,断点设置,数据观察窗,逻辑分析,输出波形等等。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
需要注意的是,同步调试一般不会将程序烧录给芯片,这与BOOT设置也有关。

3.2 Flash

烧录时,点击如下所示按钮即可

在这里插入图片描述
出现如下所示信息说明程序烧录成功,需要注意的是如果没设置烧录完毕重启的话,需要手动按下开关重启以后生效。

在这里插入图片描述

4 Example

4.1 Usart

STM32F103有三个USART外设,下面以USART1为例,进行配置:

#define USART1_GPIO 			GPIOA
#define USART1_TX 				GPIO_Pin_9
#define USART1_RX 				GPIO_Pin_10
#define USART1_GPIO_CLK 	RCC_APB2Periph_GPIOA
#define USART1_PORT_CLK 	RCC_APB2Periph_USART1
void USART1_Init(void){
USART_InitTypeDef USART_InitStructure;//usart配置结构体
GPIO_InitTypeDef GPIO_InitStructure;// usart所需引脚配置
  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(USART1_GPIO_CLK, ENABLE);
  /* Configure USART Tx as alternate function push-pull */
  //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = USART1_TX;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(USART1_GPIO, &GPIO_InitStructure);
  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = USART1_RX;
  GPIO_Init(USART1_GPIO, &GPIO_InitStructure);
	
	  /* Enable UART clock */
  RCC_APB2PeriphClockCmd(USART1_PORT_CLK, ENABLE); 
	USART_InitStructure.USART_BaudRate = 115200;
  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 configuration */
  USART_Init(USART1, &USART_InitStructure); 
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);							//开启接收中断
	//USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);		
  /* Enable USART */
  USART_Cmd(USART1, ENABLE);
}

通过下面的程序,可以将USART1的数据发送映射到printf函数

#include <stdio.h>
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
	struct __FILE
{
	int a;
};
 
FILE __stdout;
void _sys_exit(int x)
{	
}
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}
  return ch;
}

调用如下:

#include <stdio.h>
int main(){
printf("\n\rUSART Printf Example: retarget the C library printf function to the USART\n\r");
return 0;
}

结果如下:
在这里插入图片描述
实际应用中我们需要非阻塞的接收串口数据,此处我们借助了其接收中断。
代码如下:

#define RXBUF2_MAX 256 //定义为256时,uint8_t不用判断是否溢出,自动从0开始
char RxUBuf1[RXBUF1_MAX];	
static uint8_t Num_U1RxByte = 0;	
static uint8_t U1RxF = 0;
static uint8_t U1RxL = 0;

char USART1_ReadByte(void){
	if(Num_U1RxByte == 0) return '\0';	
	Num_U1RxByte--;
	return RxUBuf1[U1RxF++];
}
uint8_t USART1_RecNum(void){
		return Num_U1RxByte;
}

char USART1_SendChar(char ch){
	  USART_SendData(USART1, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
  {}
  return ch;
}

void USART1_IRQHandler(void){
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)		//判断是否为接收中断
	{
		RxUBuf1[U1RxL++] = USART_ReceiveData(USART1);				  //读取接收到的字节数据
		if(Num_U1RxByte < 255)Num_U1RxByte++;
		else{
			U1RxF++; //当buffer满了丢弃最先收到的1个数据
		}
	}
}

使用示例:

int main(void){
	int i = 0;
	GPIO_Conf(LED_PORT,LED0_PIN|LED1_PIN);
	USART1_Init();
	while(1){
	GPIO_SetBits(LED_PORT, LED0_PIN);
	GPIO_ResetBits(LED_PORT, LED1_PIN);
	delay(30);
	GPIO_SetBits(LED_PORT, LED1_PIN);
	GPIO_ResetBits(LED_PORT, LED0_PIN);
	delay(10);
	i = USART1_RecNum();
	while(i--){
		USART1_SendChar(USART1_ReadByte());
	}
	}
return 0}

结果如下:

在这里插入图片描述
以同样的方式配置USART2,用下面的程序则可以直接通过串口调试助手跟NB-IoT模组进行通信。

int main(void){
	int i = 0;
	GPIO_Conf(LED_PORT,LED0_PIN|LED1_PIN);
	USART1_Init();
	USART2_Init();
	NVIC_Config();
	while(1){
	GPIO_SetBits(LED_PORT, LED0_PIN);
	GPIO_ResetBits(LED_PORT, LED1_PIN);
	delay(30);
	GPIO_SetBits(LED_PORT, LED1_PIN);
	GPIO_ResetBits(LED_PORT, LED0_PIN);
	delay(10);
	i = USART1_RecNum();
	while(i--){
		USART2_SendChar(USART1_ReadByte());
	}
	
	i = USART2_RecNum();
	while(i--){
		USART1_SendChar(USART2_ReadByte());
	}
	}
}

与NB-IoT模组通信结果如下所示:
在这里插入图片描述
完整的测试工程代码见:https://github.com/Magelgit/KeilforSTMF103RB

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Version: 2.15.0 (2020-09-28) Keil.STM32F4xx_DFP.2.15.0.pack Download Updated Pack to STM32Cube_FW_F4 Firmware Package version V1.25.1 using HAL Drivers V1.7.9. STM32CubeMX integration (Version 6.0.1): Added support for Timebase Source TIMx (FrameworkCubeMX_gpdsc.ftl). Removed non-existent include path. CMSIS Flash Algorithm: Corrected STM32F42xxx_43xxx_OPT Algorithm. CMSIS SVD: Updated STM32F42*.svd, STM32F43*.svd files. CMSIS-Driver: I2C: Corrected 2 byte reception in master mode. MCI: Replaced empty delay loops with _NOP(). SPI: Corrected PowerControl function (to return error if Initialize was not called, to abort active transfer if power off was requested). Updated GetDataCount function to give accurate count in DMA mode. Corrected Control function (abort in DMA mode, software controlled slave select in slave mode, TI Frame Format selection, ignore bus speed for slave mode). Corrected Uninitialize function (to power off the peripheral if it is powered). Corrected SPI3_SCK pin configuration. Corrected DMA MemDataAlignment configuration. USART: Corrected DMA MemDataAlignment configuration. USBD_HS/USBH_HS: OTG_HS ULPI clock disabled in low power if internal PHY is used to enable proper operation of OTG_HS port in FS mode during CPU sleep. CAN/EMAC/USBD/USBH: Removed macros already provided by cmsis_compiler.h. Updated Boards Examples: Migrated CubeMX projects to V6.0.1 and updated config files. Changed variant selection to "MDK-Plus" where possible. Updated all USB Host/Device examples with user templates from MDK-Middleware v7.11.1. Terminating app_main thread with osThreadExit() to avoid endless loop Updated MS Windows UBS driver files.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值