Keil使用与BSP库编程

本文详细介绍了使用KEIL软件与STC-ISP进行编程配置的方法,并通过多个实例展示了如何进行数码管显示、蜂鸣器控制、音乐播放等功能的编程实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

记录学习,仅供参考

编程前的配置工作

先把keil的文件夹加到STC-ISP中
在这里插入图片描述
在这里插入图片描述
然后可以在keil中建工程了
在这里插入图片描述
先新建一个文件夹放工程文件
在这里插入图片描述
输入工程的名字点击保存。
在这里插入图片描述
这里选择第二个
在这里插入图片描述
板子的型号选择正确,后面弹出来的选择是

在这里插入图片描述
现在工程就建好了,然后要加入必要的库文件。
在这里插入图片描述
点击这里
在这里插入图片描述

勾选生成hex文件

在这里插入图片描述
因为我们用C语言写代码,所以要加入相关的头文件。如图

这里要加的东西再学习通课程网站的资料里
在这里插入图片描述
下载解压好,上面图里要用到这个路径

在这里插入图片描述
这里如图选择好,一路点击确定。

在这里插入图片描述
这里新建一个文件。先保存,保存到新建工程的那个文件夹里。命名后缀要是.c

在这里插入图片描述
这里点开Target,右键点击Source Group 点击Manage

在这里插入图片描述
在这里插入图片描述
要加入刚保存的c文件和库文件,库文件在刚在课程网站下载的文件里面,里面的source里,选择全部文件类型才能看到库文件。记得只用点击一下add就行了,之后点close,OK。

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/d4b410a7de1047f88e4947c390358ce3.png在这里插入图片描述

可以看到都加进来了,现在准备工作就做好了,可以开始开心地写程序了。
每次建工程这些都要完成一遍,不是设置一编就好

写完之后点击这里编译
在这里插入图片描述

下面解决几道练习题

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "displayer.H" 
#include "sys.H"


code unsigned long SysClock=11059200L;        //必须。 (定义系统工作时钟频率,用户可以修改,且必须与实际工作频率(下载时选择的)一致

#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13*        /
                /* 显示:   0   1    2    3    4     5    6    7   8    9  (无)   下-  中-  上-       */  
#endif



void main()
{  				
	
	  displayerInit();                              
	LedPrint(0);
		SetDisplayerArea(0,6);                           
		Seg7Print(1,2,14,15,12,2,1);	 
	MySTC_Init();
	while(1)
		MySTC_OS();
}

在这里插入图片描述

#include "sys.H"
#include "STC15F2K60S2.H"
#include "beep.H"

code unsigned long SysClock=11059200L;        //必须。 (定义系统工作时钟频率,用户可以修改,且必须与实际工作频率(下载时选择的)一致
int main(){
	
	BeepInit();
	SetBeep(1200,180);
	MySTC_Init();
	while(1)
		MySTC_OS();
	
}

在这里插入图片描述

#include "sys.H"
#include "STC15F2K60S2.H"
#include "music.H"
#include "Beep.H"

#define uchar unsigned char
code unsigned long SysClock=11059200L;        //必须。 (定义系统工作时钟频率,用户可以修改,且必须与实际工作频率(下载时选择的)一致
code uchar arr[]={
	0x31,0x10,
	0x32,0x10,
	0x33,0x10,
	0x34,0x10,
	0x35,0x10};

int main(){	
	MusicPlayerInit();
	//SetMusic
	BeepInit();
	SetPlayerMode(enumModePlay);
	SetMusic(100,0xFA,arr,10,enumMscNull);
	MySTC_Init();
	while(1)
	MySTC_OS();
	
}

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "stepmotor.h"
#include "displayer.H"  
code unsigned long SysClock=11059200L; 
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13  14   15     */
                  /* 显示:   0   1    2    3    4   5    6    7   8    9     10    11   -     #   H    L     */  
#endif
int main(){
	StepMotorInit();
	DisplayerInit();  
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10);
	LedPrint(0);
	SetStepMotor(enumStepMotor2,10,100);
	MySTC_Init();
	while(1)
		MySTC_OS();
}

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "displayer.H"            
#include "key.H" 

code unsigned long SysClock=11059200L; 

#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13  14   15     */
                  /* 显示:   0   1    2    3    4   5    6    7   8    9     10    11   -     #   H    L     */  
#endif
char a=10;
void myKey_callback()
{ char k;
	k=GetKeyAct(enumKey1);
	if( k == enumKeyPress ) a=14;
	  else if( k == enumKeyRelease ) a=10;
}

void my10mS_callback(){
Seg7Print(10,10,10,10,10,10,10,a);}
void main(){
	DisplayerInit();   
	Key_Init(); 
	SetDisplayerArea(0,7);
	//if(GetKeyAct(enumKey1)==enumKeyPress)
	
	 LedPrint(0);
	SetEventCallBack(enumEventSys10mS, my10mS_callback);
	SetEventCallBack(enumEventKey, myKey_callback);
	MySTC_Init();
	while(1)
		MySTC_OS();
}

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "beep.H"   
#include "Vib.h"

code unsigned long SysClock=11059200L;


void mysv_callback()
{
	if(GetVibAct()==enumVibQuake)
		SetBeep(1200,100);
}


void main(){
	BeepInit();
	VibInit();
	
	SetEventCallBack(enumEventVib, mysv_callback);
	MySTC_Init();
	while(1)
		MySTC_OS();
}



在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "hall.H" 
#include "displayer.H" 

code unsigned long SysClock=11059200L;
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13  14   15     */
                  /* 显示:   0   1    2    3    4   5    6    7   8    9     10    11   -     #   H    L     */  
#endif

unsigned char ch=0x01;
char flag=0;
void my100mS_callback(){
	if(flag){
		if(ch<16) {
		LedPrint(ch);
		ch=ch<<1;	
		}
		else
		ch=0x01;
	}
}
void myhall(){
	if(GetHallAct()==enumHallGetClose)
		flag=1;
		else 
			flag=0;
		
}

void main(){
	DisplayerInit();  
	HallInit(); 
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10);
	LedPrint(0);
	SetEventCallBack(enumEventSys100mS, my100mS_callback);
	SetEventCallBack(enumEventHall, myhall);
	MySTC_Init();
	while(1)
		MySTC_OS();
}

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "adc.h"   
#include "displayer.H"
#include "key.H"

code unsigned long SysClock=11059200L;

#ifdef _displayer_H_                         		 //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13  14   15     */
                  /* 显示:   0   1    2    3    4   5    6    7   8    9     10    11   -     #   H    L     */  
#endif

unsigned char temp[]={0xc0,0x60,0x30,0x18,0x0c,0x06,0x03};  //用来保存灯的7种状态
int i=3;
void mydh_callback()
{
	if(GetAdcNavAct(enumAdcNavKeyLeft)==enumKeyPress)
	{
		if(i>0)
			i--;
	}
	else if(GetAdcNavAct(enumAdcNavKeyRight)==enumKeyPress)
	{
		if(i<6)
			i++;
	}
	LedPrint(temp[i]);
}


void main(){
	DisplayerInit();
	Key_Init();
	AdcInit(ADCexpEXT);
	SetDisplayerArea(0,7);
	LedPrint(temp[3]);
	Seg7Print(10,10,10,10,10,10,10,10);		//数码管什么也不显示
	SetEventCallBack(enumEventXADC, mydh_callback);
	MySTC_Init();
	while(1)
		MySTC_OS();
}


在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "displayer.H"  

code unsigned long SysClock=11059200L;
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x76,0x38};   
	              /* 序号:   0   1    2	   3    4   5    6	  7   8	   9	 10	   11	12   13  14   15     */
                  /* 显示:   0   1    2    3    4   5    6    7   8    9     10    11   -     #   H    L     */  
#endif
long ms=0,min=0,sec=0,temp=0;
char oput[8]={0};

void fun(){
	temp++;
	ms=temp;
	sec=(temp/1000)%60000;
	min=temp/60000;
	if(sec>59)
	sec=sec-60;
	oput[0]=ms%10;
	oput[1]=(ms/10)%10;
	oput[2]=(ms/100)%10;
	oput[3]=12;
	oput[4]=sec%10;
	oput[5]=(sec/10)%10;
	oput[6]=12;
	oput[7]=min;
	Seg7Print(oput[7],oput[6],oput[5],oput[4],oput[3],oput[2],oput[1],oput[0]);
}

int main(){
	DisplayerInit(); 	
	SetDisplayerArea(0,7);
	Seg7Print(1,1,1,1,1,1,1,1);
	LedPrint(0);
	SetEventCallBack(enumEventSys1mS, fun);
	MySTC_Init();
	while(1)
		MySTC_OS();
}

在这里插入图片描述

#include "STC15F2K60S2.H"
#include "sys.H"
#include "adc.h"
#include "beep.h"
code unsigned long SysClock=11059200L;

void Rop_callback(){
	if(GetADC().Rop<20)
		SetBeep(1200,150);
	else if(GetADC().Rop>100)
		SetBeep(2000,150);
}

int main(){
	BeepInit();
	AdcInit(); 
	SetEventCallBack(enumEventXADC, Rop_callback);
MySTC_Init();
while(1)
MySTC_OS();	
}

后记

本人测试问题不大,仅供参考,如果代码出错欢迎评论区交流

<think>嗯,用户想了解KeilBSP的相关概念和配置方法。首先,我需要回忆一下BSP是什么。BSP是板级支持包,主要负责硬件抽象,让操作系统或应用程序能更容易地访问硬件资源。在Keil MDK环境下,BSP通常包含启动文件、外设驱动、时钟配置等。 接下来,用户可能需要具体的配置步骤。根据引用内容,Keil的工程创建和配置涉及项目目录结构、启动文件、配置文件等[^2]。比如,新建工程时需要选择正确的目录和芯片型号[^4],这可能和BSP配置有关。另外,引用中提到RA Smart Configurator的设置方法[^3],可能涉及到外设的图形化配置工具,这可能也是BSP配置的一部分。 用户可能还希望知道如何利用现有的BSP或者如何自定义BSP。需要提到如何添加启动文件、配置系统时钟、初始化外设驱动等步骤,这些通常在BSP中完成。例如,启动文件startup_stm32f4xx.s属于BSP的一部分,负责初始化堆栈和中断向量表[^2]。 另外,引用[1]提到以STM32F4固件创建工程模板,这可能涉及到复制文件到项目目录,配置头文件路径等,这些都是BSP配置的基础步骤。需要分步骤说明如何搭建开发环境,添加必要的驱动文件,配置编译器选项等。 还要考虑用户可能遇到的问题,比如如何解决外设配置错误,或者如何优化BSP以适应特定硬件。可能需要提到调试技巧,比如使用Keil的调试器检查外设寄存器状态,或者参考ST的官方文档进行配置。 最后,生成相关问题时,要考虑用户可能的后续疑问,比如BSP和HAL的区别,或者如何移植BSP到不同芯片。这些问题可以帮助用户更深入理解BSP的应用和调整方法。</think>### KeilBSP的概念配置方法 #### 一、BSP(板级支持包)概念 BSP(Board Support Package)是介于硬件和操作系统(或应用程序)之间的中间层,主要用于抽象硬件细节,提供统一的接口驱动。在Keil MDK开发环境中,BSP通常包含以下内容: 1. **启动文件**(如`startup_stm32f4xx.s`):负责初始化堆栈、中断向量表等底层配置。 2. **外设驱动**(如GPIO、UART、ADC):封装硬件操作函数。 3. **时钟配置**:定义系统时钟源(如使用HSE或HSI)及分频系数。 4. **链接脚本**(`.sct`文件):指定内存布局(Flash、RAM地址范围)[^2]。 #### 二、BSP配置步骤(以STM32为例) 1. **创建工程模板**: - 通过`Project -> New uVision Project`新建工程,选择芯片型号(如STM32F407)。 - 添加启动文件(位于固件的`Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/arm`目录)[^1]。 2. **配置外设驱动**: - 在工程中引入外设文件(如`stm32f4xx_gpio.c`、`stm32f4xx_rcc.c`)。 - 通过`Manage Run-Time Environment`(RTE)勾选所需外设支持(如GPIO、USART)。 3. **时钟初始化**: - 修改`system_stm32f4xx.c`中的`SystemInit()`函数,配置PLL参数。 ```c #define PLL_M 8 #define PLL_N 336 #define PLL_P 2 // 主时钟输出频率 = (HSE * PLL_N)/(PLL_M * PLL_P) ``` 4. **使用RA Smart Configurator(可选)**: - 通过图形化界面配置引脚功能、时钟树等。 - 生成的代码自动集成到Keil工程中。 #### 三、调试验证 1. **编译配置**: - 在`Options for Target -> C/C++`中定义宏(如`USE_HSE`)和头文件路径。 2. **烧录调试**: - 使用ST-LINK或J-Link连接开发板。 - 通过`Debug -> Start/Stop Debug Session`进入调试模式,查看外设寄存器状态。 #### 四、常见问题 - **时钟配置错误**:若系统时钟未生效,检查`SystemCoreClock`变量是否更新。 - **外设无法工作**:确认外设时钟已使能(如`RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE)`)。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值