程序运行到OSStatInit()时就不在运行了,将OSStatInit()注释掉后每个任务都只运行一次后就不再运行了,但是这两种情况下,卡主后都还能响应中断,不知道是怎么回事?
这个程序的目的就是:通过按键0,1进入中断,在中断中向SW任务(sw_task)发送消息,SW根据消息来挂起和解挂AD采集任务(adc_task)和温度采集任务(wen_task),按键0,采集AD,按键1,采集温度。
我之前用寄存器版本移植UCOS,运行这个程序没有任何问题,现在用库函数移植UCOS,运行这个程序就出现了这个问题,原子哥能不能帮忙看一下:
main.c代码如下:
#include"sys.h"
#include"delay.h"
#include"usart.h"
#include "led.h"
#include "adc.h"
#include "lcd.h"
#include"exti.h"
#include"includes.h"
//START 任务
#define START_TASK_PRIO 10 //设置任务优先级
#define START_STK_SIZE 512 //设置任务堆栈大小
OS_STK START_TASK_STK[START_STK_SIZE]; //任务堆栈
void start_task(void *pdata); //任务函数
//ADC任务
#define ADC_TASK_PRIO 7 //设置任务优先级
#define ADC_STK_SIZE 512 //设置任务堆栈大小
OS_STK ADC_TASK_STK[ADC_STK_SIZE]; //任务堆栈
void adc_task(void *pdata); //任务函数
//WEN任务
#define WEN_TASK_PRIO 8 //设置任务优先级
#define WEN_STK_SIZE 512 //设置任务堆栈大小
OS_STK WEN_TASK_STK[WEN_STK_SIZE]; //任务堆栈
void wen_task(void *pdata); //任务函数
//切换任务
#define SW_TASK_PRIO 5 //设置任务优先级
#define SW_STK_SIZE 512 //设置任务堆栈大小
OS_STK SW_TASK_STK[SW_STK_SIZE]; //任务堆栈
void sw_task(void *pdata); //任务函数
//CPU利用率显示
#define CPU_TASK_PRIO 9 //设置任务优先级
#define CPU_STK_SIZE 512 //设置任务堆栈大小
OS_STK CPU_TASK_STK[CPU_STK_SIZE]; //任务堆栈
void cpu_task(void *pdata); //任务函数
OS_EVENT *myMBox;//消息邮箱
#define READ_TIMES 40 //一次读取ADC数据的个数
#define LOST_VAL 3 //去掉最大值和最小值的个数
int main(void)
{
NVIC_Configuration();
delay_init(); //延时初始化
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化LED
LCD_Init();
Adc_Init();
EXTIX_Init();
OSInit();
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
void start_task(void *pdata)
{
u8 err;
OS_CPU_SR cpu_sr=0;
pdata = pdata;
POINT_COLOR=BRED;//设置字体为红色
LCD_ShowString(100,90,"CPU: 00 %");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,130,"ADC_CH0_VAL:");
LCD_ShowString(60,150,"ADC_CH0_VOL:0.000V");
LCD_ShowString(60,170,"TEMP_VAL:");
LCD_ShowString(60,190,"TEMP_VOL:0.000V");
LCD_ShowString(60,210,"TEMPERATE:00.00C");
myMBox=OSMboxCreate((void*)0); //创建消息邮箱
OSStatInit(); //初始化统计任务.这里会延时1秒钟左右,若要使用统计任务必须调用该函数
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(sw_task,(void *)0,(OS_STK*)&SW_TASK_STK[SW_STK_SIZE-1],SW_TASK_PRIO);
OSTaskCreate(adc_task,(void *)0,(OS_STK*)&ADC_TASK_STK[ADC_STK_SIZE-1],ADC_TASK_PRIO);
OSTaskCreate(wen_task,(void *)0,(OS_STK*)&WEN_TASK_STK[WEN_STK_SIZE-1],WEN_TASK_PRIO);
OSTaskCreate(cpu_task,(void *)0,(OS_STK*)&CPU_TASK_STK[CPU_STK_SIZE-1],CPU_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
void sw_task(void *pdata)
{
u8 bz1=0;
u8 bz2=0;
LCD_ShowString(110,70,"START");
while(1)
{
u32 *sign;
u8 err;
sign=(u32*)OSMboxPend(myMBox,0,&err);
switch(*sign)
{
case 1:
bz1=!bz1;
if(bz1)
{
OSTaskSuspend(ADC_TASK_PRIO);
}
else
{
OSTaskResume(ADC_TASK_PRIO);
}
break;
case 2:
bz2=!bz2;
if(bz2)
{
OSTaskSuspend(WEN_TASK_PRIO);
}
else
{
OSTaskResume(WEN_TASK_PRIO);
}
break;
}
OSTimeDly(10);
}
}
void adc_task(void *pdata)
{
while(1)
{
u8 i,j;
u16 adc[READ_TIMES]; //数组用于保存AD的值
u16 adcx=0; //AD的平均值
u16 temp,temp1,temp3;
float temp2;
u32 sum=0;
for(i=0;i<READ_TIMES;i++) //多次读取AD值
{
adc=Get_Adc(ADC_CH0);
}
for(i=0;i<READ_TIMES-1; i++)//排序
{
for(j=i+1;j<READ_TIMES;j++)
{
if(adc>adc[j])//升序排列
{
temp=adc;
adc=adc[j];
adc[j]=temp;
}
}
}
for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++) //计算平均值
{
sum+=adc;
adcx=sum/(READ_TIMES-2*LOST_VAL);
}
//屏幕上显示
LCD_ShowNum(156,130,adcx,4,16);//显示ADC的值
temp2=(float)adcx*(3.3/4096);
adcx=temp2;
LCD_ShowNum(156,150,adcx,1,16);//显示电压值整数部分
temp2-=adcx;
temp2*=1000;
LCD_ShowNum(172,150,temp2,3,16);//显示电压值小数部分
LED0=!LED0;
// //将电压值以ASCII码发送出去
// temp3=temp2; //temp2为float,temp,temp3为整型u16
// temp=adcx+48;
// USART1->DR=temp; //发送整数位ASCII码
// while((USART1->SR&0X40)==0);//等待发送结束
// USART1->DR='.';
// while((USART1->SR&0X40)==0);
// temp1=100;
// for(i=0;i<3;i++) //发送小数位ASCII码
// {
// temp=temp3/temp1;
// USART1->DR=temp+48;
// while((USART1->SR&0X40)==0);//等待发送结束
// temp3=temp3%temp1;
// temp1=temp1/10;
// }
// USART1->DR='V';
// while((USART1->SR&0X40)==0);//等待发送结束
// USART1->DR=' ';
// while((USART1->SR&0X40)==0);//等待发送结束
OSTimeDly(25);
};
}
void wen_task(void *pdata)
{
while(1)
{
u8 i,j;
u16 adc[READ_TIMES]; //数组用于保存AD的值
u16 adcx=0; //AD的平均值
u16 temp,temp1,temp3;
float temp2,temperate;
u32 sum=0;
LED1=!LED1;
for(i=0;i<READ_TIMES;i++) //多次读取AD值
{
adc=Get_Adc(ADC_WEN);
}
for(i=0;i<READ_TIMES-1; i++)//排序
{
for(j=i+1;j<READ_TIMES;j++)
{
if(adc>adc[j])//升序排列
{
temp=adc;
adc=adc[j];
adc[j]=temp;
}
}
}
for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++) //计算平均值
{
sum+=adc;
adcx=sum/(READ_TIMES-2*LOST_VAL);
}
LCD_ShowNum(132,170,adcx,4,16);//显示ADC的值
temp2=(float)adcx*(3.3/4096);
temperate=temp2;//保存温度传感器的电压值
adcx=temp2;
LCD_ShowNum(132,190,adcx,1,16); //显示电压值整数部分
temp2-=(u8)temp; //减掉整数部分
LCD_ShowNum(148,190,temp2*1000,3,16);//显示电压小数部分
temperate=(1.43-temperate)/0.0043+25;//计算出当前温度值
LCD_ShowNum(140,210,(u8)temperate,2,16); //显示温度整数部分
temperate-=(u8)temperate;
LCD_ShowNum(164,210,temperate*100,2,16);//显示温度小数部分
LED1=!LED1;
OSTimeDly(50);
};
}
void cpu_task(void *pdata)
{
while(1)
{
LCD_ShowNum(140,90,OSCPUUsage,2,16); //显示CPU利用率
OSTimeDly(100);
}
}
|