1、MP3软件解码部分核心代码:
int mp3_decoder_run(struct mp3_decoder* decoder)
{
result = rt_sem_take(&pause, RT_WAITING_FOREVER); //暂停功能所使用的信号量
if (result != RT_EOK)
{
printf(" semaphore: pause wait failed./r/n");
}
rt_sem_release(&pause);
decoder->read_offset = MP3FindSyncWord(decoder->read_ptr, decoder->bytes_left); //MP3帧同步
err = MP3Decode(decoder->decoder, &decoder->read_ptr,
(int*)&decoder->bytes_left, (short*)buffer, 0);
delta += (decoder->bytes_left_before_decoding - decoder->bytes_left); //解码MP3,数据放入buffer中
decoder->frames++; //下一帧
result = rt_sem_take(&s_semForPlay, RT_WAITING_FOREVER); //传送给PCM1770时使用的信号量,当数据传输完毕时,被释放,接着开始下一次传输
DMA_Transmit((u32 )(buffer), outputSamps );
}
void DMA1_Channel5_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC5)==SET)
{
rt_sem_release(&s_semForPlay); //释放信号量,唤醒mp3解码线程,开始下一次传输
}
}
2、读卡器部分核心代码:
uint16_t MAL_Init(uint8_t lun)
{
switch (lun)
{
case 0:
return MAL_OK;
default:
return MAL_FAIL;
}
}
uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
{
switch (lun)
{
case 0:
dev_sdio->write(dev_sdio,Memory_Offset/Mass_Block_Size[0],Writebuff,Transfer_Length/Mass_Block_Size[0]); //调用操作系统写函数
break;
default:
return MAL_FAIL;
}
return MAL_OK;
}
uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
{
switch (lun)
{
case 0: dev_sdio->read(dev_sdio,Memory_Offset/Mass_Block_Size[0],Readbuff,Transfer_Length/Mass_Block_Size[0]); //调用操作系统读函数
break;
default:
return MAL_FAIL;
}
return MAL_OK;
}
uint16_t MAL_GetStatus (uint8_t lun)
{
switch(lun)
{
case 0:
return MAL_OK;
default:
return MAL_FAIL;
}
}
3、网络播放部分核心代码:
static rt_size_t http_fetch(rt_uint8_t* ptr, rt_size_t len, void* parameter) //读取回调函数
{
struct http_session* session = (struct http_session*)parameter;
return http_session_read(session, ptr, len);
}
static void http_close(void* parameter) //关闭回调函数
{
struct http_session* session = (struct http_session*)parameter;
http_session_close(session);
}
rt_size_t http_data_fetch(void* parameter, rt_uint8_t *buffer, rt_size_t length) //mp3取数据回调函数
{
return net_buf_read(buffer, length);
}
void http_mp3(char* url)
{
struct http_session* session;
struct mp3_decoder* decoder;
session = http_session_open(url); //打开URL
if (session != RT_NULL)
{
if (net_buf_start_job(http_fetch, http_close, (void*)session) == 0) //启动一个网络下载功能,绑定读取,关闭回调函数
{
decoder = mp3_decoder_create(); //创建结构体
if (decoder != RT_NULL)
{
decoder->fetch_data = http_data_fetch; //绑定取数据回调函数
decoder->fetch_parameter = RT_NULL;
current_offset = 0;
while (mp3_decoder_run(decoder) != -1); //开始解码,播放
/* delete decoder object */
mp3_decoder_delete(decoder);
}
session = RT_NULL;
}
}
}
4、红外遥控部分核心代码:
static void TIM5_Configuration(void) //捕获定时器设定
{
/* 时钟及分频设置 */
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time Base configuration */
/* 72M/720 = 0.01ms */
TIM_TimeBaseStructure.TIM_Prescaler = 720-1;
//计数模式:向上计数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//重新计数的起始值
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
}
/* 捕获设置 */
{
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;/* 每次检测到捕获输入就触发一次捕获 */
TIM_ICInitStructure.TIM_ICFilter = 8;/* 滤波 */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;//选择通道3
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;//下降沿
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//通道方向选择
TIM_ICInit(TIM5, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;//选择通道3
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;//通道方向选择
TIM_ICInit(TIM5, &TIM_ICInitStructure);
}
/* 输入触发源选择:外部输入触发 */
TIM_SelectInputTrigger(TIM5, TIM_TS_ETRF);//TIM_TS_ETRF 外部触发
/* 从模式-复位模式 */
/* TIM_SlaveMode_Reset 4:选中的触发输入(TRGI)的上升沿重新初始化计数器,并且产生一个更新寄存器的信号 */
TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM5, ENABLE);
/* Enable the CC3 and CC4 Interrupt Request */
TIM_ITConfig(TIM5, TIM_IT_CC3, ENABLE);
TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE);
}
/* remote isr */
void remote_isr(void) //定时器调用红外中断服务
{
static unsigned int clr_flag = 1; /* 是否需要清零标致,用来判断是否是某次捕获的起点. */
unsigned int tick_now = rt_tick_get();/* 获取当前时间戳.*/
/* 红外遥控下降沿 */
if(TIM_GetITStatus(TIM5, TIM_IT_CC3) == SET)
{
switch( rem_mode )
{
case 0:/* 未启动 */
break;
case 1:/* 自学习 */
break;
case 2://正常解码
if( ( rx_count>(remote_code_len_max-10) ) || tick_now>first_tick+10 ) //超时
{
rx_count = 0;
clr_flag = 1;
}
if(rx_count < remote_code_len_max )
{
rm_code[rx_count++] = TIM_GetCapture3(TIM5); //数据保存到缓冲区中
}
break;
default:
rem_mode = remote_mode_disable;/* 异常跳入,则关闭红外摇控 */
break;
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC3);
}
/* 红外遥控上升沿 */
if(TIM_GetITStatus(TIM5, TIM_IT_CC4) == SET)
{
switch( rem_mode )
{
case 0://未启动
break;
case 1://自学习
break;
case 2://正常解码
if( rx_count < remote_code_len_max )
{
rm_code[rx_count++] = TIM_GetCapture4(TIM5); //数据保存到缓冲区中
if( p_rem_code_src[0].len == rx_count)
{
rt_sem_release(&sem_IR);
}
}
break;
default:
rem_mode = remote_mode_disable;/* 异常跳入,则关闭红外摇控 */
break;
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC4);
}
}