我想当mp3停止播放后(mp3停止播放的代码是放在外部中断函数中),可以进行其他任何操作,所以加入了UCOSlll,利用系统来创建多线程,然而加了UCOSlll的任务挂起和恢复后,mp3仍然占用线程,就是不能进行任何的操作,本人弄了很久了,也弄不出来,希望有大神帮忙解答一下。。。
这是main.c的代码,用到UCOSlll的代码标红了:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "lcd.h"
#include "key.h"
#include "touch.h"
#include "malloc.h"
#include "usmart.h"
#include "MMC_SD.h"
#include "ff.h"
#include "exfuns.h"
#include "fontupd.h"
#include "text.h"
#include "usart2.h"
#include "AS608.h"
#include "timer.h"
#include "vs10XX.h"
#include "mp3player.h"
#include "jidianqi.h"
#include "hongwai.h"
#include "exti.h"
#include "lianjie32.h"
#include "led.h"
#include "24cxx.h"
#include "myiic.h"
#include "includes.h"
//ALIENTEK Mini STM32开发板扩展实验14
//ATK-AS608指纹识别模块实验-库函数版本
//技术支持:
www.openedv.com
//淘宝店铺:
http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子
@alientek
#define usart2_baund 57600//串口2波特率,根据指纹模块波特率更改(注意:指纹模块默认57600)
SysPara AS608Para;//指纹模块AS608参数
u16 ValidN;//模块内有效模板个数
u8** kbd_tbl;
u16 ID;
const u8* kbd_menu[15]={"删除"," : ","添加","1","2","3","4","5","6","7","8","9","清除","0","确认",};//按键表
const u8* kbd_delFR[15]={"返回"," : ","全删","1","2","3","4","5","6","7","8","9","删除","0","确认",};//按键表
void Add_FR(void); //录指纹
void Del_FR(void); //删除指纹
void press_FR(void);//刷指纹
void ShowErrMessage(u8 ensure);//显示确认码错误信息
void AS608_load_keyboard(u16 x,u16 y,u8 **kbtbl);//加载虚拟键盘
u8 AS608_get_keynum(u16 x,u16 y);//获取键盘数
u16 GET_NUM(void);//获取数值
u16 CF;
u16 BE;
u16 pwd;
//任务优先级
#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 5
//任务堆栈大小
#define TASK2_STK_SIZE 128
//任务控制块
OS_TCB Task2_TaskTCB;
//任务堆栈
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//任务函数
void task2_task(void *p_arg);
int main(void)
{
OS_ERR err;
CPU_SR_ALLOC();
u8 ensure;
u8 key_num;
char *str;
u8*pwdmessage="请输入密码";
u8*notpwd="密码错误,请重新输入";
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(); //初始化延时函数
uart_init(115200); //初始化串口1波特率为115200,用于支持USMART
usart2_init(usart2_baund);//初始化串口2,用于与指纹模块通讯
PS_StaGPIO_Init(); //初始化FR读状态引脚
KEY_Init(); //按键初始化
LCD_Init(); //LCD初始化
LED_Init();
VS_Init(); //初始化VS1053
JIDIANQI_Init(); //初始化继电器
HONGWAI_Init(); //初始化红外
EXTIX_Init(); //外部中断初始化
LIANJIE32_Init();
tp_dev.init(); //初始化触摸屏
usmart_dev.init(72);//初始化USMART
mem_init(); //初始化内存池
exfuns_init(); //为fatfs相关变量申请内存
AT24CXX_Init(); //IIC初始化
TIM3_Int_Init(29999,7199);//10Khz的计数频率,计数到30000为3s
f_mount(fs[0],"0:",1); //挂载SD卡
f_mount(fs[1],"1:",1); //挂载FLASH.
POINT_COLOR=RED;
while(font_init()) //检查字库
{
LCD_ShowString(60,50,240,16,16,"Font Error!");
delay_ms(200);
LCD_Fill(60,50,240,66,WHITE);//清除显示
delay_ms(200);
}
if(!(tp_dev.touchtype&0x80))//如果是电阻屏
{
Show_Str_Mid(0,30,"Adjust the touch screen?",16,240);
POINT_COLOR=BLUE;
Show_Str_Mid(0,60,"YES: KEY1 NO: KEY0",16,240);
while(1)
{
key_num=KEY_Scan(0);
if(key_num==KEY0_PRES)
break;
if(key_num==KEY1_PRES)
{
LCD_Clear(WHITE);
TP_Adjust(); //屏幕校准
TP_Save_Adjdata();//保存校准参数
break;
}
}
}
/*加载指纹识别实验界面*/
LCD_Clear(WHITE);
POINT_COLOR=RED;
Show_Str_Mid(0,0,"AS608 Fingerprint module test",16,240);
Show_Str_Mid(0,20,"Author: @ALIENTEK",16,240);
POINT_COLOR=BLUE;
Show_Str_Mid(0,40,"Connect with AS608....",16,240);
while(PS_HandShake(&AS608Addr))//与AS608模块握手
{
LCD_Fill(0,40,240,80,WHITE);
Show_Str_Mid(0,40,"Cannot connect with AS608!",16,240);
delay_ms(1000);
LCD_Fill(0,40,240,80,WHITE);
Show_Str_Mid(0,40,"Try to connect again....",16,240);
delay_ms(1000);
}
LCD_Fill(0,40,240,320,WHITE);
Show_Str_Mid(0,40,"Connect success!",16,240);//通讯成功
str=mymalloc(30);
sprintf(str,"Baudrate:%d Addr:%x",usart2_baund,AS608Addr);//显示波特率
Show_Str(0,60,240,16,(u8*)str,16,0);
delay_ms(100);
ensure=PS_ValidTempleteNum(&ValidN);//读库指纹个数
if(ensure!=0x00)
ShowErrMessage(ensure);//显示确认码错误信息
ensure=PS_ReadSysPara(&AS608Para); //读AS608模块参数
if(ensure==0x00)
{
mymemset(str,0,50);
sprintf(str,"RemainNum:%d Level:%d",AS608Para.PS_max-ValidN,AS608Para.PS_level);//显示剩余指纹数量和安全等级
Show_Str(0,80,240,16,(u8*)str,16,0);
}
else
ShowErrMessage(ensure);
myfree(str);
AS608_load_keyboard(0,170,(u8**)kbd_menu);//加载虚拟键盘
while(1)
{
u8 j=0;
//LED1=0;
//delay_ms(1000);
//LED1=1;
if (LJ==1){
JDQ=0;
if(JDQ==0){
BE=1;
}
delay_ms(1000);
JDQ=1;
}
key_num=AS608_get_keynum(0,170);
if(key_num)
{
if(key_num==1){
Show_Str_Mid(0,120,(u8*)pwdmessage,16,240);
delay_ms(3000);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
pwd=GET_NUM();
if(pwd==123){
LCD_ShowNum(80+15,170+7,0,6,16);
Del_FR(); //删指纹
}
while(pwd!=123){
j++;
Show_Str_Mid(0,120,(u8*)notpwd,16,240);
delay_ms(3000);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
pwd=GET_NUM();
if(pwd==123){
LCD_ShowNum(80+15,170+7,0,6,16);
Del_FR(); //删指纹
}
}
}
if(key_num==3){
Show_Str_Mid(0,120,(u8*)pwdmessage,16,240);
delay_ms(3000);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
pwd=GET_NUM();
if(pwd==123){
LCD_ShowNum(80+15,170+7,0,6,16);
Add_FR(); //录指纹
}
while(pwd!=123){
j++;
Show_Str_Mid(0,120,(u8*)notpwd,16,240);
delay_ms(3000);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
pwd=GET_NUM();
if(pwd==123){
LCD_ShowNum(80+15,170+7,0,6,16);
Add_FR(); //录指纹
// printf("pwd:%d
",pwd);
}
/*if(j==2){
Show_Str_Mid(0,120,(u8*)notpwd,16,240);
delay_ms(3000);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
}*/
}
}
}
//PS_Open();
//TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断
if(PS_Sta) //检测PS_Sta状态,如果有手指按下
{
press_FR();//刷指纹
}
if(CF==1){ //打开柜门超过3分钟,则MP3响起
// LED0=0;
// delay_ms(200);
// LED0=1;
VS_Ram_Test();
VS_Sine_Test();
mp3_play();
}
}
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 )0,
(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 )0,
(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任务自身
}
//task1任务函数
void task1_task(void *p_arg)
{
// u8 task1_num=0;
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
// OS_CRITICAL_ENTER(); //进入临界区
// mp3_play();
// OS_CRITICAL_EXIT(); //退出临界区
while(1)
{
/* if(HW==0)
{
OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//红外遇到障碍物时,把mp3挂起
printf("MP3挂起!
");
}*/
if(JDQ==0)
{
OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err); //锁打开了,mp3定时后会发生报警
printf("mp3恢复了报警!
");
}
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
}
}
//task2任务函数
void task2_task(void *p_arg)
{
// u8 task2_num=0;
OS_ERR err;
CPU_SR_ALLOC();
p_arg = p_arg;
// OS_CRITICAL_ENTER(); //进入临界区
// mp3_play();
// OS_CRITICAL_EXIT(); //退出临界区
while(1)
{
// task2_num++; //任务2执行次数加1 注意task1_num2加到255的时候会清零!!
LED1=~LED1;
mp3_play();
// printf("任务2已经执行:%d次
",task2_num);
// LCD_ShowxNum(206,111,task2_num,3,16,0x80); //显示任务执行次数
// LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //延时1s
}
}
//加载按键界面(尺寸x,y为240*150)
//x,y:界面起始坐标(240*320分辨率的时候,x必须为0)
void AS608_load_keyboard(u16 x,u16 y,u8 **kbtbl)
{
u16 i;
POINT_COLOR=RED;
kbd_tbl=kbtbl;
LCD_Fill(x,y,x+240,y+150,WHITE);
LCD_DrawRectangle(x,y,x+240,y+150);
LCD_DrawRectangle(x+80,y,x+160,y+150);
LCD_DrawRectangle(x,y+30,x+240,y+60);
LCD_DrawRectangle(x,y+90,x+240,y+120);
POINT_COLOR=BLUE;
for(i=0;i<15;i++)
{
if(i==1)//按键表第2个‘:’不需要中间显示
Show_Str(x+(i%3)*80+2,y+7+30*(i/3),80,30,(u8*)kbd_tbl
,16,0);
else
Show_Str_Mid(x+(i%3)*80,y+7+30*(i/3),(u8*)kbd_tbl,16,80);
}
}
//按键状态设置
//x,y:键盘坐标
//key:键值(0~14)
//sta:状态,0,松开;1,按下;
void AS608_key_staset(u16 x,u16 y,u8 keyx,u8 sta)
{
u16 i=keyx/3,j=keyx%3;
if(keyx>16)return;
if(sta &&keyx!=1)//按键表第2个‘:’不需要清除
LCD_Fill(x+j*80+1,y+i*30+1,x+j*80+78,y+i*30+28,GREEN);
else if(keyx!=1)
LCD_Fill(x+j*80+1,y+i*30+1,x+j*80+78,y+i*30+28,WHITE);
if(keyx!=1)//不是‘:’
Show_Str_Mid(x+j*80,y+7+30*i,(u8*)kbd_tbl[keyx],16,80);
}
//得到触摸屏的输入
//x,y:键盘坐标
//返回值:(1~15,对应按键表)
u8 AS608_get_keynum(u16 x,u16 y)
{
u16 i,j;
static u8 key_x=0;//0,没有任何按键按下
u8 key=0;
tp_dev.scan(0);
if(tp_dev.sta&TP_PRES_DOWN)//触摸屏被按下
{
for(i=0;i<5;i++)
{
for(j=0;j<3;j++)
{
if(tp_dev.x[0]<(x+j*80+80)&&tp_dev.x[0]>(x+j*80)&&tp_dev.y[0]<(y+i*30+30)&&tp_dev.y[0]>(y+i*30))
{
key=i*3+j+1;
break;
}
}
if(key)
{
if(key_x==key)key=0;
else
{
AS608_key_staset(x,y,key_x-1,0);
key_x=key;
AS608_key_staset(x,y,key_x-1,1);
}
break;
}
}
}else if(key_x)
{
AS608_key_staset(x,y,key_x-1,0);
key_x=0;
}
return key;
}
//获取键盘数值
u16 GET_NUM(void)
{
u8 key_num=0;
u16 num=0;
while(1)
{
key_num=AS608_get_keynum(0,170);
if(key_num)
{
if(key_num==1)return 0xFFFF;//‘返回’键
if(key_num==3)return 0xFF00;//
if(key_num>3&&key_num<13&&num<99)//‘1-9’键(限制输入3位数)
num =num*10+key_num-3;
if(key_num==13)num =num/10;//‘Del’键
if(key_num==14&&num<99)num =num*10;//‘0’键
if(key_num==15)return num; //‘Enter’键
}
LCD_ShowNum(80+15,170+7,num,6,16);
}
}
//显示确认码错误信息
void ShowErrMessage(u8 ensure)
{
LCD_Fill(0,120,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,(u8*)EnsureMessage(ensure),16,240);
}
//录指纹
void Add_FR(void)
{
u8 i=0,ensure ,processnum=0;
//u16 ID;
while(1)
{
switch (processnum)
{
case 0:
i++;
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"Pleas touch finger!",16,240);//请按手指
ensure=PS_GetImage();
if(ensure==0x00)
{
ensure=PS_GenChar(CharBuffer1);//生成特征
if(ensure==0x00)
{
LCD_Fill(0,120,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,"Fingerprint correct",16,240);//指纹正确
i=0;
processnum=1;//跳到第二步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 1:
i++;
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"Pleas touch finger again!",16,240);//再按一次手指
ensure=PS_GetImage();
if(ensure==0x00)
{
ensure=PS_GenChar(CharBuffer2);//生成特征
if(ensure==0x00)
{
LCD_Fill(0,120,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,"Fingerprint correct",16,240);//指纹正确
i=0;
processnum=2;//跳到第三步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 2:
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"Compare twice fingerprint",16,240);//对比两次指纹
ensure=PS_Match();
if(ensure==0x00)
{
LCD_Fill(0,120,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,"Twice fingerprint are same",16,240);//两次指纹是一样的
processnum=3;//跳到第四步
}
else
{
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"Compare fail,pleas touch again!",16,240);//对比失败,请重新按手指
ShowErrMessage(ensure);
i=0;
processnum=0;//跳回第一步
}
delay_ms(1000);
break;
case 3:
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"Generate fingerprint template",16,240);//产生一个指纹模板
ensure=PS_RegModel();
if(ensure==0x00)
{
LCD_Fill(0,120,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,"Generate fingerprint success",16,240);//生成指纹模板成功
processnum=4;//跳到第五步
}else {processnum=0;ShowErrMessage(ensure);}
delay_ms(1000);
break;
case 4:
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,100,"请输入柜子编号,并按确认!",16,240);//输入ID并按“Enter”保存
// Show_Str_Mid(0,120,"0=< ID <=299",16,240);
do
ID=GET_NUM();
while(!(ID<300));//输入ID必须小于300
ensure=PS_StoreChar(CharBuffer2,ID);//储存模板
if(ensure==0x00)
{
LCD_Fill(0,100,lcddev.width,160,WHITE);
Show_Str_Mid(0,120,"Add fingerprint success!!!",16,240);//添加指纹成功
PS_ValidTempleteNum(&ValidN);//读库指纹个数
LCD_ShowNum(80,80,AS608Para.PS_max-ValidN,3,16);//显示剩余指纹个数
delay_ms(1500);//延时后清除显示
LCD_Fill(0,100,240,160,WHITE);
LCD_ShowNum(80+15,170+7,0,6,16);
return ;
}else {processnum=0;ShowErrMessage(ensure);}
break;
}
delay_ms(800);
if(i==5)//超过5次没有按手指则退出
{
LCD_Fill(0,100,lcddev.width,160,WHITE);
break;
}
}
}
//刷指纹
void press_FR(void)
{
&
亲爱的原子哥,可以帮我看看我那红 {MOD}字的代码位置是否放错,代码是否写错了吗?@正点原子
一周热门 更多>