📄 main.c
字号:
#define CLEAR_INT_MARK() { EXTINT = 0x02; VICVectAddr = 0x00;}
#include "..\ARM\config.h"
#include "..\LED\LED.h"
#include "..\ARM\LPC214x.h"
#include "..\VS1003\vs1003.h"
#include "..\CH375\CH375.h"
#include "..\CH375\CH375HFM.h"
#include "..\LGDP4216\LGDP4216.h"
#define TaskStartStkLength 512
#define TaskStkLength 128 // 定义用户任务堆栈长度
#define TaskStartPrio 1
#define VS1003SemFlag 1
#define CH375SemFlag 2
#define LGDP4216SemFlag 4
OS_STK TaskStartStk[TaskStartStkLength]; // 定义用户任务 打印统计信息任务的堆栈
OS_STK TerminalTaskStk[TaskStkLength];
OS_STK CH375TaskStk[TaskStkLength]; // 定义用户任务 U盘读取任务的堆栈
OS_STK VS1003TaskStk[TaskStkLength]; // 定义用户任务 音乐播放任务的堆栈
OS_STK DisplayTaskStk[TaskStkLength]; //定义用户任务 显示任务的堆栈
static void AppTerminalRx(INT8U data);
INT8U AppTerminalRxMboxData;
INT8U PlayCtrlData;
OS_EVENT *AppTerminalRxMbox;
OS_FLAG_GRP *SemFlag;
uint8 err;
uint8 Spe[14];
uint8 SpeFlag;
void TaskStart(void *pdata);
void TerminalTask(void *pdata);
void CH375Task(void *pdata); // U盘读取任务
void VS1003Task(void *pdata); // 音乐播放任务
void DisplayTask(void *pdata); // 显示任务
static void AppTerminalRx(INT8U data)
{
AppTerminalRxMboxData = data;
OSMboxPost(AppTerminalRxMbox, &AppTerminalRxMboxData);
}
/* 检查操作状态,如果错误则显示错误代码并停机 */
void mStopIfError( unsigned char iError )
{
if ( iError == ERR_SUCCESS ) return; /* 操作成功 */
//printf( "Error: 0x%02X\r\n", iError ); /* 显示错误 */
while ( 1 ) {
LED_OUT_ACT( ); /* LED闪烁 */
OSTimeDly( OS_TICKS_PER_SEC / 10 );
LED_OUT_INACT( );
OSTimeDly( OS_TICKS_PER_SEC / 10 );
}
}
#if LIB_CFG_INT_EN == 1
void init_eint1() {
PINSEL0 = (PINSEL0 & (~(0x03 << 6))) | (0x03 << 6); // 选择 EINT1
VICVectAddr1 = (unsigned long)CH375Interrupt; // 设置中断处理方法地址
VICVectCntl1 = 0x20 | 0x0F; // 设置使用1号中断向量寄存器
VICIntEnable = 0x01 << 0x0F; // 开启1号中断
}
#endif
int main (void)
{
#if OS_VERSION > 276
#if OS_TASK_NAME_SIZE > 0
INT8U err;
#endif
#endif
SCS = 0x03;
TargetInit(); //初始化硬件
OSInit(); //初始化 uC/OS-II
OSTaskCreateExt(TaskStart,
(void *)0,
&TaskStartStk[TaskStartStkLength - 1],
TaskStartPrio,
TaskStartPrio,
&TaskStartStk[0],
TaskStartStkLength,
(void *)0,
OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR );
#if OS_VERSION > 276
#if OS_TASK_NAME_SIZE > 14
OSTaskNameSet(TaskStartPrio, (INT8U *)"Start Task", &err);
#else
#if OS_TASK_NAME_SIZE > 7
OSTaskNameSet(TaskStartPrio, (INT8U *)"Start", &err);
#endif
#endif
#endif
//创建起动任务
OSStart();
return 0; //开始多任务
}
void TaskStart(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 //Allocate storage for CPU status register
OS_CPU_SR cpu_sr;
#endif
#if OS_VERSION > 276
#if OS_TASK_NAME_SIZE > 0
INT8U err;
#endif
#endif
#if OS_TASK_STAT_EN > 0
OSStatInit(); /* Determine CPU capacity */
#endif
#if OS_VIEW_MODULE > 0
OSView_Init();
OSView_TerminalRxSetCallback(AppTerminalRx);
OSView_RxIntEn(); /* Enable Rx Interrupts */
#endif
SemFlag = OSFlagCreate(VS1003SemFlag | LGDP4216SemFlag, &err);
AppTerminalRxMbox = OSMboxCreate((void *)0);
OSTaskCreateExt(CH375Task,
(void *)0,
&CH375TaskStk[TaskStkLength - 1],
4,
4,
&CH375TaskStk[0],
TaskStkLength,
(void *)0,
OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR );
OSTaskCreateExt(VS1003Task,
(void *)0,
&VS1003TaskStk[TaskStkLength - 1],
5,
5,
&VS1003TaskStk[0],
TaskStkLength,
(void *)0,
OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR );
OSTaskCreateExt(TerminalTask,
(void *)0,
&TerminalTaskStk[TaskStkLength - 1],
6,
6,
&TerminalTaskStk[0],
TaskStkLength,
(void *)0,
OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR );
OSTaskCreateExt(DisplayTask,
(void *)0,
&DisplayTaskStk[TaskStkLength - 1],
7,
7,
&DisplayTaskStk[0],
TaskStkLength,
(void *)0,
OS_TASK_OPT_STK_CHK+OS_TASK_OPT_STK_CLR );
#if OS_VERSION > 276
#if OS_TASK_NAME_SIZE > 14
OSTaskNameSet(4, (INT8U *)"CH375 Task", &err);
OSTaskNameSet(5, (INT8U *)"VS1003 Task", &err);
OSTaskNameSet(6, (INT8U *)"Terminal Task", &err);
OSTaskNameSet(7, (INT8U *)"Display Task", &err);
#endif
#endif
while(1){
OSTimeDly(OS_TICKS_PER_SEC / 10);
}
}
void TerminalTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
char s[100];
INT8U *key;
INT8U err;
pdata = pdata; /* Prevent compiler warning */
while (TRUE) {
key = (INT8U *)OSMboxPend(AppTerminalRxMbox, 0, &err);
switch (*key) {
case '1':
sprintf(s, "\nCPU Usage = %3u%%\n", OSCPUUsage);
OSView_TxStr(s, 1);
break;
case '2':
sprintf(s, "\n#Tasks = %3u\n", OSTaskCtr);
OSView_TxStr(s, 1);
break;
case 'n':
PlayCtrlData |= 0x01;
OSView_TxStr("\nNext song.\n", 1);
break;
default:
OSView_TxStr("\n\nMicrium, Inc.", 1);
OSView_TxStr("\n1: CPU Usage (%)", 1);
OSView_TxStr("\n2: #Tasks", 1);
OSView_TxStr("\n?: Help (This menu)\n", 1);
break;
}
}
}
//U盘读取任务
void CH375Task (void *pdata)
{
INT8U searchFileIndex, ch375Result, readSecCount, nameLen, i;
char *pCodeStr, *pExt;
pdata = pdata;
InitLGDP4216Port();
LGDP4216UnSelect();
//printf( "UART init finish.\r\n" );
//printf( "Start\r\n" );
CH375_PORT_INIT( );
#if LIB_CFG_INT_EN == 1
init_eint1();
#endif
LED_OUT_INIT( );
LED_OUT_ACT( ); /* 开机后LED亮一下以示工作 */
OSTimeDly(OS_TICKS_PER_SEC / 10); /* 延时100毫秒 */
LED_OUT_INACT( );
//printf( "CH375 Reset.\r\n" );
CH375Reset();
//printf( "CH375Lib init begin.\r\n" );
ch375Result = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */
//printf( "CH375Lib init finish.\r\n" );
mStopIfError( ch375Result );
//printf( "Wait Udisk\r\n" );
#if LIB_CFG_INT_EN == 1
while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 查询CH375中断并更新中断状态,等待U盘插入 */
#else
while ( CH375DiskStatus < DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘插入 */
if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */
OSTimeDly( OS_TICKS_PER_SEC / 10 );
}
#endif
while ( 1 ) {
// buttonState = BUTTON_CLICK_CLR;
LED_OUT_ACT( ); /* LED亮 */
OSTimeDly( OS_TICKS_PER_SEC / 20 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */
/* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */
for ( i = 0; i < 10; i++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */
OSTimeDly( OS_TICKS_PER_SEC / 10 );
//printf( "Ready ?\r\n" );
if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */
}
pCodeStr = (char *)"\\*"; /* 列出根目录下的文件 */
//printf( "List file %s\r\n", pCodeStr );
for ( searchFileIndex = 0; searchFileIndex < 255; searchFileIndex++ ) { /* 最多搜索前255个文件 */
strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr ); /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */
i = strlen( (char const *)mCmdParam.Open.mPathName ); /* 计算文件名长度,以处理文件名结束符 */
mCmdParam.Open.mPathName[ i ] = searchFileIndex; /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */
ch375Result = CH375FileOpen( ); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */
if ( ch375Result == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */
if ( ch375Result == ERR_FOUND_NAME ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */
nameLen = strlen( (char const *)mCmdParam.Open.mPathName );
if(nameLen < 4) continue;
pExt = ((char *)mCmdParam.Open.mPathName) + nameLen - 4;
if(strcmp(pExt, (char *)".MP3") == 0 || strcmp(pExt, (char *)".WMA") == 0 || strcmp(pExt, (char *)".WAV") == 0) {
//printf( " Play song %03d#: %s\r\n", (unsigned int)searchFileIndex, mCmdParam.Open.mPathName );
ch375Result = CH375FileOpen( ); /* 打开文件 */
if ( ch375Result != ERR_MISS_DIR && ch375Result != ERR_MISS_FILE ) {
mStopIfError( ch375Result );
//printf( " Song file size: %ld bytes.\r\n", CH375vFileSize);
readSecCount = FILE_DATA_BUF_LEN / 512;
while(1) {
if((PlayCtrlData & 0x01) == 1)
{
PlayCtrlData &= ~0x01;
break;
}
OSFlagPend(SemFlag, (OS_FLAGS)(VS1003SemFlag | LGDP4216SemFlag), OS_FLAG_WAIT_SET_ALL, 0, &err);
OSFlagPost(SemFlag, (OS_FLAGS)(VS1003SemFlag | LGDP4216SemFlag), OS_FLAG_CLR, &err);
mCmdParam.Read.mSectorCount = readSecCount;
ch375Result = CH375FileRead();
mStopIfError( ch375Result );
if ( mCmdParam.Read.mSectorCount < 1 )
{
OSFlagPost(SemFlag, (OS_FLAGS)(CH375SemFlag | LGDP4216SemFlag), OS_FLAG_SET, &err);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -