做网站muse好还是DW好用,jssdk wordpress,网站建设需要的模块,网站开发人员的行业分析0、GPIO回顾
GPIO#xff0c;通用型输入输出#xff0c;控制stm32输入输出的引脚#xff0c;统称GPIO。
主功能是默认的功能
复用的功能在芯片里都是由连线的#xff0c;有联系才能复用。所以GPIO引脚能复用的功能只能是它默认复用功能和重定义功能。一般都使用默认功能…0、GPIO回顾
GPIO通用型输入输出控制stm32输入输出的引脚统称GPIO。
主功能是默认的功能
复用的功能在芯片里都是由连线的有联系才能复用。所以GPIO引脚能复用的功能只能是它默认复用功能和重定义功能。一般都使用默认功能重定义往往不会打开一旦要用重定义功能需要用到重映射。 想象成多路开关内部的配置决定输入输出模式。 端口配置寄存器 低位CRL 0-7 高位CRH8-15 4位配一个引脚CNF和MODE各配2个。
一、改进GPIO流水灯
1复制案例修改名称
03_led_flow_pro_register 2删减
删除除user和start以外的文件夹和文件保留.uvprojx文件
3创建文件 像这样的基础配置都可以放在一起称为初始化。也就是将外围的LED灯写一个驱动程序。LED灯是属于硬件外设所以新建文件夹Hardware,新建两个文件如下 4打开keil文件项目 5打开项目管理添加User文件夹下delay.c文件 6在Hardware文件下创建LED文件夹将led.c和led.h文件放进去。 7配完关掉keil,通过vscode打开。
首先补充delay.c第一步肯定是引入.h文件。 在delay.h中如此定义 前一个文件在main中定义的函数可以直接挪移。 led.c也是同理。引入led.h 之后把所有定义函数的操作放进.c文件里。
#include led.h//初始化
void LED_Init(void)
{//1.时钟配置开启GPIOA时钟RCC-APB2ENR|RCC_APB2ENR_IOPAEN;//2.工作模式配置PA0 PA1 PA8通用推挽输出 CNF00,MODE11GPIOA-CRL~GPIO_CRL_CNF0;GPIOA-CRL|GPIO_CRL_MODE0;GPIOA-CRL~GPIO_CRL_CNF1;GPIOA-CRL|GPIO_CRL_MODE1;GPIOA-CRH~GPIO_CRH_CNF8;GPIOA-CRH|GPIO_CRH_MODE8;//3.初始全高电平都置1, 全关灯/*GPIOA-ODR|GPIO_ODR_ODR0; LED_Off(LED_1);GPIOA-ODR|GPIO_ODR_ODR1; LED_Off(LED_2)GPIOA-ODR|GPIO_ODR_ODR8; LED_Off(LED_3);*/uint16_t leds[]{LED_1,LED_2,LED_3};LED_OffAll(leds,3);
}//开关LED灯参数就定为led要开哪个灯就传哪个灯
void LED_On(uint16_t led)
{
GPIOA-ODR~led;
}
void LED_Off(uint16_t led)
{GPIOA-ODR|led;
}//反转LED灯状态
void LED_Toggle(uint16_t led)
{//根据IDR对应位的值判断当前LED状态. IDR和ODR对应的位是一样的if((GPIOA-IDRled)0){LED_Off(led);}else{LED_On(led);}
}//控制所有灯的开关
void LED_OnAll(uint16_t leds[],uint8_t size)//全开
{for (uint8_t i 0; i size; i){LED_On(leds[i]);}}
void LED_OffAll(uint16_t leds[],uint8_t size)//全关
{for (uint8_t i 0; i size; i){LED_Off(leds[i]);}}为了看起来方便将开启数据端口的寄存器写法宏定义为我们的白话。
合理规范代码
delay.c
#include delay.h
//延时函数
void Delay_us(uint16_t us)
{SysTick-LOAD72*us;SysTick-CTRL0x05;while(!(SysTick-CTRLSysTick_CTRL_COUNTFLAG)){}SysTick-CTRL~SysTick_CTRL_ENABLE;
}
void Delay_ms(uint16_t ms)
{while(ms--){
Delay_us(1000);}}
void Delay_s(uint16_t s)
{while(s--){
Delay_ms(1000);}}
delay.h
#ifndef __DELAY_H
#define __DELAY_H#include stm32f10x.h
//定义延时函数
void Delay_us(uint16_t us);
void Delay_ms(uint16_t ms);
void Delay_s(uint16_t s);
#endifled.c
#include led.hvoid LED_Init(void)
{// 时钟配置打开时钟RCC-APB2ENR | RCC_APB2ENR_IOPAEN;// 工作模式配置PA0 PA1 PA8通过推挽输出。CNF00,MODE11GPIOA-CRL | GPIO_CRL_MODE0;GPIOA-CRL ~GPIO_CRL_CNF0;GPIOA-CRL | GPIO_CRL_MODE1;GPIOA-CRL ~GPIO_CRL_CNF1;GPIOA-CRH | GPIO_CRH_MODE8;GPIOA-CRH ~GPIO_CRH_CNF8;// 初始化引脚输出高电平关灯LED_Off(LED_1);LED_Off(LED_2);LED_Off(LED_3);
}void LED_On(uint16_t led)
{GPIOA-ODR ~led;
}void LED_Off(uint16_t led)
{GPIOA-ODR | led;
}void LED_Toggle(uint16_t led)
{// 根据IDR对应位的值判断当前LED状态if ((GPIOA-IDR led) 0){LED_Off(led);}else{LED_On(led);}
}void LED_OnAll(uint16_t leds[], uint8_t size)
{for (uint8_t i 0; i size; i){LED_On(leds[i]);}
}void LED_OffAll(uint16_t leds[], uint8_t size)
{for (uint8_t i 0; i size; i){LED_Off(leds[i]);}
}led.h
#ifndef __LED_H
#define __LED_H
#include stm32f10x.h
//定义LED灯
#define LED_1 GPIO_ODR_ODR0
#define LED_2 GPIO_ODR_ODR1
#define LED_3 GPIO_ODR_ODR8
//初始化
void LED_Init(void);
//开关LED灯
void LED_On(uint16_t led);
void LED_Off(uint16_t led);//翻转LED灯状态
void LED_Toggle(uint16_t led);
//控制所有LED灯的开关
void LED_OnAll(uint16_t leds[],uint8_t size);
void LED_OffAll(uint16_t leds[],uint8_t size);
#endifmain.c
#include stdint.h
#include delay.h
#include led.h
int main(void){//初始化
LED_Init();
uint16_t leds[]{LED_1,LED_2,LED_3};
uint8_t n3;while(1){for(uint8_t i0;in;i){LED_On(leds[i]);Delay_ms(500);LED_Off(leds[i]);}}}二、总体架构和时钟系统
1.总体架构stm32 13个被动单元
内部SRAM
存储程序执行时用到的变量
在嵌入式环境中SRAM相当于运行内存
内部闪存存储器
存储下载的程序 程序执行时用到的常量
flash严格来讲划分为ROM随机访问存储器掉电就丢类型
在嵌入式环境中flash相当于存储内存
AHB到APB的桥AHB to APBx
B:Bus 总线的意思 AHB高速系统总线 是总线的核心 桥1通过APB2总线连接到APB2上的外设。属于高速外设最高72MHz.
桥2通过APB1总线连接APB1的外设。低速外设最高36MHz。时钟配置时需要二分频。
2四个驱动(主动)单元 3其他单元
内核Code总线
通过外部的ICode总线连接Flash实现指令的读取 FSMC 2.时钟系统
51不需要开启时钟因为简单只有一个时钟不用配。
32有不同时钟来源高速设备接高速时钟低速设备接低速时钟。这样效率最高。
时钟源 内部的低速时钟 40k 外部的低速时钟 32.768k
SYSCLK 系统时钟
RTCCLK 实时时钟 1HSE时钟
高速外部时钟是由外部时钟源提供。做过STM32项目的同学都知道几乎所有的单片机都会外部接一个8Mhz的晶振经过PLL九倍频得到72MHZ的系统时钟这是系统默认的时钟。 2HSI时钟
HSI时钟是内部的8MHZ的RC振荡器产生可直接作为系统时钟或在2分频后作为PLL输入。不需要任何外部器件就能提供系统时钟。启用时间比HSE晶体振荡器短。缺点是就算校准时钟频率精度较差。 3PLL时钟
内部PLL用来倍频HSI RC的输出时钟或HSE晶体输出时钟。PLL设置必须在其被激活前完成一旦激活参数不能被改动。如果PLL中断在时钟中断寄存器里被允许当PLL准备就绪时可产生中断申请。
PLL时钟对外部8MHZ时钟信号9倍频得到72MHZ时钟频率这是STM32F1系列允许的最高时钟频率。 4LSE时钟
LSE晶体是一个32.768khz的低速外部晶体或陶瓷谐振器。它为实时时钟或者其他定时功能他提供一个低功耗且精确的时钟源。LSE不能驱动系统时钟。 5LSI时钟
低功耗时钟源在停机和待机模式下保持运行为独立看门狗和自动唤醒单元提供时钟。时钟频率大约40kHZ(30-60之间)。
不能驱动系统时钟。 6stm32时钟配置源码分析
关于时钟配置的源代码往往在启动文件中已经做完了。 CR是时钟的控制器 CFGR 时钟配置寄存器 三、HAL库开发
1.简介
寄存器效率虽高但是开发效率低对开发者来说不太友好。 2.环境与安装
Java8很稳定我们就安装这个。
winr cmd
输入 java -version 检验是否安装java8 能够显示版本号就说明电脑安装着Java的jdk.
然后就是傻瓜式安装。cubmx 图形化界面自动生成ST的hal库文件让我们的配置变成点点点。 之后就是芯片支持包了。双击打开cubeMX. 这是在线安装可能时间费得有些多。
下面是离线安装步骤 文章结尾我会给大家资料包里面就有离线芯片支持包 里面有两个一个是基础的一个是升级的1-8-5比较尴尬的是只能安装基础包但我们可以李代桃僵。
我们安装好CUBEMX之后就去找它的仓库之前安装的时候不改路径的话应该在C盘用户 我们在CUBEmx上先装基础包之后将高版本的解压到仓库文件夹替换掉它 必须解压到这里哦。
解压之后替换掉基础包。 3.流水灯案例HAL库
1配置 联网的话会出现更新提示直接关掉即可。
之后让我开始点点点。 这里面都是我们所要配的引脚找准需求定位普通或要复用的引脚吧。
系统核心配置 SYS是必配的。选择模式和系统时钟单线模式SW一根数据线一根时钟线。JTAG有四根线。 如果是标准库寄存器写法时钟需要自己配。 前边我们说过PLL时钟会选择外部晶振提供时钟。这一点主要在下图体现 之后配置GPIO点亮LED灯主要是靠GPIO的通用推挽输出。 剩下两个引脚都一样。
之后创建工程文件 之后跟随窗口就打开KEIL。
2代码实现 话不多说开始写代码。将我们之前写的硬件外设LED灯的两个文件导入工程。 led.c
#include led.h//开关LED灯参数就定为led要开哪个灯就传哪个灯
void LED_On(uint16_t led)
{
HAL_GPIO_WritePin(LED_1_GPIO_Port,led,GPIO_PIN_RESET);
}
void LED_Off(uint16_t led)
{HAL_GPIO_WritePin(LED_1_GPIO_Port,led,GPIO_PIN_SET);
}//反转LED灯状态
void LED_Toggle(uint16_t led)
{HAL_GPIO_TogglePin(LED_1_GPIO_Port,led);
}//控制所有灯的开关
uint16_t leds[]{LED_1_Pin,LED_2_Pin,LED_3_Pin};
void LED_OnAll(uint16_t leds[],uint8_t size)//全开
{for (uint8_t i 0; i size; i){LED_On(leds[i]);}}
void LED_OffAll(uint16_t leds[],uint8_t size)//全关
{for (uint8_t i 0; i size; i){LED_Off(leds[i]);}}main.c
/* USER CODE BEGIN Header */
/********************************************************************************* file : main.c* brief : Main program body******************************************************************************* attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include main.h
#include gpio.h
#include led.h
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** brief The application entry point.* retval int*/
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();//初始化所有引脚高电平等全灭uint8_t n3;uint16_t leds[]{LED_1_Pin,LED_2_Pin,LED_3_Pin};while (1){for (uint8_t i 0; i n; i){LED_On(leds[i]);HAL_Delay(1000);LED_Off(leds[i]);}}/* USER CODE END 3 */
}/*** brief System Clock Configuration* retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** brief This function is executed in case of error occurrence.* retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#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 CODE BEGIN 6 *//* 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) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */四、资料下载
stm32开发官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供stm32开发最新版正式版官方版绿色版下载,stm32开发安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123684.com/s/TQubTd-1eEtv?提取码:xscF