#include "public.h"

#define FFT_POINT 	(256)

static uint16_t _DmaBuffer[FFT_POINT];
static uint16_t _AdcBuffer[FFT_POINT];
static uint8_t F_DMA_TC; static int32_t FFT_InBuffer[FFT_POINT];
static int32_t FFT_OutBuffer[FFT_POINT];
#define FFT_MagBuffer _AdcBuffer static void _InitClk(void) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
} static void _InitGpio(void) {
SocGpio_SetMode(SocGpio_GetPinIndex(0<<4|1), INPUT_MODE_AIN);
SocGpio_SetMode(SocGpio_GetPinIndex(0<<4|0), OUTPUT_MODE_PUSH_PULL);
} static void _InitDMA(void) {
DMA_InitTypeDef def; // 初始化
def.DMA_PeripheralBaseAddr = (uint32_t)(&ADC1->DR); // 外设地址
def.DMA_MemoryBaseAddr = (uint32_t)(&_DmaBuffer[0]); // 内存地址
def.DMA_DIR = DMA_DIR_PeripheralSRC; // 从外设复制到内存
def.DMA_BufferSize = ASIZE(_DmaBuffer); // 内存元素个数
def.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址固定
def.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
def.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设元素大小16字节
def.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存元素大小16字节
def.DMA_Mode = DMA_Mode_Circular; // 循环采集
def.DMA_Priority = DMA_Priority_High; // 循环
def.DMA_M2M = DMA_M2M_Disable; // 外设到内存
DMA_Init(DMA1_Channel1, &def); // 中断
NVIC_SetPriority(DMA1_Channel1_IRQn, 0);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
DMA_ClearFlag(DMA1_FLAG_TC1);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE);
} static void _InitAdc(void) {
ADC_InitTypeDef def; // 初始化
ADC_StructInit(&def);
def.ADC_Mode = ADC_Mode_Independent; // 独立模式
def.ADC_ScanConvMode = DISABLE; // 单通道
def.ADC_ContinuousConvMode = DISABLE; // 定时器触发,不连续转换
def.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;// 转换不受外界决定
def.ADC_DataAlign = ADC_DataAlign_Right; // 右对齐
def.ADC_NbrOfChannel = 1; // 扫描通道数
ADC_Init(ADC1, &def); // 通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); // 校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1)); } static void _InitTim(void) {
TIM_TimeBaseInitTypeDef def;
TIM_TimeBaseStructInit(&def); def.TIM_Period = 100-1;
def.TIM_Prescaler = 72-1;
def.TIM_ClockDivision = TIM_CKD_DIV1;
def.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &def); TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); TIM_Cmd(TIM3, ENABLE);
} void cr4_fft_256_stm32(void *pssOUT, void *pssIN, u16 Nbin); static void _FFT_Proc(void) {
for (uint16_t i = 0; i < FFT_POINT; i++) {
FFT_InBuffer[i] = (_AdcBuffer[i]-1990) << 16;
}
#if 0
printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
FFT_InBuffer[1], FFT_InBuffer[2], FFT_InBuffer[3], FFT_InBuffer[4],
FFT_InBuffer[5], FFT_InBuffer[6], FFT_InBuffer[7], FFT_InBuffer[8],
FFT_InBuffer[9], FFT_InBuffer[10], FFT_InBuffer[11], FFT_InBuffer[12]);
#endif
cr4_fft_256_stm32(FFT_OutBuffer, FFT_InBuffer, FFT_POINT); #if 0
printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
_AdcBuffer[1], _AdcBuffer[2], _AdcBuffer[3], _AdcBuffer[4],
_AdcBuffer[5], _AdcBuffer[6], _AdcBuffer[7], _AdcBuffer[8],
_AdcBuffer[9], _AdcBuffer[10], _AdcBuffer[11], _AdcBuffer[12]);
#endif
} #if 0
void GetPowerMag(void)
{
signed short lX,lY;
float X,Y,Mag;
unsigned short i; for(i=0; i<NPT; i++)
{
lX = (lBufOutArray[i] << 16) >> 16;
lY = (lBufOutArray[i] >> 16); //除以32768再乘65536是为了符合浮点数计算规律
X = NPT * ((float)lX) / 32768;
Y = NPT * ((float)lY) / 32768;
Mag = sqrt(X * X + Y * Y)*1.0/ NPT;
if(i == 0)
lBufMagArray[i] = (unsigned long)(Mag * 32768);
else
lBufMagArray[i] = (unsigned long)(Mag * 65536);
}
}
#endif static void _Send(uint8_t ch) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1, ch);
} // STEP:39Hz
static void _FFT_GetMag(void) {
int16_t x, y;
for (uint16_t i = 1; i <= 64; i++) {
x = FFT_OutBuffer[i]&0xFFFF;
y = FFT_OutBuffer[i]>>16;
//printf("%d: %d, %d\n", i, x, y);
FFT_MagBuffer[i] = sqrt(x*x + y*y); // 存在超过25为有信号, 需要连续好几个周期的判断,以便防抖
}
} void SocAdc_Init(void) {
_InitClk();
_InitGpio();
_InitDMA();
_InitAdc();
_InitTim(); ADC_SoftwareStartConvCmd(ADC1, ENABLE);
} void SocAdc_Main(void) {
if (F_DMA_TC) {
F_DMA_TC = 0;
memcpy(_AdcBuffer, _DmaBuffer, sizeof(_DmaBuffer));
GPIOA->BSRR = GPIO_Pin_0;
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
_FFT_Proc();
_FFT_GetMag(); #if 1
_Send(0xFF);
for (uint16_t i = 1; i <= 64; i++) { // 不要第一个分量
if (FFT_MagBuffer[i] > 0xFE) {
_Send(0xFE);
} else {
_Send(FFT_MagBuffer[i]);
}
}
#endif #if 0
printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
FFT_MagBuffer[1], FFT_MagBuffer[2], FFT_MagBuffer[3], FFT_MagBuffer[4],
FFT_MagBuffer[5], FFT_MagBuffer[6], FFT_MagBuffer[7], FFT_MagBuffer[8],
FFT_MagBuffer[9], FFT_MagBuffer[10], FFT_MagBuffer[11], FFT_MagBuffer[12]);
#endif
}
} // DMA的ADC通道中断
void DMA1_Channel1_IRQHandler(void) {
if (DMA_GetFlagStatus(DMA1_FLAG_TC1)) {
DMA_ClearFlag(DMA1_FLAG_TC1);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
F_DMA_TC = 1;
GPIOA->BRR = GPIO_Pin_0;
}
}

最新文章

  1. js 数组去重(7种)
  2. Trie字典树 动态内存
  3. 模块在insmod之后无法rmmod问题
  4. (转)浅谈MD5加密算法中的加盐值(SALT)
  5. windows 服务安装脚本拾遗
  6. 使用JsonObject解析json
  7. hdu 3280 动态规划
  8. cheerio返回数据格式
  9. XQuery FLWOR 表达式
  10. 网页设计之PS画渐变线条
  11. tomcat升级,tomcat窗体改名,一台电脑安装多版本JDK
  12. 一个Ruby静态代码分析器 rubocop
  13. 201521123013 《Java程序设计》第12周学习总结
  14. 那些年踩过的WebAPI的坑(一)
  15. fs检测文件夹状态
  16. Objective-C代码简写
  17. C# [LINQ] Linq Expression 获取多格式文件
  18. 腾讯云部署keepalived高可用
  19. 【算法】解析IEEE 754 标准
  20. C#编码、解码与ASP.NET编码解码对应函数

热门文章

  1. 基于Spring-AOP的自定义分片工具
  2. psutil.AccessDenied: psutil.AccessDenied
  3. 【数据库】union和union all合并结果操作
  4. MetaTown:一个可以自己构建数字资产的平台
  5. mouseMove模拟拖拽,封装指令
  6. linux安装Erlang和Rabbitmq以及安装问题解决
  7. 五年经验的前端社招被问:CPU 和 GPU 到底有啥区别?
  8. 记一次 .NET 某安全生产信息系统 CPU爆高分析
  9. java中的instanceof方法
  10. 使用linux的ffmpeg进行B站直播推流