基于STM32H743的调试记录2——使用VScode开发环境点亮LED

使用VScode开发环境点亮LED

1.搭建VScode的STM32开发环境
(1)下载安装 VScode,官网地址:
自行安装,网上教程丰富!
(2)在VScode商店中安装chinses简体中文插件,Embedded IDE插件及所需的工作环境插件 C/C++ 、C/C++ Extension Pack、C/C++ Themes
(3)打开Embedded IDE :官方论坛链接
设置工具链 指定 Keil C51和Keil MDK的路径,及自己安装的Keil路径。我安装了两个软件在同一路径下(可以同时开发两种内核的MCU)所以指定两次。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如截图工具链设置成功后面会出现对号。

2.导入项目
在这里插入图片描述
选择MDK选项,导入之前建立的工程模板在这里插入图片描述
根据提示选择信任及工作平台,即可加载文件完成,如下图:选择编译器及内核在这里插入图片描述
打开main.c文件单击右上角 构建图标(F7)或工程列表区域构建图标,进行编译。在这里插入图片描述
下方终端提示如下信息编译完成。在这里插入图片描述

  1. 点亮LED灯
    在HARDWARE文件夹中添加LED.C文件
    EIDE项目栏——项目属性——包含目录中单击+添加LED.H的文件路径。在这里插入图片描述
    主函数部分如下:
#include "sys.h"
#include "delay.h"
#include "led.h"


int main(void)
{
    Cache_Enable();                 //打开L1-Cache
    HAL_Init();				        //初始化HAL库
	Stm32_Clock_Init(160,5,2,4);    //设置时钟,400Mhz 
	delay_init(400);
    LED_Init();
    while(1)
    {
		delay_ms(500); //延时500ms
        LED1_Toggle; //翻转LED电平
    }
}

Cache_Enable(); //打开L1-Cache
开启功能

//使能CPU的L1-Cache
void Cache_Enable(void)
{
	//MPU_Config();
    SCB_EnableICache();//使能I-Cache
    SCB_EnableDCache();//使能D-Cache   
	SCB->CACR|=1<<2;   //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题	
}

Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz 重新设定系统时钟 为400Mhz
在led.c文件中
定义输出的引脚

#include "led.h"
 			    
//LED IO初始化
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOC_CLK_ENABLE();					//开启GPIOC时钟
    __HAL_RCC_GPIOH_CLK_ENABLE();					//开启GPIOC时钟
    GPIO_Initure.Pin=GPIO_PIN_9;			//PC9
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  		//推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;         			//上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;  	//高速
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);     		//初始化GPIOC9
	
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET);	//PC9置1 

    GPIO_Initure.Pin=GPIO_PIN_12;			//PC9
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  		//推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;         			//上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;  	//高速
    HAL_GPIO_Init(GPIOH,&GPIO_Initure);     		//初始化GPIOB.0和GPIOB.1
    HAL_GPIO_WritePin(GPIOH,GPIO_PIN_12,GPIO_PIN_RESET);	//PB1置1 
}

GPIO_InitTypeDef GPIO_Initure; 为GPIO结构体句柄;
使用外设之前应对外设的时钟进行使能,HAL库定义了完整的时钟函数:__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
对于H7系列的GPIO具有8种工作模式,可以详见H7系列参考手册:一般输出功能可以选择具有上拉功能的推挽输出。在这里插入图片描述

#define LED1(n)		(n?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET))
#define LED1_Toggle (HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9)) //LED1输出电平翻转

H7系列不支持位带操作,定义LED1(n) 使用三目运算对单一引脚进行赋值,本质是调用HAL库的void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)函数;
同时HAL库还提供了电平翻转函数oid HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
编译工程 提示没有错误即可下载!
EIDE 支持多种下载工具:烧录配置:——选择自己的下载工具
在这里插入图片描述
1JLink: 打开插件设置指定JLink安装路径;在这里插入图片描述

配置芯片型号、接口类型、下载速度。
在这里插入图片描述
2.STLink:指定ST-LINK Utility软件安装路径:在这里插入图片描述
3OpenOCD:指定OpenOCD的安装路径:
在这里插入图片描述
芯片配置;工具链;
在这里插入图片描述
4.下载程序验证
点击 烧录按键在这里插入图片描述下载程序。

使用定时器控制LED频闪

STM32H7系列单片机设计有基本定时器 TIM6、TIM7。基本定时器 TIM6 和 TIM7 包含一个 16 位自动重载计数器,该计数器由可编程预分频器驱动。此类定时器不仅可用作通用定时器以生成时基,还可以专门用于驱动数模转换器 (DAC)。实际上,此类定时器内部连接到 DAC 并能够通过其触发输出驱动 DAC。这些定时器彼此完全独立,不共享任何资源。
首先要明白STM32H7系列的时钟架构:可以参考STM32H7新版系统框图
查询数据总线结构,我们发现 TIM6挂在APB1的总线上,在看时钟系统、在系统主频率为400MHz的情况下APB1总线的定时器时钟为200MHz。
在这里插入图片描述
在这里插入图片描述
由此可以配置定时周期为10ms的工作模式。

#include "timer.h"
#include "led.h"

TIM_HandleTypeDef TIM6_Handler;      //定时器句柄 

//基本定时器6中断初始化,定时器6在APB1上,APB1的定时器时钟为200MHz
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器6!(定时器6挂在APB1上,时钟为HCLK/2)
void TIM6_Init(u16 arr,u16 psc)
{  
    TIM6_Handler.Instance=TIM6;                          //定时器6
    TIM6_Handler.Init.Prescaler=psc;                     //分频
    TIM6_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIM6_Handler.Init.Period=arr;                        //自动装载值
    TIM6_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
    HAL_TIM_Base_Init(&TIM6_Handler);
    
    HAL_TIM_Base_Start_IT(&TIM6_Handler); //使能定时器6和定时器6更新中断:TIM_IT_UPDATE    
}

//定时器底册驱动,开启时钟,设置中断优先级
//此函数会被HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM6)
	{
		__HAL_RCC_TIM6_CLK_ENABLE();            //使能TIM6时钟
		HAL_NVIC_SetPriority(TIM6_DAC_IRQn,15,0);    //设置中断优先级,抢占优先级15,子优先级0
		HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);          //开启ITM6中断   
	}  
}

//定时器6中断服务函数
void TIM6_DAC_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM6_Handler);
}


#include "sys.h"
#include "delay.h"
#include "led.h"
#include "timer.h"

int main(void)
{
    Cache_Enable();                 //打开L1-Cache
    HAL_Init();				        //初始化HAL库
	Stm32_Clock_Init(160,5,2,4);    //设置时钟,400Mhz 
	delay_init(400);
    LED_Init();
    TIM6_Init(100-1,20000-1);    //定时器时钟 200M 分频系数 2000-1; 200M-20000=10k  自动重装载 100-1  定时周期 10ms  1/10k*100= 10ms
    while(1)
    {
      
    }
}

u8 timer_flags=0;

//定时器中断服务回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   if(htim->Instance==TIM6)
   {
      timer_flags++;
      if(timer_flags==50)
      {
        LED1_Toggle;        //LED1反转
        timer_flags=0;
      }
      
   }
    
}

HAL_NVIC_SetPriority(TIM6_DAC_IRQn,15,0); //设置中断优先级,抢占优先级15,子优先级0
中断优先级的设定。
在 HAL_Init(void);函数中设定 4 位抢占优先级, 0 位响应优先级
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
IP[240]:全称是: Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄
存器组相当重要! STM32H743 的中断分组与这个寄存器组密切相关。 IP 寄存器组由 240 个 8bit
的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。 而 STM32H743
只用到了其中的 150 个。 IP[149]~IP[0]分别对应中断 149~0。 而每个可屏蔽中断占用的 8bit 并没
有全部使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,
子优先级在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
这里简单介绍一下 STM32H743 的中断分组: STM32H743 将中断分为 5 个组,组 0~4。该
分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。

AIRCR[10: 8]bit[7: 4]分配情况分配结果
01110: 40 位抢占优先级, 4 位响应优先级
11101: 31 位抢占优先级, 3 位响应优先级
21012: 22 位抢占优先级, 2 位响应优先级
31003: 13 位抢占优先级, 1 位响应优先级
40114: 04 位抢占优先级, 0 位响应优先级

通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系, 例如组设置为 3,那么此时所有的 108 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断, 你可以设置抢占优先级为 0~7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

void TIM6_DAC_IRQHandler(void) 是TIM6的中断服务函数可以在startup_stm32h743xx.s文件中的中断向量表中找到。
在这里插入图片描述

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 是HAL库封装的特点,所有的定时器中断程序都可以通过
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);函数对其调用 因此所有的逻辑程序都可以在里面进行执行;
本文 执行500ms 对LED的状态改变一次。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值