新手入门
积分 13
金钱 13
注册时间 2016-12-23
在线时间 1 小时
1 金钱
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "adc.h"
#include "stm32_dsp.h"
#include <math.h>
#include "ff.h"
#include "sdio_sdcard.h"
#include "w25qxx.h"
#include "exfuns.h"
#include "text.h"
#include "vs10xx.h"
#include "mp3player.h"
#include "malloc.h"
#include "includes.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//任务优先级
#define START_TASK_PRIO 3
//任务堆栈大小
#define START_STK_SIZE 128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);
//任务优先级
#define TASK1_TASK_PRIO 4
//任务堆栈大小
#define TASK1_STK_SIZE 128
//任务控制块
OS_TCB Task1_TaskTCB;
//任务堆栈
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);
//任务优先级
#define TASK2_TASK_PRIO 4
//任务堆栈大小
#define TASK2_STK_SIZE 128
//任务控制块
OS_TCB Task2_TaskTCB;
//任务堆栈
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//任务函数
void task2_task(void *p_arg);
#define DOUBLE_COLOR 1 //是否为双色屏,若为双色屏则改为1
#define NPT 64 //FFT采样点数
#define GREEN_STOP_TIME 15 //绿色点顶端停顿时间,值越大时间越长
#define GREEN_SUB_SPEED 100 //绿色点下移速度,值越大速度越慢
#define RED_SUB_SPEED 50 //红色频柱向下缩短速度,值越大速度越慢
uint32_t ADC_DataNum=0; //ADC采样点数
uint32_t RedTime=0; //红色点下移时间变量
#if DOUBLE_COLOR
uint32_t GreenTime=0; //绿色点下移时间变量
uint32_t GreenStopTime[32]={0}; //绿色点顶端停顿时间数据
#endif
volatile uint8_t ADC_TimeOutFlag=1; //ADC定时采样时间到标志
extern __IO uint16_t ADCConvertedValue; //ADC采样值
extern int LCD_COLOR;
long lBUFMAG[NPT+NPT/2]; //存储求模后的数据
long lBUFOUT[NPT];//FFT输出序列
long lBUFIN[NPT];//FFT输入系列
uint8_t fftHightRedBuf[NPT/2]={0}; //红色频柱高度数组
uint8_t DisplayRedDataBuf[32*8]={0}; //红色显示缓冲区
#if DOUBLE_COLOR
uint8_t fftHightGreenBuf[NPT/2]={0}; //绿色频点高度数组
uint8_t DisplayGreenDataBuf[32*8]={0}; //绿色显示缓冲区
#endif
u16 color_tab[16]={DARKBLUE,BLUE,LIGHTBLUE,GREEN,LIGHTGREEN,RED,BRED,BRRED,BLACK,YELLOW,CYAN,MAGENTA,GRAYBLUE,LGRAYBLUE,BROWN,LGRAY};
void music_fft_main(uint8_t *RedNewHeight,uint8_t *GreenNewHeight)
{
int BarWidth = 8;
int i=0;
int j=0;
static uint8_t RedOldHeight[32] = {0};
static uint8_t GreenOldHeight[32] = {0};
for(i=0;i<32;i++)
{
//清除之前的绿色方块
//LCD_COLOR = LCD_COLOR_BLACK;
LCD_Fill(GreenOldHeight[i],(BarWidth+2)*i,GreenOldHeight[i]+3,(BarWidth+2)*i+BarWidth,WHITE);
//显示当前的绿色方块
LCD_Fill(GreenNewHeight[i],(BarWidth+2)*i,GreenNewHeight[i]+3,(BarWidth+2)*i+BarWidth,color_tab[16-j]);
//显示红色柱
if(RedNewHeight[i]>RedOldHeight[i]){//如果当前的绿色柱子高度比之前的大则补齐绿色柱子
LCD_Fill(RedOldHeight[i],(BarWidth+2)*i,RedNewHeight[i],(BarWidth+2)*i+BarWidth,color_tab[j]);
}else{//如果当前显示的绿色柱子高度小于之前的柱子则需要将多余的绿色柱子用背景色填充
LCD_Fill(RedNewHeight[i],(BarWidth+2)*i,RedOldHeight[i],(BarWidth+2)*i+BarWidth,WHITE);
}
//将新数据保存
RedOldHeight[i] = RedNewHeight[i];
GreenOldHeight[i] = GreenNewHeight[i];
if(j>=15)
j=0;
j++;
}
}
void powerMag(long nfill)//计算各谐波幅值
{ int32_t lX,lY;
uint32_t i;
for (i=0; i < nfill; i++)
{
lX= (lBUFOUT[i]<<16)>>16; /* sine_cosine --> cos */ //低16位
lY= (lBUFOUT[i] >> 16); /* sine_cosine --> sin */ //高16位
{
float X= 64*((float)lX)/32768;
float Y = 64*((float)lY)/32768;
float Mag = sqrt(X*X+ Y*Y)/nfill; // 先平方和,再开方
lBUFMAG[i] = (long)(Mag*65536);
}
}
}
int main(void)
{
OS_ERR err;
CPU_SR_ALLOC();
uint32_t i=0;
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
LED_Init(); //LED端口初始化
TIM2_Configuration();
TIM2_NVIC_Configuration();
FFT_RCC_Configuration();
FFT_GPIO_Configuration();
FFT_DMA_Init();
FFT_ADC_Init();
LCD_Init();
W25QXX_Init(); //初始化W25Q128
VS_Init(); //初始化VS1053
my_mem_init(SRAMIN); //初始化内部内存池
exfuns_init(); //为fatfs相关变量申请内存
f_mount(fs[0],"0:",1); //挂载SD卡
f_mount(fs[1],"1:",1); //挂载FLASH.
POINT_COLOR=RED;
// BACK_COLOR=BLACK;
TIM_Cmd(TIM2, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
OSInit(&err); //初始化UCOSIII
OS_CRITICAL_ENTER();//进入临界区
//创建开始任务
OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块
(CPU_CHAR * )"start task", //任务名字
(OS_TASK_PTR )start_task, //任务函数
(void * )0, //传递给任务函数的参数
(OS_PRIO )START_TASK_PRIO, //任务优先级
(CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址
(CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位
(CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小
(OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
(OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度,
(void * )0, //用户补充的存储区
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
(OS_ERR * )&err); //存放该函数错误时的返回值
OS_CRITICAL_EXIT(); //退出临界区
OSStart(&err); //开启UCOSIII
}
//开始任务函数
void start_task(void *p_arg)
{
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err); //统计任务
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间
CPU_IntDisMeasMaxCurReset();
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候
//使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endif
OS_CRITICAL_ENTER(); //进入临界区
//创建TASK1任务
OSTaskCreate((OS_TCB * )&Task1_TaskTCB,
(CPU_CHAR * )"Task1 task",
(OS_TASK_PTR )task1_task,
(void * )0,
(OS_PRIO )TASK1_TASK_PRIO,
(CPU_STK * )&TASK1_TASK_STK[0],
(CPU_STK_SIZE)TASK1_STK_SIZE/10,
(CPU_STK_SIZE)TASK1_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )2, //2个时间片,既2*5=10ms
(void * )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR * )&err);
//创建TASK2任务
OSTaskCreate((OS_TCB * )&Task2_TaskTCB,
(CPU_CHAR * )"task2 task",
(OS_TASK_PTR )task2_task,
(void * )0,
(OS_PRIO )TASK2_TASK_PRIO,
(CPU_STK * )&TASK2_TASK_STK[0],
(CPU_STK_SIZE)TASK2_STK_SIZE/10,
(CPU_STK_SIZE)TASK2_STK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )2, //2个时间片,既2*5=10ms
(void * )0,
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
(OS_ERR * )&err);
OS_CRITICAL_EXIT(); //退出临界区
OSTaskDel((OS_TCB*)0,&err); //删除start_task任务自身
}
void task1_task(void *p_arg)
{
u8 i,task1_num=0;
OS_ERR err;
p_arg = p_arg;
POINT_COLOR=RED;
while(1)
{
LED1=0;
LED1=1;
mp3_play();
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
}
}
void task2_task(void *p_arg)
{
u8 i,task2_num=0;
OS_ERR err;
p_arg = p_arg;
POINT_COLOR = RED;
while(1)
{
if(ADC_TimeOutFlag){
#if DOUBLE_COLOR
GreenTime++;
#endif
RedTime++;
ADC_TimeOutFlag=0;
if(ADC_DataNum<NPT){//采样点没有达到所要求的点
// ADC1->CR2 |= 0x00500000;//
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的软件转换启动功能
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); //判断传输完成
/* Clear channel1 transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC1);//清除通道1传输完成标志
// ADC1->CR2 &= 0xFFAFFFFF;//
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
lBUFIN[ADC_DataNum]=ADCConvertedValue<<16;
ADC_DataNum++;
}else{
TIM_Cmd(TIM2, DISABLE);
ADC_DataNum=0;
cr4_fft_64_stm32(lBUFOUT,lBUFIN,NPT);//调用STM32的DSP库作FFT变换
powerMag(NPT);//计算频点幅值
//更新红色点的高度
for(i=0;i<NPT/2;i++){
if((uint8_t)(lBUFMAG[i])>fftHightRedBuf[i]){
fftHightRedBuf[i]=(lBUFMAG[i]);
}
#if DOUBLE_COLOR
//刷新绿色点高度
if(fftHightRedBuf[i]>=fftHightGreenBuf[i]){
fftHightGreenBuf[i]=fftHightRedBuf[i];
GreenStopTime[i]=GREEN_STOP_TIME;//绿点停顿时间
if(fftHightRedBuf[i]>=235){
fftHightGreenBuf[i]=235;
fftHightRedBuf[i]=235;
}
}
#else
if(fftHightRedBuf[i]>=239){
fftHightRedBuf[i]=239;
}
#endif
}
//显示红色柱子
music_fft_main(fftHightRedBuf,fftHightGreenBuf);
//显示绿色点
#if DOUBLE_COLOR
//绿色点下移
if((GreenTime>GREEN_SUB_SPEED)){ //绿色点下降间隔时间
GreenTime=0;
for(i=0;i<NPT/2;i++){
if((fftHightGreenBuf[i]!=0)&&(GreenStopTime[i]==0)){
fftHightGreenBuf[i]--;
}
}
}
#endif
//红色下移
if(RedTime>RED_SUB_SPEED){
RedTime=0;
for(i=0;i<NPT/2;i++){
if((fftHightRedBuf[i]!=0)){
fftHightRedBuf[i]--;
}
}
}
//绿色点停顿时间减一
#if DOUBLE_COLOR
for(i=0;i<NPT/2;i++){
if(GreenStopTime[i]!=0){
GreenStopTime[i]--;
}
}
#endif
TIM_Cmd(TIM2, ENABLE);//使能定时2外设
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
}
}
}
}
//定时器2中断服务程序
void TIM2_IRQHandler(void)//TIM2中断
{
OSIntEnter();
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
// TIM2->SR = (uint16_t)~TIM_FLAG_Update; //检查tim2更新中断发生与否
TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update); //清中断
ADC_TimeOutFlag=1;
}
OSIntExit();
}
我来回答