从零开始的STM32F1课程学习(STM32CubeMX)

新学期新气象,新学期我们要学32了,之前虽然学了一点点,但是学的都不是很系统,这里终于能系统的学习一下32了,从原理角度进行一下学习。

文章目录

我的基本配置:STM32CubeMX、Jlink、STM32F103RCT6 MINI

STM32MINI就是我们学校上课用的32
在这里插入图片描述

第一节课

嵌入式就是在单片机上跑操作系统
在这里插入图片描述
在这里插入图片描述
STM32芯片内部
在这里插入图片描述
这是STM32的命名规则
在这里插入图片描述
在这里插入图片描述
时钟最高72M

在这里插入图片描述
PIN to PIN兼容是指两款芯片的引脚数目一样,功能一样,大小也一样

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过修改BOOT0和BOOT1的方式来修改32的启动方式,利用跳线帽改这个
在这里插入图片描述
将2,4等引脚短接来修改其启动方式

在这里插入图片描述
在这里插入图片描述

第一节课课后练习:点灯

灯的连线
在这里插入图片描述

1.配置好Cube的Project Manager

路径和工程名称设置
在这里插入图片描述
Code Generator设置
在这里插入图片描述

2.时钟树设置

都改成最高的
在这里插入图片描述

3.RCC设置

在这里插入图片描述

4.Debug模式设置

在这里插入图片描述

5.LED0引脚设置

设置为GPIO_Output
在这里插入图片描述

6.生成代码

在这里插入图片描述

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA8 */
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

下面是标准库的配置

void LED_Init(void)
{
 GPIO_InitTypeDef GPIO_InitTypeStrucre;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 
 GPIO_InitTypeStrucre.GPIO_Mode=GPIO_Mode_Out_PP;
 GPIO_InitTypeStrucre.GPIO_Pin=GPIO_Pin_8 ;
 GPIO_InitTypeStrucre.GPIO_Speed=GPIO_Speed_50MHz;

 GPIO_Init(GPIOA,&GPIO_InitTypeStrucre); 
 GPIO_SetBits(GPIOA,GPIO_Pin_8 );
}
7.在主函数while中写出灯的亮灭

HAL_Delay(1)实际延时时间多于1ms一点

/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(300);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
		HAL_Delay(300);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
8.配置Jlink

在这里插入图片描述

9.检测芯片

注意:要先给芯片上电,再连接Jlink
在这里插入图片描述

10.编译后下载

在这里插入图片描述

第二节课

什么是看门狗?

是一个定时器,将里面的数值加到一定数值之后,会被复位

所以在程序中每隔多少秒要把看门狗复位

看门狗主要用于无人看管的程序,防止程序跑飞了

GPIO:General Purpose Input Output,通用输入输出
输出三种:1.推挽2.开漏3.关闭
在这里插入图片描述

第二节课课后练习:按键控制灯的亮灭

1.配置好基础配置,和上面前4步一样
2.启用按键和LED的引脚

在这里插入图片描述

3.配置好GPIO

KEY0采用上拉模式和输入模式
我一般习惯把名字起的和原理图一模一样,这样代码读起来方便
在这里插入图片描述

4.在while中写出按键检测
  while (1)
  {
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
		{	
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
			{	
				HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
				while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET);
			}
		}
    /* USER CODE END WHILE */
  }
5.编译后下载成功

下载后要先按一下Reset才能成功执行

第三节课

第三节课课后练习:外部中断控制灯

1.配置好基础配置,和第一节课4步一样

在这里插入图片描述
在这里插入图片描述

2.配置按键的GPIO模式

在这里插入图片描述

3.在主函数中让程序执行LED0的亮灭

让LED0闪烁,LED1灭

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_Delay(300);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
		HAL_Delay(300);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  }
4. 在stm32f1xx_hal_gpio.c中找到中断回调函数

如果按下按键,则LED1亮,表示进入外部中断

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
	if(GPIO_Pin==GPIO_PIN_1)
  {
  
    if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)==0)
    {
     HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
    }
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
  }
}

5.编译后成功下载

第四节课

第四节课系统学习了外部中断

第四节课课后练习:在while(1)中执行灯的同步闪烁,按下KEY0按键,灯闪烁加快20次,按下WKUP,灯交替闪烁20次,KEY0的优先级更高

1.配置好基础配置
2.配置按键的GPIO

在CUBE中都设置为GPIO_EXTI模式
在这里插入图片描述
因为KEY0接地,我们配置成上拉模式
在这里插入图片描述
同理,配置WKUP
在这里插入图片描述

3.在NVIC中配置中断优先级

数字越小,优先级越高
在这里插入图片描述

4.配置两个灯为推挽输出

在这里插入图片描述

5.在while(1)中写出同步闪烁
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
		delay_ms(500);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
		delay_ms(500);
  }
  /* USER CODE END 3 */

delay_ms

//毫秒延时
void delay_ms(uint16_t nms)
{
 uint32_t temp;
 SysTick->LOAD = 9000*nms;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}
6.在stm32f10x_hal_gpio.c中写中断回调函数
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	

  
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */

		if(GPIO_Pin==GPIO_PIN_1)
  {
  
    if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)==0)
    {
			for(int i=0;i<20;i++)
				{	
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
			delay_ms(200);
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
			delay_ms(200);
			
				}
			}
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
	}
		if(GPIO_Pin==GPIO_PIN_0)
  {
  
    if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)
    {
			for(int i=0;i<20;i++)
				{	
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET);
			delay_ms(200);
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET);
			delay_ms(200);
				}
		}
		__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
	}
	
}
7.编译成功后下载

在这个作业中不要将按键设置成浮空,浮空状态会有点问题,要根据引脚设置成需要的状态

第五节课

  • 高级定时器 TIM1 TIM8 在APB1上
  • 通用定时器 TIM2 TIM3 TIM4 TIM5 在APB2上
  • 基本定时器 TIM6 TIM7 在APB1上

在这里插入图片描述
周期表
p n u m 1 K M G T
更新事件Update event(UE)
可以把CNT清零
在这里插入图片描述

定时器时间t=1/Tout

如果使能影子寄存器,影子寄存器会在更新事件发生时,将内部数值更新到ARR

ARR是计算时间间隔所以要加1
因为PSC不能为0,所以要加上1
在这里插入图片描述

第五节课课后练习:定时器实现灯的500ms间隔闪烁,和另一个灯的700ms闪烁

1.配置好基础配置
2.打开TIM2和TIM3

在这里插入图片描述
arr和psc的计算过程

(4999+1)*(7199+1)=36000000
72000000/36000000=2
1/2=0.5s=500ms

在这里插入图片描述

3.在NVIC中设置优先级

在这里插入图片描述

4.设置灯为推挽输出

在这里插入图片描述

5.打开定时器中断

main.c

/* USER CODE BEGIN PV */
static int i=0;
/* USER CODE END PV */
  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_Base_Start_IT(&htim3);
  /* USER CODE END 2 */

在stm32f10x_hal_tim.c中找到中断回调函数,在main.c中重定义

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim==&htim2)
  {
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_8);//对GPIO口的电平进行反转(低-高,高—低)
  }
	if(htim==&htim3)
  {
		if(++i>=700)
		{
		i=0;
    HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_2);//对GPIO口的电平进行反转(低-高,高—低)
		}
  }
	
6.编译后成功下载

第六节课

第六节课课后练习:通过两个按键利用PWM控制灯的亮灭

1.配置好基础配置
2.打开TIM1_CH1

在这里插入图片描述

2.在NVIC中打开中断

在这里插入图片描述

3.设置两个按键的GPIO

在这里插入图片描述

4.写出按键检测代码和启动PWM
/* USER CODE BEGIN 1 */
	int i=500;
  /* USER CODE END 1 */
  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);  // 使能PWM输出
  /* USER CODE END 2 */
    /* USER CODE BEGIN 3 */
		if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)==GPIO_PIN_RESET)
		{	
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)==GPIO_PIN_RESET)
			{	
				i=i+1;
				htim1.Instance->CCR1 = i; 
				HAL_Delay(1);
				while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)==GPIO_PIN_RESET);
			}
		}
		if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET)
		{	
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET)
			{	
				i=i-1;
				htim1.Instance->CCR1 = i; 
				HAL_Delay(1);
				while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET);
			}
		}
  }
  /* USER CODE END 3 */
5.编译后下载

第七节课

第七节课课后作业:串口的收发回显测试

1.配置好基础配置
2.打开串口

设置异步模式和打开中断
在这里插入图片描述

3.在main.c中添加fputc fgetc
/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}
4.主函数代码

定义了一个字符串

/* USER CODE BEGIN 1 */
	char str[10];
  /* USER CODE END 1 */

因为scanf在单片机中并不是阻塞式接收,所以我们要将其改为阻塞式的

/* USER CODE BEGIN 3 */
			printf("测试发送\n");
			HAL_Delay(100);
			 str[0]=0;
		  while(str[0] == 0)
		  	{
			scanf("%s",str);
				}//使其变成手动的阻塞式接收
			HAL_Delay(1000);
			printf("output:%s\n",str);
5.编译下载

可以发送也可以接收
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
此软件包中提供的 HAL(硬件抽象层)驱动程序支持 以下STM32F100xx STM32F101xx,STM32F102xx,STM32F103xx ,STM32F105xx 和STM32F107xx系列。 STM32CubeF1固件包附带一个更新程序实用程序STM32CubeUpdater,可配置为自动或按需检查新固件包更新(新版本或/和补丁)。 要快速入门STM32CubeF1固件包,请参阅UM1847,您可以从www.st.com/stm32cube下载固件更新和所有最新文档。 下面 链接到最有用的文档 最新版本 的STM32CubeF1固件包。 UM1847:STM32F1系列STM32CubeF1入门。 UM1853:STM32CubeF1 Nucleo演示固件。 UM1850:STM32F1xx HAL驱动程序的说明。 UM1734:STM32Cube USB设备库。 UM1720:STM32Cube USB主机库。 UM1721:使用FatF在STM32Cube上开发应用程序。 UM1722:使用RTOS在STM32Cube上开发应用程序。 UM1713:使用LwIP TCP / IP堆栈在STM32Cube上开发应用程序。 UM1709:STM32Cube以太网IAP示例。 更新历史记录 V1.7.0 / 09-October-2018 主要变化 用于修复已知缺陷和一些实现增强的常规更新 对HAL驱动程序进行的以下更改需要基于较旧的HAL版本更新应用程序代码 HAL CAN驱动程序的返工(兼容性中断) 新的HAL CAN驱动程序已经使用新的API进行了重新设计,以绕过先前HAL CAN驱动程序版本中对CAN Tx / Rx FIFO管理的限制。 推荐使用新的HAL CAN驱动程序。它通常位于Drivers / STM32F1xx_HAL_Driver / Src和Drivers / STM32f1xx_HAL_Driver / Inc文件夹中。它可以通过stm32f1xx_hal_conf.h中的开关HAL_CAN_MODULE_ENABLED启用 出于软件兼容性原因,旧版HAL CAN驱动程序也出现在Drivers / STM32F1xx_HAL_Driver / Src / Legacy和Drivers / STM32F1xx_HAL_Driver / Inc / Legacy文件夹中。建议不要使用它作为已弃用的用法。但是可以通过stm32f1xx_hal_conf.h中的开关HAL_CAN_LEGACY_MODULE_ENABLED启用它 \ HAL stm32f1xx_hal_conf_template.h:添加开关 HAL_CAN_LEGACY_MODULE_ENABLED HAL CAN驱动程序已使用新API进行了重新设计。 \ CMSIS 修复已知缺陷 和几个实现 增强 \项目 更新CAN示例以支持新的HAL CAN驱动程序。 通过添加开关 HAL_CAN_LEGACY_MODULE_ENABLED 更新stm32f1xx_hal_conf.h 。 F 或完整的更改列表,请参阅每个固件组件的发行说明 内容 STM32CubeF1固件包附带了一系列在STMicroelectronics板上运行的示例,由板组织,并为主要支持的工具链提供预配置项目。此表(STM32CubeProjectsList.html)中提供了详尽的项目列表。 项目发布说明 STM32F103RB,核蛋白 应用程序 (发行说明) 演示(发行说明) 示例(发行说明) Examples_LL (发行说明) Examples_MIX (发行说明) 模板(发行说明) Templates_LL (发行说明) STM32VL发现 示例(发行说明) 模板(发行说明) Templates_LL (发行说明) STM3210C_EVAL 应用程序(发行说明) 示例(发行说明) 模板(发行说明) Templates_LL (发行说明) STM3210E_EVAL 应用程序(发行说明) 示例(发行说明) Examples_LL (发行说明) Examples_MIX (发行说明) 模板(发行说明) Templates_LL (发行说明) 驱动程序 Cortex-M CMSIS V4.5(发行说明) STM32F1xx CMSIS V4.3.0(发行说明) STM32F1 xx HAL V1.1.3 (发行说明) BSP STM3210E_EVAL V7.0.0 (发行说明) BSP STM3210C_EVAL V6.1.0 (发行说明) BSP STM32VL-Discovery V1.0.1 (发行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sol-itude

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值