依据数据手册找到需要的参数
ws2812的需要参数
0码 |--|---| 高电平时间范围220ns~420ns|低电平时间范围750ns~1600ns
320 960
1码 |---|--|
960 320
帧数据时间范围800ns~1400ns
当前单片机的需要参数
单片机的主频
举例两个单片机的先是H750的480M
480M的主频320ns的延时大概需要96个空操作
72M 则需要16个空操作(理论值)
单片机一个指令所需的机器时钟是不一样的,在ns级别循环和函数调用对此时间都是略有差异的。
废话不多说,直接看代码(H750)
先初始化端口和一些方便使用的宏定义
我这里用的是PC5
#define rgb_led_low HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET)
#define rgb_led_high HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET)
#define LED_COUNT 60 // 假设有60个LED灯
#define ANIMATION_STEPS 10 // 动画步骤数
#define DELAY_TIME 50 // 每步动画之间的延时,单位毫秒
void ws2812_init(void){
GPIO_InitTypeDef gpio_init_struct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
/* 配置控制引脚 */
gpio_init_struct.Pin = GPIO_PIN_5;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
gpio_init_struct.Pull = GPIO_PULLDOWN;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//高速
HAL_GPIO_Init(GPIOC, &gpio_init_struct);
}
编写延时函数
void delay_320nm(void){
//volatile关键字告诉编译器不要优化对i的访问
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //10
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//20
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//30
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//70
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
}
帧单位延时函数
//帧单位大于300这里给350
void out_led_reset(void){
rgb_led_low;
delay_us(350);
}
HAL库不自带nm延时可使用:
HAL_Delay(1);
发送1码函数
void out_led_1(void){
rgb_led_high;
delay_320nm();
delay_320nm();
delay_320nm();
rgb_led_low;
delay_320nm();
}
发送0码函数
void out_led_0(void){
rgb_led_high;
delay_320nm();
rgb_led_low;
delay_320nm();
delay_320nm();
delay_320nm();
}
发送数据位函数
/*
给单个LED发送RGB数据
*/
void rgb_led_data(uint8_t red,uint8_t green,uint8_t blue){
uint8_t i;
for(i=0;i<8;i++)
{
green<<=i;
if(green&0x80)
out_led_1();
else
out_led_0();
}
for(i=0;i<8;i++)
{
red<<=i;
if(red&0x80)
out_led_1();
else
out_led_0();
}
for(i=0;i<8;i++)
{
blue<<=i;
if(blue&0x80)
out_led_1();
else
out_led_0();
}
out_led_reset();
}
在此就可以调用进行亮灯动画了
示例:
//波浪效果
void motion1(void){
uint16_t i, j;
for (i = 0; i < LED_COUNT * 5; i++) { // 波浪来回5次
for (j = 0; j < LED_COUNT; j++) {
if (j < i % LED_COUNT) {
rgb_led_data(colors[1][0], colors[1][1], colors[1][2]); // 蓝色波浪
} else if (j > LED_COUNT - 1 - (i % LED_COUNT)) {
rgb_led_data(colors[2][0], colors[2][1], colors[2][2]); // 绿色波浪
} else {
rgb_led_data(0, 0, 0); // 黑色背景
}
}
delay_ms(DELAY_TIME); // 延迟以展示波浪效果
}
}
主函数
int main(void){
while(1){
motion1();
}
}
完整代码
WS2812B.c
#include "WS2812B.h"
//#define rgb_led_low HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET)
//#define rgb_led_high HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET)
#define rgb_led_low HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET)
#define rgb_led_high HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET)
#define LED_spend 30
static uint8_t colors[][3] = {
{255, 0, 0}, // 红色
{255, 0, 255}, // 品红
{255, 165, 0}, // 橙色
{255, 255, 0}, // 黄色
{0, 255, 0}, // 绿色
{0, 0, 255}, // 蓝色
{75, 0, 130}, // 靛色
{128, 0, 128}, // 紫色
{255, 192, 203}, // 粉色
{0, 255, 255}, // 青色
{255, 255, 255}, // 白色
{0, 0, 0} // 黑色
};
void ws2812_init(void){
GPIO_InitTypeDef gpio_init_struct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
/* 配置控制引脚 */
gpio_init_struct.Pin = GPIO_PIN_5;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_PULLDOWN;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOC, &gpio_init_struct);
}
void delay_320nm(void){
//volatile关键字告诉编译器不要优化对i的访问
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //10
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//20
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//30
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();//70
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
}
/*
0码 |--|---| 高电平时间范围220ns~420ns|低电平时间范围750ns~1600ns|帧数据时间范围800ns~1400ns
320 960
1码 |---|--|
960 320
*/
void out_led_1(void){
rgb_led_high;
delay_320nm();
delay_320nm();
delay_320nm();
rgb_led_low;
delay_320nm();
}
void out_led_0(void){
rgb_led_high;
delay_320nm();
rgb_led_low;
delay_320nm();
delay_320nm();
delay_320nm();
}
//帧单位大于300这里给350
void out_led_reset(void){
rgb_led_low;
delay_us(350);
}
/*
给单个LED发送RGB数据
*/
void rgb_led_data(uint8_t red,uint8_t green,uint8_t blue){
uint8_t i;
for(i=0;i<8;i++)
{
green<<=i;
if(green&0x80)
out_led_1();
else
out_led_0();
}
for(i=0;i<8;i++)
{
red<<=i;
if(red&0x80)
out_led_1();
else
out_led_0();
}
for(i=0;i<8;i++)
{
blue<<=i;
if(blue&0x80)
out_led_1();
else
out_led_0();
}
out_led_reset();
}
void cartoon1(void){
uint16_t is,id;
uint16_t arr = 60; //600
for(is=0;is<arr;is++)
{
for(id=arr;id-is>0;id--){
rgb_led_data(0,0,0);
}
for(id=0;id<is;id++){
rgb_led_data(255,255,100); //10,7,200
}
HAL_Delay(50);
}
}
void cartoon2(void){
uint8_t is,id;
for(is=0;is<30;is++)
{
// rgb_led_data(10,5,10);
// HAL_Delay(1000);
for(id=30;id-is>0;id--){
rgb_led_data(255,255,10);
}
for(id=0;id<is;id++){
rgb_led_data(10,100,10);
}
HAL_Delay(LED_spend);
}
}
void cartoon3(void){
//uint8_t is,id,ir,ig; //,ib
uint16_t ir,id,ic=0,is=600,sc;
//uint8_t rs=0,gs=0,bs=0;
for(id=0;id<12;id++){
ic+=50;
sc=id%2;
for(ir=0;ir<ic;ir++){
rgb_led_data(colors[sc][0], colors[sc][1], colors[sc][2]);
}
if(ic==600){
ic=0;
}
for(ir=0;ir<is-ic;ir++){
rgb_led_data(0, 0, 0);
}
HAL_Delay(LED_spend+1000);
}
}
void cartoon4(void){
//int num_colors = sizeof(colors) / sizeof(colors[0]);
HAL_Delay(LED_spend); // 调整延迟时间以控制彩虹流动速度
for (uint16_t i = 0; i < 7 * 5; i++) {
for (uint16_t j = 0; j < 60; j++) {
uint8_t color_index = (i + j) % 7;
rgb_led_data(colors[color_index][0], colors[color_index][1], colors[color_index][2]);
}
HAL_Delay(LED_spend+50);
}
}
/*
iz=层数
*/
void cartoon5(void){
uint16_t id; //is=600
for(id=0;id<12;id++){
for (uint16_t j = 0; j < id*50; j++) {
rgb_led_data(0, 0, 0);
}
for (uint16_t j = id*50; j < id*50+50; j++) {
rgb_led_data(241,241,102); //0, 0, 200
}
HAL_Delay(1000);
}
for (uint16_t j = 0; j < 600; j++) {
rgb_led_data(0, 0, 0);
}
HAL_Delay(1000);
}
void cartoon6(void){
//uint8_t is,id,ir,ig; //,ib
uint16_t ir,id,ic=0,is=600;
//uint8_t rs=0,gs=0,bs=0;
for(id=0;id<12;id++){
ic+=50;
for(ir=0;ir<ic;ir++){
rgb_led_data(colors[4][0], colors[4][1], colors[4][2]);
}
if(ic==600){
ic=0;
break;
}
for(ir=0;ir<is-ic;ir++){
rgb_led_data(0, 0, 0);
}
HAL_Delay(LED_spend+1000);
}
for (uint16_t j = 0; j < 600; j++) {
rgb_led_data(0, 0, 0);
}
HAL_Delay(1000);
}
void cartoon7(void){
uint16_t i, j;
for (i = 0; i < LED_COUNT * 2; i++) { // 波浪来回两次
for (j = 0; j < LED_COUNT; j++) {
if (j < i % LED_COUNT) {
rgb_led_data(colors[1][0], colors[1][1], colors[1][2]); // 蓝色波浪
} else if (j > LED_COUNT - 1 - (i % LED_COUNT)) {
rgb_led_data(colors[2][0], colors[2][1], colors[2][2]); // 绿色波浪
} else {
rgb_led_data(0, 0, 0); // 黑色背景
}
}
delay_ms(DELAY_TIME); // 延迟以展示波浪效果
}
}
void cartoon8(void){
uint16_t i,j;
for(i=3;i<LED_COUNT+3;i++){
for(j=0;j<i-3;j++){
rgb_led_data(0,0,0);
}
for(j=0;j<i;j++){
rgb_led_data(colors[5][0],colors[5][1],colors[5][2]);
}
delay_ms(DELAY_TIME);
}
}
void led_off(void){
uint16_t i;
for(i=0;i<600;i++){
rgb_led_data(0, 0, 0);
}
}
//波浪效果
void motion1(void){
uint16_t i, j;
for (i = 0; i < LED_COUNT * 5; i++) { // 波浪来回5次
for (j = 0; j < LED_COUNT; j++) {
if (j < i % LED_COUNT) {
rgb_led_data(colors[1][0], colors[1][1], colors[1][2]); // 蓝色波浪
} else if (j > LED_COUNT - 1 - (i % LED_COUNT)) {
rgb_led_data(colors[2][0], colors[2][1], colors[2][2]); // 绿色波浪
} else {
rgb_led_data(0, 0, 0); // 黑色背景
}
}
delay_ms(DELAY_TIME); // 延迟以展示波浪效果
}
}
//呼吸灯效果
void motion2(void){
uint8_t brightness = 0;
uint8_t direction = 1; // 1表示亮度增加,-1表示亮度减少
uint16_t i,j=LED_COUNT;
while (j--) { // 无限循环
for (i = 0; i < LED_COUNT; i++) {
rgb_led_data(brightness, brightness, brightness); // 设置所有LED为相同的亮度
}
brightness += direction; // 改变亮度
if (brightness == 0 || brightness == 255) { // 到达最大或最小亮度时改变方向
direction *= -1;
}
delay_ms(50); // 较快地更新亮度以创建呼吸效果
}
}
//彩虹效果
void motion3(void){
uint16_t position = 0;
uint16_t i,j=LED_COUNT;
while (j--) {
for (i = 0; i < LED_COUNT; i++) {
uint8_t color_index = (position + i) % 9; // 循环使用6种颜色
rgb_led_data(colors[color_index][0], colors[color_index][1], colors[color_index][2]);
}
position++; // 移动彩虹位置
delay_ms(DELAY_TIME); // 延迟以展示彩虹效果
}
}
//随机闪烁效果
void motion4(void){
// 初始化随机数生成器
// srand((unsigned int)time(NULL));
//
// while (1) { // 无限循环
// for (uint16_t i = 0; i < LED_COUNT; i++) {
// if (rand() % 2) { // 50%的概率打开LED
// rgb_led_data(colors[rand() % 6][0], colors[rand() % 6][1], colors[rand() % 6][2]);
// } else {
// rgb_led_data(0, 0, 0); // 关闭LED
// }
// }
// delay_ms(DELAY_TIME); // 延迟以展示随机闪烁效果
// }
}
//
void motion5(void){
uint16_t position = 0;
uint16_t i,j=LED_COUNT;
while (j--) { // 无限循环
for (i = 0; i < LED_COUNT; i++) {
uint8_t color_index = (position + i) % 6; // 循环使用6种颜色
rgb_led_data(colors[color_index][0], colors[color_index][1], colors[color_index][2]);
}
position++; // 移动彩虹位置
//delay_ms(DELAY_TIME + 100); // 延迟以展示彩虹效果 熄灭延时
// 闪烁效果:将所有LED设置为黑色,然后稍微延迟后再次显示彩虹
for (uint16_t i = 0; i < LED_COUNT; i++) {
rgb_led_data(0, 0, 0); // 关闭所有LED
}
delay_ms(DELAY_TIME +300); // 短暂延迟,创造闪烁效果
}
}
//
void motion6(void){
uint16_t i,j=LED_COUNT;
while (j--) { // 无限循环
j--;
for (i = 0; i < LED_COUNT; i++) {
// 计算颜色渐变
uint8_t red = (i * 255) / LED_COUNT;
uint8_t green = ((LED_COUNT - i) * 255) / LED_COUNT;
uint8_t blue = 0; // 可以添加蓝色渐变或其他颜色组合
rgb_led_data(red, green, blue);
}
delay_ms(DELAY_TIME); // 延迟以展示渐变彩虹效果
// 可以添加其他逻辑,比如改变渐变的方向或速度
}
}
//
void motion7(void){
#define CHASE_GROUP_SIZE 5 // 追逐组的大小
uint16_t chase_position = 0; // 追逐组的起始位置
uint16_t j=LED_COUNT,i;
while (j--) { // 无限循环
// 初始化所有LED为黑色
for (i = 0; i < LED_COUNT; i++) {
rgb_led_data(0, 0, 0);
}
// 设置追逐组的LED为白色或其他亮色
for (i = 0; i < CHASE_GROUP_SIZE; i++) {
if (chase_position + i < LED_COUNT) {
rgb_led_data(255, 255, 255); // 假设rgb_led_data接受索引作为最后一个参数
}
}
// 移动追逐组的位置
chase_position = (chase_position + 1) % LED_COUNT;
delay_ms(DELAY_TIME); // 延迟以展示追逐效果
}
}
//
void motion8(uint16_t i){
// 计算每个颜色段的大小
uint16_t color_segment_size = LED_COUNT / 9;
for (uint16_t j = 0; j < LED_COUNT; j++) {
// 计算当前LED属于哪个颜色段
uint16_t color_index = j / color_segment_size;
// 如果LED在颜色段的边界上,确保它使用正确的颜色
if (j % color_segment_size == 0) {
color_index = (color_index + i) % 9; // 根据波浪位置滚动颜色
}
// 设置LED的颜色
rgb_led_data(colors[color_index][0], colors[color_index][1], colors[color_index][2]);
}
}
//
void motion9(void){
uint16_t i = 0;
// 增加i的值以移动波浪 // 保证i在0到8之间循环
for(i=0;i<9;i++){
motion8(i); // 不断更新i来创建动画效果
delay_ms(DELAY_TIME+500); // 延时一段时间,控制动画速度
}
}
WS2812B.h
/*******************************************************************************
* @file HDL_WS2812B.h
* @author huiyang
* @version V1.0
* @date 01/21/2022
******************************************************************************/
#ifndef __WS2812B_H
#define __WS2812B_H
//#include "gpio.h"
#include "sys.h"
#include "delay.h"
#include <stdlib.h> // 为了使用rand()和srand()
/* 根据DataSheet定义0/1编码对应的高电平比较值,因为高电平在前,定义高电平的即可
** 高低电平的比例约为2:1
*/
/* 灯珠亮的个数 */
#define LED_COUNT 60 // 假设有60个LED灯
#define ANIMATION_STEPS 10 // 动画步骤数
#define DELAY_TIME 50 // 每步动画之间的延时,单位毫秒
void ws2812_init(void);
void delay_320nm(void);
void out_led_0(void);
void out_led_1(void);
void out_led_reset(void);
void rgb_led_data(uint8_t red,uint8_t gree,uint8_t blue);
void cartoon1(void);
void cartoon2(void);
void cartoon3(void);
void cartoon4(void);
void cartoon5(void);
void cartoon6(void);
void cartoon7(void);
void cartoon8(void);
void led_off(void);
void motion1(void);
void motion2(void);
void motion3(void);
void motion4(void);
void motion5(void);
void motion6(void);
void motion7(void);
void motion8(uint16_t i);
void motion9(void);
extern uint16_t spend;
#endif
main.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "sys.h"
#include "delay.h"
#include "WS2812B.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);
static void MPU_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)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
delay_init(480);
ws2812_init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
motion6();
motion5();
motion4();
motion3();
motion2();
motion1();
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/* MPU Configuration */
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/**
* @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 */