程序运行到OSSta
tinit()时就不在运行了,将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); //串口初始化为9600LED_Init(); //初始化LEDLCD_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
=Get_Adc(ADC_CH0);} for(i=0;i>adc[j])//升序排列{temp=adc;adc=adc[j];adc[j]=temp;}}}for(i=LOST_VAL;i;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=Get_Adc(ADC_WEN);} for(i=0;i>adc[j])//升序排列{temp=adc;adc=adc[j];adc[j]=temp;}}}for(i=LOST_VAL;i;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);}}