OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4426|回复: 4

用UCOSIII在STM32F103上实现音乐播放频谱的显示,结果只出现了白屏,不知哪里有错误,请各位大神帮忙

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-12-23
在线时间
1 小时
发表于 2017-2-27 15:16:00 | 显示全部楼层 |阅读模式
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();
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165287
金钱
165287
注册时间
2010-12-1
在线时间
2107 小时
发表于 2017-2-27 21:40:16 | 显示全部楼层
调试,找液晶初始化过程,是否有异常,然后看显示代码。
回复

使用道具 举报

1

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-2-2
在线时间
20 小时
发表于 2017-3-29 21:20:09 | 显示全部楼层
分段一步步调试
回复

使用道具 举报

酷儿 该用户已被删除
发表于 2017-4-12 10:55:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-10
在线时间
4 小时
发表于 2019-4-11 21:31:19 | 显示全部楼层
老哥不知道你有没实现音乐频谱的显示,求教
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-2 08:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表