其实就是不让单片机死循环,让1khz的中断去扫描各个任务
程序没有写完 也没测试 只是让大家看看思路对不对
是否可行
理论上这种结构比死循环的结构实时性和稳定性要好
#include<pic.h>
__config(0x3b32);
//**************************************************
// key定义
//**************************************************
#define uchar unsigned char //无符号字符数据声明
#define uint unsigned int //无符号整形数据声明
#define s1 rc4 //key1
#define s2 rc5 //key2
#define cw rb1 //drv cw
#define ccw rb2 //drv ccw
#define out1 rb3 //ext control1
#define out2 rb4 //ext control2
#define short rb0 //short signal input
#define ck rb5 //clock dida output
const uchar table[]={0xd7,0x12,0xcb,0x5b,0x1e,0x5d,0xdd,0x13,0xdf,0x5f};
//**************************************************
// 任务调度标记
//**************************************************
volatile static uchar ad_flag; //ad标记
volatile static uchar tmr1_flag; //tm1标记
volatile static uchar disp_flag; //disp标记
volatile static uchar short_flag; //short标记
//**************************************************
// 内核调度标记
//**************************************************
volatile static uchar core_flag; //内核调度标记
volatile static uchar task_flag; //任务标记
volatile static uchar task_level; //内核优先级标记
volatile static uchar h; //定时器1高位值
volatile static uchar l; //定时器1低位值
volatile static uint data_temp;
//***************************************************
// 变量声明
//***************************************************
uint ad_val; //瞬态值
long ad_ave; //平均值
uchar bai; //百位
uchar shi; //十位
uchar ge; //个位
//***************************************************
// 函数声明
//***************************************************
void dsp(uchar num1,uchar num2,uchar num3);
void io_init(); //io初始化函数
void ext_init(); //外设初始化函数
void int_init(); //中断初始化函数
void delay(uint x); //软件延时函数
uint task_ad();
void task_disp();
void task_nc();
void task_out();
void task_key();
void task_setp();
void task_cw();
void task_ccw();
main()
{
io_init();
ext_init();
int_init();
aa:
while(!s1);
delay(10);
if(s1)
{
goto ab;
}
else
{
goto aa;
}
ab:
tmr1on=1; //open time1 power
adgo=1; //open ad converter switch
while(1)
{
begin:
if(task_flag!=0) //动态内核队列
{
if(task_level=((task_flag&0x80)>>7))
{
core_flag=0x01;
goto core_process;
}
else if(task_level=((task_flag&0x40)>>6))
{
core_flag=0x02;
goto core_process;
}
else if(task_level=((task_flag&0x20)>>5))
{
core_flag=0x03;
goto core_process;
}
else if(task_level=((task_flag&0x10)>>4))
{
core_flag=0x04;
goto core_process;
}
else if(task_level=((task_flag&0x08)>>3))
{
core_flag=0x05;
goto core_process;
}
else if(task_level=((task_flag&0x04)>>2))
{
core_flag=0x06;
goto core_process;
}
else
{
core_flag=0xff;
goto begin;
}
} //end if
core_process:
if(core_flag!=0)
{
switch(core_flag) //t1
{
case 0x01: //内核任务扫描
{
uchar disp_t;
uchar nc_t;
uchar key_t;
uchar short_t;
if(disp_t!=0) //disp基准100hz
{
disp_t=disp_t--;
if(disp_t==0)
{
disp_t=0x0a;
task_flag=task_flag|0x08; //队列3
}
}
else
{
disp_t=0x0a;
}
if(nc_t!=0) //nc时间基准
{
nc_t=nc_t--;
if(nc_t==0)
{
nc_t=0x0b;
task_flag=task_flag|0x10; //任务队列4
}
}
else
{
nc_t=0x0b;
}
if(key_t!=0) //key时间基准
{
key_t=key_t--;
if(nc_t==0)
{
key_t=0x0f;
task_flag=task_flag|0x04; //任务队列5
}
}
else
{
key_t=0x0f;
}
if(short_t!=0) //short时间基准
{
short_t=short_t--;
if(short_t==0)
{
short_t=0x09;
task_flag=task_flag|0x20; //任务队列6
}
}
else
{
short_t=0x09;
}
task_flag=task_flag&0x7f; //任务结束标记
}
break;
case 0x02: //ad
{
uchar k;
long ad_temp;
long shi_temp;
long ge_temp;
ad_val=task_ad();
if(k!=0)
{
ad_ave=ad_ave+ad_val;
k--;
}
else
{
k=49;
ad_temp=ad_ave*1000; //数据转换
ad_temp=ad_temp/50;
bai=ad_temp/1000;
shi_temp=ad_temp%1000;
shi=shi_temp/100;
ge_temp=ad_temp%100;
ge=ge_temp/10;
ad_ave=0;
ad_val=0;
}
task_flag=task_flag&0xbf; //任务结束标记
}
break;
case 0x03: //short task
{
uchar i;
if(short)
{
i++;
if(i==2)
{
short_flag=1;
i=0;
}
else
{
short_flag=0;
}
}
else
{
i=0;
}
}
break;
case 0x04: //nc
{
if(short_flag)
{
task_cw();
}
else
{
task_ccw();
}
}
break;
default:
{
nop();
}
}
}
} //end while
}
void io_init()
{
trisa=0x01;
trisb=0x01;
trisc=0x30;
trisd=0;
trise=0;
porta=0;
portb=0;
portc=0;
portd=0;
porte=0;
}
void ext_init()
{
h=((0xc350&0xff00)>>8);
l=(0xc350&0xff);
tmr1h=h;
tmr1l=l;
t1con=0x04; //定时器1 分频比1:1 关闭振荡器 内部时钟 tmr1on=0
adcon0=0x81; //an1输入 分频比1/64 power up 右对齐
adcon1=0xce;
cmcon=0x07; //关比较器
}
void int_init()
{
gie=1; //启用全局中断
peie=1; //启用外设中断
adie=1; //启用ad中断
tmr1ie=1; //启用ti中断
tmr1if=0; //t1标记清零
adif=0; //ad标记清零
}
void sc()//数据所存
{
porte=0;
delay(2);
porte=0x06;
delay(2);
porte=0;
delay(2);
}
uint task_ad()
{
uint adval_l,adval_h,adval_temp;
float adval;
adval_l=adresl;
adval_h=adresh;
adval_temp=((adval_h<<8)|adval_l);
adval=adval_temp/1023*5.0;
adval=adval*1000;
return (adval);
}
void delay(uint x)//延时程序
{
uint a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void dsp(uchar num1,uchar num2,uchar num3)
{
portb=table[num1];//显示第一个数码管
portd=0x04;
sc();
delay(2);
portb=table[num2];//显示第二个数码管
portd=0x02;
sc();
delay(2);
portb=table[num3];//显示第三个数码管
portd=0x01;
sc();
delay(2);
}
void task_cw()
{
cw=0;
ccw=1;
delay(10);
cw=1;
}
void task_ccw()
{
cw=1;
ccw=0;
delay(10);
ccw=1;
}
void interrupt di()//中断处理
{
if(adif) //ad_flag创建
{
adif=0;
task_flag=((1<<6)&0x40);
}
else
{
adif=0;
}
//========================================
if(tmr1if)
{
tmr1if=0;
task_flag=((1<<7)&0x80);
tmr1on=0;
tmr1h=h;
tmr1l=l;
tmr1_flag=1;
nop();
nop();
tmr1on=1;
}
else
{
tmr1if=0;
}
//=========================================
if(ck)
{
ck=0;
}
else
{
ck=1;
}
}