Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
|
8d9f5ae77c | |
|
a6030813eb | |
|
a66354ed9b | |
|
1557e1da76 | |
|
883cf7d530 |
114
bsp/adcs.c
114
bsp/adcs.c
|
@ -2,7 +2,7 @@
|
||||||
* @file adcs.c
|
* @file adcs.c
|
||||||
* @author xxx
|
* @author xxx
|
||||||
* @date 2023-09-04 15:59:16
|
* @date 2023-09-04 15:59:16
|
||||||
* @brief LL库ADC驱动
|
* @brief LL库ADC驱动 STM32F407
|
||||||
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
|
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ static uint8_t adc_get_channels_count(uint32_t channnels); // 通过用户配置
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @note TCONV(转换时间) = (采样时间 + 12.5 个周期)/(主频/ADC分频系数)
|
* @note TCONV(转换时间) = (采样时间 + 12.5 个周期)/(主频/ADC分频系数)
|
||||||
*/
|
*/
|
||||||
void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels)
|
void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_stream, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
||||||
DBG_ASSERT(adc != NULL __DBG_LINE);
|
DBG_ASSERT(adc != NULL __DBG_LINE);
|
||||||
|
@ -34,6 +34,7 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
|
||||||
osel_memset((uint8_t *)p, 0, sizeof(adcs_t));
|
osel_memset((uint8_t *)p, 0, sizeof(adcs_t));
|
||||||
p->adc = adc;
|
p->adc = adc;
|
||||||
p->dma = dma;
|
p->dma = dma;
|
||||||
|
p->dma_stream = dma_stream;
|
||||||
p->dma_channel = dma_channel;
|
p->dma_channel = dma_channel;
|
||||||
p->channels.data = channels;
|
p->channels.data = channels;
|
||||||
p->adc_cct = adc_cct;
|
p->adc_cct = adc_cct;
|
||||||
|
@ -49,36 +50,40 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
|
||||||
DBG_ASSERT(p->adc_value != NULL __DBG_LINE);
|
DBG_ASSERT(p->adc_value != NULL __DBG_LINE);
|
||||||
osel_memset((uint8_t *)p->adc_value, 0, sizeof(uint16_t) * p->adc_sum);
|
osel_memset((uint8_t *)p->adc_value, 0, sizeof(uint16_t) * p->adc_sum);
|
||||||
|
|
||||||
uint32_t backup_setting_adc_dma_transfer = 0U;
|
LL_DMA_SetChannelSelection(p->dma, p->dma_stream, p->dma_channel);
|
||||||
backup_setting_adc_dma_transfer = LL_ADC_REG_GetDMATransfer(p->adc);
|
LL_DMA_ConfigTransfer(p->dma, p->dma_stream,
|
||||||
LL_ADC_REG_SetDMATransfer(p->adc, LL_ADC_REG_DMA_TRANSFER_NONE);
|
LL_DMA_DIRECTION_PERIPH_TO_MEMORY |
|
||||||
|
LL_DMA_MODE_CIRCULAR |
|
||||||
|
LL_DMA_PERIPH_NOINCREMENT |
|
||||||
|
LL_DMA_MEMORY_INCREMENT |
|
||||||
|
LL_DMA_PDATAALIGN_HALFWORD |
|
||||||
|
LL_DMA_MDATAALIGN_HALFWORD |
|
||||||
|
LL_DMA_PRIORITY_HIGH);
|
||||||
|
LL_DMA_ConfigAddresses(p->dma, p->dma_stream,
|
||||||
|
LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA),
|
||||||
|
(uint32_t)p->adc_value,
|
||||||
|
LL_DMA_GetDataTransferDirection(p->dma, p->dma_stream));
|
||||||
|
|
||||||
// ADC开始校准
|
LL_DMA_SetDataLength(p->dma, p->dma_stream, p->adc_sum);
|
||||||
LL_ADC_StartCalibration(p->adc, LL_ADC_SINGLE_ENDED);
|
LL_DMA_EnableStream(p->dma, p->dma_stream);
|
||||||
// 等待校准完成
|
|
||||||
while (LL_ADC_IsCalibrationOnGoing(p->adc))
|
LL_ADC_REG_SetContinuousMode(p->adc, LL_ADC_REG_CONV_CONTINUOUS);
|
||||||
;
|
LL_ADC_REG_SetDMATransfer(p->adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
|
||||||
LL_ADC_REG_SetDMATransfer(p->adc, backup_setting_adc_dma_transfer);
|
|
||||||
LL_mDelay(10);
|
|
||||||
LL_ADC_EnableIT_OVR(p->adc);
|
|
||||||
LL_ADC_Enable(p->adc);
|
|
||||||
LL_mDelay(10);
|
|
||||||
|
|
||||||
if (BIT_IS_SET(channels, INVREF))
|
if (BIT_IS_SET(channels, INVREF))
|
||||||
{
|
{
|
||||||
// 使能VREFINT
|
// 使能VREFINT
|
||||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_VREFINT);
|
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_VREFINT);
|
||||||
}
|
}
|
||||||
|
if (BIT_IS_SET(channels, INTEMP))
|
||||||
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
|
|
||||||
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
|
|
||||||
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
|
|
||||||
LL_DMA_EnableChannel(p->dma, p->dma_channel);
|
|
||||||
|
|
||||||
if (backup_setting_adc_dma_transfer == LL_ADC_REG_DMA_TRANSFER_UNLIMITED)
|
|
||||||
{
|
{
|
||||||
LL_ADC_REG_StartConversion(p->adc); // 开始转换
|
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(p->adc), LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LL_mDelay(10);
|
||||||
|
// 启动 ADC 转换
|
||||||
|
LL_ADC_Enable(p->adc);
|
||||||
|
LL_ADC_REG_StartConversionSWStart(p->adc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,18 +96,7 @@ void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_chann
|
||||||
void start_sample(adcs_e num)
|
void start_sample(adcs_e num)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
||||||
adcs_t *p = &adcs[num];
|
// adcs_t *p = &adcs[num];
|
||||||
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
|
|
||||||
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
|
|
||||||
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
|
|
||||||
LL_DMA_EnableChannel(p->dma, p->dma_channel);
|
|
||||||
|
|
||||||
LL_ADC_ClearFlag_OVR(p->adc);
|
|
||||||
LL_ADC_ClearFlag_EOC(p->adc);
|
|
||||||
LL_ADC_REG_StartConversion(p->adc); // 开始转换
|
|
||||||
|
|
||||||
// ADC开始校准
|
|
||||||
LL_ADC_StartCalibration(p->adc, LL_ADC_SINGLE_ENDED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,14 +109,7 @@ void start_sample(adcs_e num)
|
||||||
void stop_sample(adcs_e num)
|
void stop_sample(adcs_e num)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
||||||
adcs_t *p = &adcs[num];
|
// adcs_t *p = &adcs[num];
|
||||||
|
|
||||||
LL_ADC_REG_StopConversion(p->adc);
|
|
||||||
while (LL_ADC_REG_IsConversionOngoing(p->adc) != 0)
|
|
||||||
;
|
|
||||||
LL_DMA_DisableChannel(p->dma, p->dma_channel);
|
|
||||||
DMA_CLEAR_FLAG_TC_CHANNEL(p->dma, p->dma_channel);
|
|
||||||
DMA_CLEAR_FLAG_TE_CHANNEL(p->dma, p->dma_channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,8 +134,6 @@ void adc_dinit(adcs_e num)
|
||||||
{
|
{
|
||||||
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
DBG_ASSERT(num < ADCS_MAX __DBG_LINE);
|
||||||
adcs_t *p = &adcs[num];
|
adcs_t *p = &adcs[num];
|
||||||
LL_ADC_REG_StopConversion(p->adc);
|
|
||||||
LL_DMA_DisableChannel(p->dma, p->dma_channel);
|
|
||||||
LL_ADC_Disable(p->adc);
|
LL_ADC_Disable(p->adc);
|
||||||
if (p->adc_value != NULL)
|
if (p->adc_value != NULL)
|
||||||
{
|
{
|
||||||
|
@ -190,7 +175,7 @@ uint16_t adc_result_median_average(adcs_e num, uint8_t chan)
|
||||||
|
|
||||||
if (p->adc_cct <= 2)
|
if (p->adc_cct <= 2)
|
||||||
return 0; // 如果adc_cct小于等于2,直接返回0
|
return 0; // 如果adc_cct小于等于2,直接返回0
|
||||||
p->median_average_ticks.uticks = sys_get_tick();
|
|
||||||
uint16_t adc_temp[p->adc_cct];
|
uint16_t adc_temp[p->adc_cct];
|
||||||
uint32_t adc_sum = 0;
|
uint32_t adc_sum = 0;
|
||||||
uint16_t count = p->adc_cct >> 2; // 使用位移操作计算n的值
|
uint16_t count = p->adc_cct >> 2; // 使用位移操作计算n的值
|
||||||
|
@ -212,13 +197,6 @@ uint16_t adc_result_median_average(adcs_e num, uint8_t chan)
|
||||||
|
|
||||||
// 计算平均值,确保不会除以0
|
// 计算平均值,确保不会除以0
|
||||||
uint16_t res = adc_sum / (p->adc_cct - (count << 1));
|
uint16_t res = adc_sum / (p->adc_cct - (count << 1));
|
||||||
|
|
||||||
p->median_average_ticks.ticks_current = sys_get_tick() - p->median_average_ticks.uticks;
|
|
||||||
if (p->median_average_ticks.ticks_current > p->median_average_ticks.ticks_max)
|
|
||||||
{
|
|
||||||
p->median_average_ticks.ticks_max = p->median_average_ticks.ticks_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,8 +214,6 @@ uint16_t adc_result_median(adcs_e num, uint8_t chan)
|
||||||
adcs_t *p = &adcs[num];
|
adcs_t *p = &adcs[num];
|
||||||
DBG_ASSERT(p != NULL __DBG_LINE);
|
DBG_ASSERT(p != NULL __DBG_LINE);
|
||||||
|
|
||||||
p->median_ticks.uticks = sys_get_tick();
|
|
||||||
|
|
||||||
uint16_t adc_temp[p->adc_cct];
|
uint16_t adc_temp[p->adc_cct];
|
||||||
// 减少重复计算,计算基础偏移量
|
// 减少重复计算,计算基础偏移量
|
||||||
uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
|
uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
|
||||||
|
@ -247,12 +223,6 @@ uint16_t adc_result_median(adcs_e num, uint8_t chan)
|
||||||
}
|
}
|
||||||
insertion_sort(adc_temp, p->adc_cct);
|
insertion_sort(adc_temp, p->adc_cct);
|
||||||
res = adc_temp[p->adc_cct >> 1];
|
res = adc_temp[p->adc_cct >> 1];
|
||||||
|
|
||||||
p->median_ticks.ticks_current = sys_get_tick() - p->median_ticks.uticks;
|
|
||||||
if (p->median_ticks.ticks_current > p->median_ticks.ticks_max)
|
|
||||||
{
|
|
||||||
p->median_ticks.ticks_max = p->median_ticks.ticks_current;
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,8 +241,6 @@ uint16_t adc_result_average(adcs_e num, uint8_t chan)
|
||||||
adcs_t *p = &adcs[num];
|
adcs_t *p = &adcs[num];
|
||||||
DBG_ASSERT(p != NULL __DBG_LINE);
|
DBG_ASSERT(p != NULL __DBG_LINE);
|
||||||
|
|
||||||
p->average_ticks.uticks = sys_get_tick();
|
|
||||||
|
|
||||||
// 减少重复计算,计算基础偏移量
|
// 减少重复计算,计算基础偏移量
|
||||||
uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
|
uint16_t *adc_values = (uint16_t *)p->adc_value + chan;
|
||||||
for (uint16_t i = 0; i < p->adc_cct; ++i, adc_values += p->adc_chans_count)
|
for (uint16_t i = 0; i < p->adc_cct; ++i, adc_values += p->adc_chans_count)
|
||||||
|
@ -281,12 +249,6 @@ uint16_t adc_result_average(adcs_e num, uint8_t chan)
|
||||||
}
|
}
|
||||||
res = adc_sum / p->adc_cct;
|
res = adc_sum / p->adc_cct;
|
||||||
|
|
||||||
p->average_ticks.ticks_current = sys_get_tick() - p->average_ticks.uticks;
|
|
||||||
if (p->average_ticks.ticks_current > p->average_ticks.ticks_max)
|
|
||||||
{
|
|
||||||
p->average_ticks.ticks_max = p->average_ticks.ticks_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,10 +298,6 @@ void adc_dma_callback(adcs_e num)
|
||||||
if (LL_DMA_IsActiveFlag_TC1(p->dma) != 0)
|
if (LL_DMA_IsActiveFlag_TC1(p->dma) != 0)
|
||||||
{
|
{
|
||||||
LL_DMA_ClearFlag_TC1(p->dma);
|
LL_DMA_ClearFlag_TC1(p->dma);
|
||||||
// 停止ADC转换
|
|
||||||
LL_ADC_REG_StopConversion(p->adc);
|
|
||||||
// 关闭ADC,可以不关闭但是校准无法清除
|
|
||||||
// LL_ADC_Disable(p->adc);
|
|
||||||
}
|
}
|
||||||
// 检查DMA1的传输错误标志是否为1,如果是,则清除该标志
|
// 检查DMA1的传输错误标志是否为1,如果是,则清除该标志
|
||||||
if (LL_DMA_IsActiveFlag_TE1(p->dma) != 0)
|
if (LL_DMA_IsActiveFlag_TE1(p->dma) != 0)
|
||||||
|
@ -361,17 +319,7 @@ void adc_env_callback(adcs_e num)
|
||||||
if (LL_ADC_IsActiveFlag_OVR(p->adc) != 0)
|
if (LL_ADC_IsActiveFlag_OVR(p->adc) != 0)
|
||||||
{
|
{
|
||||||
p->ovr_count++;
|
p->ovr_count++;
|
||||||
LL_ADC_REG_StopConversion(p->adc);
|
|
||||||
LL_DMA_DisableChannel(p->dma, p->dma_channel);
|
|
||||||
|
|
||||||
LL_DMA_SetDataLength(p->dma, p->dma_channel, p->adc_sum);
|
|
||||||
LL_DMA_SetPeriphAddress(p->dma, p->dma_channel, LL_ADC_DMA_GetRegAddr(p->adc, LL_ADC_DMA_REG_REGULAR_DATA));
|
|
||||||
LL_DMA_SetMemoryAddress(p->dma, p->dma_channel, (uint32_t)p->adc_value);
|
|
||||||
LL_DMA_EnableChannel(p->dma, p->dma_channel);
|
|
||||||
|
|
||||||
LL_ADC_ClearFlag_OVR(p->adc);
|
LL_ADC_ClearFlag_OVR(p->adc);
|
||||||
LL_ADC_ClearFlag_EOC(p->adc);
|
|
||||||
LL_ADC_REG_StartConversion(p->adc); // 开始转换
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
|
|
||||||
#ifndef __ADCS_H__
|
#ifndef __ADCS_H__
|
||||||
#define __ADCS_H__
|
#define __ADCS_H__
|
||||||
|
|
||||||
#include "lib.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
|
|
||||||
#define ADC_CHANNEL_MAX 18 ///< Maximum number of ADC channels
|
#define ADC_CHANNEL_MAX 18 ///< Maximum number of ADC channels
|
||||||
|
@ -85,6 +82,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
ADC_TypeDef *adc; ///< ADC peripheral
|
ADC_TypeDef *adc; ///< ADC peripheral
|
||||||
DMA_TypeDef *dma; ///< DMA peripheral
|
DMA_TypeDef *dma; ///< DMA peripheral
|
||||||
|
uint32_t dma_stream; ///< DMA stream
|
||||||
uint32_t dma_channel; ///< DMA channel
|
uint32_t dma_channel; ///< DMA channel
|
||||||
adcs_channels_u channels; ///< ADC channels
|
adcs_channels_u channels; ///< ADC channels
|
||||||
uint32_t ovr_count; ///< ADC overflow count
|
uint32_t ovr_count; ///< ADC overflow count
|
||||||
|
@ -94,9 +92,6 @@ typedef struct
|
||||||
uint16_t adc_sum; ///< Channel acquisition count
|
uint16_t adc_sum; ///< Channel acquisition count
|
||||||
__IO uint16_t *adc_value; ///< Address to store ADC conversion results
|
__IO uint16_t *adc_value; ///< Address to store ADC conversion results
|
||||||
|
|
||||||
utime_ticks_t median_average_ticks; ///< Median average filtering ticks
|
|
||||||
utime_ticks_t median_ticks; ///< Median filtering ticks
|
|
||||||
utime_ticks_t average_ticks; ///< Average filtering ticks
|
|
||||||
} adcs_t;
|
} adcs_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +106,7 @@ typedef struct
|
||||||
* @param adc_cct The ADC continuous conversion mode.
|
* @param adc_cct The ADC continuous conversion mode.
|
||||||
* @param channels The number of ADC channels to be converted.
|
* @param channels The number of ADC channels to be converted.
|
||||||
*/
|
*/
|
||||||
extern void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels);
|
extern void adc_init(adcs_e num, ADC_TypeDef *adc, DMA_TypeDef *dma, uint32_t dma_stream, uint32_t dma_channel, uint16_t adc_cct, uint32_t channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the ADC conversion.
|
* @brief Starts the ADC conversion.
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
#define __BSP_H__
|
#define __BSP_H__
|
||||||
|
|
||||||
#include "gpios.h"
|
#include "gpios.h"
|
||||||
#include "dmas.h"
|
// #include "dmas.h"
|
||||||
// #include "adcs.h"
|
// #include "adcs.h"
|
||||||
// #include "dacs.h"
|
// #include "dacs.h"
|
||||||
// #include "tims.h"
|
// #include "tims.h"
|
||||||
// #include "pwms.h"
|
// #include "pwms.h"
|
||||||
#include "uarts.h"
|
// #include "uarts.h"
|
||||||
// #include "eeprom.h"
|
// #include "eeprom.h"
|
||||||
// #include "spis.h"
|
// #include "spis.h"
|
||||||
// #include "i2cs.h"
|
// #include "i2cs.h"
|
||||||
|
@ -29,4 +29,5 @@ typedef void (*pvd_irq_handle_cb)(void);
|
||||||
extern void pvd_configuration(uint32_t pwr_level, pvd_irq_handle_cb call); ///< Configures the Programmable Voltage Detector (PVD) module
|
extern void pvd_configuration(uint32_t pwr_level, pvd_irq_handle_cb call); ///< Configures the Programmable Voltage Detector (PVD) module
|
||||||
extern void pvd_irq_handle(void); ///< Handles the PVD interrupt
|
extern void pvd_irq_handle(void); ///< Handles the PVD interrupt
|
||||||
extern void disable_debug_interface(void); ///< Disables the debug interface
|
extern void disable_debug_interface(void); ///< Disables the debug interface
|
||||||
|
|
||||||
#endif ///< __BSP_H__
|
#endif ///< __BSP_H__
|
||||||
|
|
50
delay.c
50
delay.c
|
@ -10,6 +10,12 @@
|
||||||
|
|
||||||
#include "delay.h"
|
#include "delay.h"
|
||||||
|
|
||||||
|
#if USE_OS == 1
|
||||||
|
#include "os.h"
|
||||||
|
// 确保包含了 vPortSetupTimerInterrupt 函数的声明
|
||||||
|
extern void vPortSetupTimerInterrupt(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
// static uint16_t g_fac_ms = 0; // ms延时倍乘数,在os下,代表每个节拍的ms数
|
// static uint16_t g_fac_ms = 0; // ms延时倍乘数,在os下,代表每个节拍的ms数
|
||||||
static uint32_t g_fac_us = 0; /* us延时倍乘数 */
|
static uint32_t g_fac_us = 0; /* us延时倍乘数 */
|
||||||
|
|
||||||
|
@ -44,6 +50,49 @@ void delay_init(uint16_t sysclk)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_OS == 1
|
||||||
|
void delay_us(uint32_t nus)
|
||||||
|
{
|
||||||
|
uint32_t ticks;
|
||||||
|
uint32_t told, tnow, reload, tcnt = 0;
|
||||||
|
|
||||||
|
if ((0x0001 & (SysTick->CTRL)) == 0)
|
||||||
|
{
|
||||||
|
// 定时器未工作,初始化定时器
|
||||||
|
vPortSetupTimerInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
reload = SysTick->LOAD; // 获取重装载寄存器值
|
||||||
|
ticks = nus * g_fac_us; // 计算延时所需的SysTick计数
|
||||||
|
|
||||||
|
vTaskSuspendAll(); // 阻止OS调度,防止打断us延时
|
||||||
|
told = SysTick->VAL; // 获取当前数值寄存器值(开始时数值)
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
tnow = SysTick->VAL; // 获取当前数值寄存器值
|
||||||
|
if (tnow != told)
|
||||||
|
{ // 当前值不等于开始值说明已在计数
|
||||||
|
if (tnow < told)
|
||||||
|
{
|
||||||
|
tcnt += told - tnow; // 计数值 = 开始值 - 当前值
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcnt += reload - tnow + told; // 计数值 = 重装载值 - 当前值 + 开始值
|
||||||
|
}
|
||||||
|
told = tnow; // 更新开始值
|
||||||
|
if (tcnt >= ticks)
|
||||||
|
{
|
||||||
|
break; // 时间超过/等于要延迟的时间,则退出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xTaskResumeAll(); // 恢复OS调度
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
* @brief 延时nus
|
* @brief 延时nus
|
||||||
* @param nus: 要延时的us数.
|
* @param nus: 要延时的us数.
|
||||||
|
@ -79,6 +128,7 @@ void delay_us(uint32_t nus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 对指定的硬件定时器进行微秒级延时
|
* @brief 对指定的硬件定时器进行微秒级延时
|
||||||
|
|
2
delay.h
2
delay.h
|
@ -14,6 +14,8 @@
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "tims.h"
|
#include "tims.h"
|
||||||
|
|
||||||
|
#define USE_OS 0
|
||||||
|
|
||||||
void delay_init(uint16_t sysclk); /* 初始化延迟函数 */
|
void delay_init(uint16_t sysclk); /* 初始化延迟函数 */
|
||||||
void delay_ms(uint16_t nms); /* 延时nms */
|
void delay_ms(uint16_t nms); /* 延时nms */
|
||||||
void delay_us(uint32_t nus); /* 延时nus */
|
void delay_us(uint32_t nus); /* 延时nus */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#ifndef FREERTOS_CONFIG_H
|
#ifndef FREERTOS_CONFIG_H
|
||||||
#define FREERTOS_CONFIG_H
|
#define FREERTOS_CONFIG_H
|
||||||
|
#include "main.h"
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Application specific definitions.
|
* Application specific definitions.
|
||||||
*
|
*
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_IDLE_HOOK 0
|
#define configUSE_IDLE_HOOK 0
|
||||||
#define configUSE_TICK_HOOK 0
|
#define configUSE_TICK_HOOK 0
|
||||||
#define configCPU_CLOCK_HZ ((unsigned long)72000000)
|
#define configCPU_CLOCK_HZ ((unsigned long)SystemCoreClock)
|
||||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||||
#define configMAX_PRIORITIES (5)
|
#define configMAX_PRIORITIES (5)
|
||||||
#define configMINIMAL_STACK_SIZE ((unsigned short)128)
|
#define configMINIMAL_STACK_SIZE ((unsigned short)128)
|
||||||
|
|
|
@ -1,7 +1,34 @@
|
||||||
#ifndef __OS_H__
|
#ifndef __OS_H__
|
||||||
#define __OS_H__
|
#define __OS_H__
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t free_heap_size; ///< 空闲堆大小
|
||||||
|
uint32_t min_free_heap_size; ///< 最小空闲堆大小
|
||||||
|
uint32_t min_free_stack_size; ///< 最小空闲栈大小
|
||||||
|
} os_t;
|
||||||
|
|
||||||
|
static inline void os_read(os_t *os)
|
||||||
|
{
|
||||||
|
os->free_heap_size = xPortGetFreeHeapSize();
|
||||||
|
os->min_free_heap_size = xPortGetMinimumEverFreeHeapSize();
|
||||||
|
os->min_free_stack_size = uxTaskGetStackHighWaterMark(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁止任务抢占
|
||||||
|
static inline void os_task_preemption_disable(void)
|
||||||
|
{
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 允许任务抢占
|
||||||
|
static inline void os_task_preemption_enable(void)
|
||||||
|
{
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __OS_H__
|
#endif // __OS_H__
|
||||||
|
|
|
@ -1,3 +1,33 @@
|
||||||
# 移植
|
## 移植
|
||||||
|
|
||||||
https://blog.csdn.net/ctt15703065585/article/details/139291183
|
https://blog.csdn.net/ctt15703065585/article/details/139291183
|
||||||
|
|
||||||
|
## 创建任务
|
||||||
|
|
||||||
|
```c
|
||||||
|
static TaskHandle_t xxx_task_handle = NULL; // 定义任务句柄
|
||||||
|
static void xxx_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
vTaskDelay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void task_init()
|
||||||
|
{
|
||||||
|
// 创建任务
|
||||||
|
xTaskCreate((TaskFunction_t)xxx_task,
|
||||||
|
(const char *)"xxx_task",
|
||||||
|
(uint16_t)configMINIMAL_STACK_SIZE,
|
||||||
|
(void *)NULL,
|
||||||
|
(UBaseType_t)1,
|
||||||
|
(TaskHandle_t *)&xxx_task_handle);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 信号量
|
||||||
|
|
||||||
|
```c
|
||||||
|
|
||||||
|
```
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef __STORAGE_H__
|
#ifndef __STORAGE_H__
|
||||||
#define __STORAGE_H__
|
#define __STORAGE_H__
|
||||||
|
#include "sys.h"
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -34,7 +34,7 @@ typedef struct
|
||||||
BOOL(*read)
|
BOOL(*read)
|
||||||
(uint32_t addr, uint8_t *buf, uint16_t size);
|
(uint32_t addr, uint8_t *buf, uint16_t size);
|
||||||
BOOL(*write)
|
BOOL(*write)
|
||||||
(uint32_t addr, uint8_t * buf, uint16_t size);
|
(uint32_t addr, uint8_t *buf, uint16_t size);
|
||||||
BOOL(*erase_page)
|
BOOL(*erase_page)
|
||||||
(uint32_t page);
|
(uint32_t page);
|
||||||
} ops;
|
} ops;
|
||||||
|
|
|
@ -26,7 +26,6 @@ BOOL DBG_ASSERT(uint8_t cond _DBG_LINE_)
|
||||||
#else
|
#else
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
|
|
||||||
BOOL DBG_ASSERT(uint8_t cond _DBG_LINE_)
|
BOOL DBG_ASSERT(uint8_t cond _DBG_LINE_)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
|
9
sys.h
9
sys.h
|
@ -18,6 +18,15 @@
|
||||||
#define LOCK() __disable_irq() ///< 系统关全局中断
|
#define LOCK() __disable_irq() ///< 系统关全局中断
|
||||||
#define UNLOCK() __enable_irq() ///< 系统开全局中断
|
#define UNLOCK() __enable_irq() ///< 系统开全局中断
|
||||||
|
|
||||||
|
#ifndef __NOP
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief No Operation
|
||||||
|
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP() __ASM volatile("nop")
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t pll_source;
|
uint32_t pll_source;
|
||||||
|
|
Loading…
Reference in New Issue