U3_处理机的调度

处理机的调度

接下来进入第三章的内容。这一个内容主要讲的是进程的调度及其简单的介绍。话不多说就开始吧。

1、调度的基本概念

比如,我们通过按顺序排队打餐就是一种简单的调度,即通过一种规则下执行一件事情(这里就是先到先得)。当然,有时候这种调度会考虑一些问题,比如说军训期间的教官优先呀,老师优先等等,这也是调度的体现。下图能够很形象的展示调度的概念:

在这里插入图片描述

比如前面举的身份优先,或者时间优先。通过某一种规则来决定以什么样的顺序来处理问题。

在多道程序系统中,进程的数量往往是多于处理机的个数,这样不可能同时并行地处理各个进程。所以处理机的调度,就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它们运行以实现进程的并发执行。

2、调度的三个层次

2.1 高级调度

高级调度被称为长程调度或者作业调度。它的主要功能在于根据某种算法,决定将外存上处于后备队列中的哪几个作业调入内存中,为它们创建进程、分配必要的资源,并将它们放入就绪队列中。

每个作业只能调入一次,调出一次。作业调入时也会建立相应的PCB,作业调出之后才撤销PCB。

2.2 中级调度

中级调度就是内存调度,它在于提高内存的利用率和系统的吞吐量。它将暂时不能运行的进程调至外存等待。此时进程的状态被称为挂起状态。

在挂起状态中,PCB并不会一起调到至外存,而是会常驻内存,放置于挂起队列中。PCB会记录进程数据在外存中存放的位置,进程状态等信息,起到对进程的监督和管理作用。

2.3 低级调度

低级调度也被称为进程调度,主要任务就是根据某种方法和策略从就绪队列中选取一个进程,并将处理机分配给它。

低级调度是最基本的一种调度,其所调度的对象是进程。

2.4 三种调度的对比

在这里插入图片描述

3、进程调度

进程调度就是低级调度,当然其中也要对进程调度进行判断。

在这里插入图片描述

3.1 进程调度的方式

根据需要进行进程调度与切换的情况,我们将进程调度分为两部分:非剥夺调度方式剥夺调度方式

非剥夺调度方式也称为非抢占方式,它只允许进程主动放弃处理机。在运行过程中即便有更加紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或者主动要求进入阻塞态。

剥夺调度方式又称为抢占方式,当一个进程正在处理机上执行时,如果有一个更重要或者更紧凑的进程需要使用处理机时,则立刻暂停正在执行的进程,将处理机分配给更重要紧凑的那个进程。

3.2 进程的切换和过程

进程调度就是从就绪队列中选中一个要运行的进程。其中这个进程可以是刚刚被暂停执行的进程,也可以是另一个进程,后一种情况就需要进程切换。

进程的切换就是指一个进程让出处理机,由另一个进程占用处理机的过程。

进程切换的过程主要完成了:

  • 对原来运行进程各种数据的保存
  • 对新的进程各种数据的恢复

这说明其实对于进程切换是有代价存在的。如果过于频繁的进行进程调度、切换,必然会使得整个系统的效率降低,使大部分时间都花在进程切换上,而真正用于执行进程的时间减少。

总结

以上就是对处理机调度和进程调度切换的知识点的简单介绍,后续会相应的介绍调度算法的评价指标,谢谢!

#include <ny8.h> #include "NY8_constant.h" #define MCUO2 PA6 #define KEY PA7 #define LED PA5 #define TIM PA1 #define IRIN PB4 #define NM8_G PA0 #define M2O1 PB0 #define M2O2 PB1 #define M2O3 PB2 #define M2O4 PB3 #define MCUO PA4 #define OLED PA2 #define CTL_M PB5 #define Coil_A { M2O1 = 1; M2O2 = 0; M2O3 = 0; M2O4 = 0;} #define Coil_AB { M2O1 = 1; M2O2 = 1; M2O3 = 0; M2O4 = 0;} #define Coil_B { M2O1 = 0; M2O2 = 1; M2O3 = 0; M2O4 = 0;} #define Coil_BC { M2O1 = 0; M2O2 = 1; M2O3 = 1; M2O4 = 0;} #define Coil_C { M2O1 = 0; M2O2 = 0; M2O3 = 1; M2O4 = 0;} #define Coil_CD { M2O1 = 0; M2O2 = 0; M2O3 = 1; M2O4 = 1;} #define Coil_D { M2O1 = 0; M2O2 = 0; M2O3 = 0; M2O4 = 1;} #define Coil_DA { M2O1 = 1; M2O2 = 0; M2O3 = 0; M2O4 = 1;} #define TASK_NUM 7 //最大任务数 unsigned char TaskCount[TASK_NUM] = {1,30,30,100,100,125,1}; //任务计时器 unsigned char TaskMake[TASK_NUM] = {0,0,0,0,0,0,0}; //任务运行标志位 unsigned char const ltvTime[TASK_NUM]={1,30,30,100,100,125,1}; unsigned char S_Time=0,x=0; unsigned char i,j; unsigned char sleep_t=0; //电机 unsigned char Count=0; unsigned char Coil=0; unsigned char const Seepd=5; unsigned char Dir_Time=0; unsigned int StepNumber=4224; unsigned char Sleep_Time=0; unsigned int Step_conut=0; unsigned int tmp=0,LastValue=0; unsigned char DATA_LB=0,DATA_HB=0; unsigned int DATA=0; unsigned int V_E=0; unsigned char fan=0; unsigned char led_dat=0; unsigned char clock=0; unsigned char Motor_Go=0; unsigned char Motor_Stop=0; unsigned char dangwei_count=0; unsigned char tdangwei_count=0; unsigned char al=0xff; __sbit k1=al:0; __sbit k2=al:1; __sbit k3=al:2; __sbit k1_last=al:3; __sbit k2_last=al:4; __sbit k3_last=al:5; __sbit k4 = al:6; __sbit k4_last = al:7; unsigned char bl = 0x60; __sbit yy = bl:0; __sbit sleep_bit = bl:1; //__sbit Motor_Go = bl:2; __sbit close = bl:3; __sbit dangwei_go = bl:4; __sbit key_ir = bl:5; __sbit key_ir_last = bl:6; __sbit IR_AG = bl:7; unsigned char cl = 0x00; __sbit direction = cl:0; __sbit first = cl:1; __sbit tdangwei_go = cl:2; //__sbit Motor_Stop = cl:3; __sbit Motor_dc = cl:4; void Wait(void) { while (ADMDbits.EOC == 0) ; } void Delay(char count) { char m; for (m = 1; m <= count; m++) ; } void GPIO_Init(void){ BPHCON = 0XFF; ABPLCON = 0XFF; IOSTB = 0X10;//PB4 IOSTA = 0XE3;//PA0、1、5、6、7 APHCON = 0XFF; PORTA = 0X00; PORTB = 0X00; PACON = 0x02; //PA1纯模拟输入 } void sleep_Init(void) { INTFbits.PABIF = 0; AWUCON = 0X00; BWUCON = 0X00; INTE |= C_INT_PABKey; } void Time_Init(void) { //200us T1CR1 = C_TMR1_Dis; TMRH = 0x00; TMR1 = 0x7C; T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Div8; INTE = C_INTE_TMR1; T1CR1 = C_TMR1_Reload | C_TMR1_En; } void PWM_Init(void) { //100k TM3RH = 0x00; TMR3 = 49; PWM4DUTY = 0x00; T3CR2 = C_TMR3_ClkSrc_Inst | C_PS3_Dis; T3CR1 = C_PWM3_En | C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; P4CR1 = C_PWM4_En | C_PWM4_Active_Hi; } void ADC_Init(void) { DATA_LB = DATA_HB = 0X00; ADR = C_Ckl_Div8; ADCR = C_Sample_8clk | C_12BIT; Delay(50); } unsigned int ADC_ReadValue(void) { ADVREFH = 0x03; //参考电压:0x00:2V,0x02:4V,0x03:VCC ADMD = 0x91; ADMDbits.START = 1; Wait(); DATA_LB = ADR & 0X0F; DATA_HB = ADD; DATA = (DATA_HB << 4) | DATA_LB ; tmp = (8 * DATA + 2 * LastValue) / 10 + 1; LastValue = DATA; return tmp; } void Motor_work(void) { if(direction){ Count++; if(Count > Seepd){ // 每1.25ms切换一次线圈 Coil++; Count = 0; } if(Coil > 7){ Coil = 0; } switch(Coil){ case 0: Coil_A; break; case 1: Coil_AB; break; case 2: Coil_B; break; case 3: Coil_BC; break; case 4: Coil_C; break; case 5: Coil_CD; break; case 6: Coil_D; break; case 7: Coil_DA; break; } } else { Count++; if(Count > Seepd){ // 每1.25ms切换一次线圈 Coil++; Count = 0; } if(Coil > 7){ Coil = 0; } switch(Coil){ case 0: Coil_DA; break; case 1: Coil_D; break; case 2: Coil_CD; break; case 3: Coil_C; break; case 4: Coil_BC; break; case 5: Coil_B; break; case 6: Coil_AB; break; case 7: Coil_A; break; } } } void ULN2003A(void) { if(!fan && StepNumber != 4224) { Motor_Stop = 1; } // //回到中间: // //计算步进值,假设左到右走8448步,那么中间值是8448/2=4224步 // //如果当前步数大于4224步说明已超过中间值,这时控制步进电机走(当前步数-4224)的相反步数,回到中间。 // //如果当前步数小于4224步说明未超过中间值,这是控制步进电机走(4224-当前步数)的同向步数,回到中间。 if(Motor_Stop) { Motor_work(); if(StepNumber > 4224 && !Step_conut) { Motor_dc = 1; Step_conut = StepNumber; direction = !direction; } else if(StepNumber < 4224 && !Step_conut) { Motor_dc = 0; Step_conut = StepNumber; } if(Motor_dc) { Dir_Time++; if(Dir_Time > Seepd) { Dir_Time = 0; Step_conut--; //停止后是4224 StepNumber--; if(Step_conut <= 4224) { Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 4224; Motor_Stop = 0; Step_conut = 0; } } } else { Dir_Time++; if(Dir_Time > Seepd) { Dir_Time = 0; Step_conut++; //停止后是4224 StepNumber++; if(Step_conut >= 4224) { Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 4224; Motor_Stop = 0; Step_conut = 0; } } } } else if(Motor_Go){ Motor_work(); Dir_Time++; if(Dir_Time > Seepd){ Dir_Time = 0; StepNumber++; if(StepNumber > 8448){ //1056*8 // 关键修改:调整Coil确保相位连续 Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 0; } } } else { M2O1 = 0; M2O2 = 0; M2O3 = 0; M2O4 = 0; } } unsigned char k1_time=0,k2_time=0; unsigned char u1=0,u2=0,u3=0; unsigned long int timing_temp=0; unsigned int timing_count=0; unsigned char stop=0; unsigned char stop_time=0; unsigned char go_time=0; unsigned int key_value=0; unsigned char display_close=0; void key_scanf(void) { //6ms key_value = ADC_ReadValue(); if(key_value < 200) { //TIM(0) k3 = 0; } if(key_value > 1200) { //YT(1/2) k4 = 0; } if(key_value > 3200) { //松开 k3 = 1; k4 = 1; } k1 = KEY;k2 = LED; if(!stop) { if(!k1 && k1_last) { k1_time = 0; u1 = 0; } if(!k1 && !k1_last && !u1) { k1_time++; if(k1_time > 250) { k1_time = 0; u1 = 1; } } if(k1 && !k1_last && !u1) { if(k1_time > 5) { fan++; display_close = 0; } } if(!k2 && k2_last) { k2_time = 0; u2 = 0; } if(!k2 && !k2_last && !u2) { k2_time++; if(k2_time > 250) { //1.5s k2_time = 0; u2 = 1; display_close = !display_close; led_dat = 0; } } if(k2 && !k2_last && !u2) { if(k2_time > 5) { led_dat++; display_close = 0; } } if(k3 && !k3_last) { clock++; tdangwei_go = 1; tdangwei_count = 0; timing_count = 0; display_close = 0; } if(k4 && !k4_last) { Motor_Go = !Motor_Go; display_close = 0; } } if(!NM8_G) { go_time = 0; stop_time++; if(stop_time > 20) { //120ms stop_time = 0; stop = 1; fan = 0; //风扇 clock = 0; //定时 timing_count = 0; //定时计数器 led_dat = 0; //照明灯 PWM3DUTY = 0; T3CR1 &= 0X7F; //关闭PWM3 display_close = 0; } } if(NM8_G) { stop_time = 0; go_time++; if(go_time > 20) { go_time = 0; stop = 0; T3CR1 |= 0X80; //开启PWM3 } } k1_last = k1;k2_last = k2;k3_last = k3;k4_last = k4; if(fan > 4) { fan = 0; led_dat = 0; } if(led_dat > 3) { led_dat = 0; } if(clock > 4) { clock = 0; } if(!fan) { Motor_Go = 0; clock = 0; } if(!clock) { tdangwei_go = 0; tdangwei_count = 0; } switch(clock) { case 0:timing_temp = 0;break; case 1:timing_temp = 14400;break; case 2:timing_temp = 28800;break; case 3:timing_temp = 57600;break; case 4:timing_temp = 115200;break; } if(tdangwei_go) { tdangwei_count++; if(tdangwei_count > 250) { tdangwei_go = 0; tdangwei_count = 0; } } else { tdangwei_count = 0; } } void led_work(void) { //6ms switch(led_dat) { case 0:PWM3DUTY = 0;break; case 1:PWM3DUTY = 25;break; case 2:PWM3DUTY = 35;break; case 3:PWM3DUTY = 49;break; } } unsigned char fan_time=0; unsigned char fan4_bit=0; void fan_work(void) { //20ms if(fan) { CTL_M = 1; }else { CTL_M = 0; } if(fan == 4) { //4-4 fan_time++; if(fan_time > 200) { //4s fan_time = 0; fan4_bit = !fan4_bit; } if(fan4_bit) { CTL_M = 1; if(MCUO2) PWM4DUTY = 10; else PWM4DUTY = 14; }else { PWM4DUTY = 0; CTL_M = 0; } } else { fan_time = 0; } if(MCUO2) switch(fan) { case 0:PWM4DUTY = 0;break; case 1:PWM4DUTY = 10;break; case 2:PWM4DUTY = 15;break; case 3:PWM4DUTY = 20;break; } else if(!MCUO2) switch(fan) { case 0:PWM4DUTY = 0;break; case 1:PWM4DUTY = 14;break; case 2:PWM4DUTY = 22;break; case 3:PWM4DUTY = 30;break; } } unsigned char cti=0; void timing(void) { //250ms if(clock) { cti++; if(cti > 10) { cti = 0; timing_count++; //250ms加一 } if(timing_count > timing_temp) { timing_count = 0; timing_temp = 0; fan = 0; led_dat = 0; clock = 0; } } else { timing_count = 0; } } unsigned char low_go=0; unsigned char hight_go=0; unsigned char low_t; unsigned char high_t; unsigned int IR_dat=0; unsigned int IR_dat_last=0; unsigned char Start=0; unsigned char on=1; unsigned int on_time=0; unsigned char low_count=0; //下降沿计数,12个为一组数 unsigned int ac_t=0; //高电平超过10ms数据清零 //低电平到下一个上升沿时间超过800us为数据1 //低电平到下一个上升沿时间小于800us为数据0 void irin_work(void) { key_ir = IRIN; if(!key_ir && key_ir_last) { //下降沿 IR_dat <<= 1; low_go = 1; hight_go = 0; low_t = 0; } if(key_ir && !key_ir_last) { //上升沿 hight_go = 1; low_go = 0; on_time = 0; if(low_t > 4) { //低电平持续时间超过800us IR_dat |= 0x01; } high_t = 0; } if(low_go) { low_t++; } if(hight_go) { high_t++; on_time++; } if(on_time > 250) { //50ms,高电平超过50ms时on为1,否则为0 on = 1; on_time = 251; }else { on = 0; } if(IR_AG) { if(high_t > 100) { //超过20ms松手 high_t = 0; IR_dat = 0; IR_AG = 0; } }else { if(high_t > 20) { //超过4ms数据清零 IR_dat = 0; high_t = 0; } } if(!IR_AG) { if(IR_dat == 0xd81) { //夜灯 IR_AG = 1; led_dat++; IR_dat = 0; display_close = 0; } if(IR_dat == 0xd82 && Start) { //摇头 IR_AG = 1; Motor_Go = !Motor_Go; IR_dat = 0; display_close = 0; } if(IR_dat == 0xdac) { //挡位短按(开) IR_dat_last = IR_dat; IR_dat = 0; display_close = 0; } if(IR_dat_last == 0xdac) { //有波形的时候on为1,波形消失20ms后,on为0 ac_t++; if(ac_t > 5000) { //1.0s(5000) ac_t = 0; fan = 0; led_dat = 0; IR_dat_last = 0; IR_dat = 0; on = 1; IR_AG = 1; } else if(on) { fan++; dangwei_go = 1; dangwei_count = 0; IR_dat_last = 0; IR_dat = 0; ac_t = 0; } } if(IR_dat == 0xd88 && Start) { //定时 IR_AG = 1; clock++; timing_count = 0; tdangwei_go = 1; tdangwei_count = 0; IR_dat = 0; display_close = 0; } } if(fan > 4) { fan = 0; led_dat = 0; } if(clock > 4) { clock = 0; } if(!clock) { tdangwei_go = 0; tdangwei_count = 0; } if(led_dat > 3) { led_dat = 0; } if(fan) { Start = 1; }else { Start = 0; Motor_Go = 0; clock = 0; dangwei_count = 0; dangwei_go = 0; } key_ir_last = key_ir; } unsigned int mcu_date=0; unsigned int out_count=0; unsigned char out_time=0; void data_output(void) { //200us if(!out_count) { mcu_date = 0; mcu_date |= ((unsigned int)fan << 12); if(!tdangwei_go) mcu_date |= (((unsigned int)clock) << 8); else mcu_date |= (((unsigned int)clock + 8) << 8); if(!display_close) mcu_date |= ((unsigned int)led_dat << 4); else mcu_date |= (((unsigned int)led_dat + 8) << 4); mcu_date |= Motor_Go; out_time++; if(out_time > 125) { //125 * 200us = 50000us = 25ms out_time = 0; out_count = 1; } } else if(out_count < 17) { //16次 if(mcu_date & 0x8000) { //取高位,如果是1,高电平持续1.5ms out_time++; if(out_time < 8) { //1.5ms = 200 * 7.5 MCUO = 1; } else if(out_time > 25) { //5ms = 200us * 25 MCUO = 0; out_time = 0; out_count++; mcu_date <<= 0x0001; } else if(out_time > 8) { MCUO = 0; } } else { //如果是0,高电平持续3.5ms out_time++; if(out_time < 18) { //3.5ms = 200 * 17.5 MCUO = 1; } else if(out_time > 25) { //5ms = 200 * 25 MCUO = 0; out_time = 0; out_count++; mcu_date <<= 0x0001; } else if(out_time > 18) { MCUO = 0; } } } else { out_count = 0; } } void SLEEPING(void)//20 { if((!fan && IRIN && !MCUO2 && !led_dat && KEY && LED && !Motor_Stop) || stop) { sleep_t++; if(sleep_t > 100) { //2s sleep_t = 0; PWM3DUTY = 0; PWM4DUTY = 0; close = 1; sleep_bit = 1; } }else { sleep_t = 0; } if(sleep_bit) { sleep_bit = 0; yy = 1; PORTA = 0X00; PORTB = 0X00; ADMD &= 0X6F; //bit7清零,关闭ADC T1CR1 &= 0XFE; //关闭定时器1 T3CR1 &= 0X7F; //关闭PWM3 P4CR1 &= 0X7F; //关闭PWM4 INTE = 0X02; //只开启输入状态变化中断 PCON = 0X10; //关闭看门狗和低压复位,关闭PA5上拉 AWUCON = 0XE1;//PA0 5,6,7 BWUCON = 0X10;//PB4 dangwei_count = 0; dangwei_go = 0; sleep_t = 0; SLEEP(); } } void taskScheduler(void) //任务调度器 { for(j=0;j<TASK_NUM;j++) { if(TaskMake[0]){ ULN2003A(); TaskMake[0] = 0; } if(TaskMake[1]){ key_scanf(); TaskMake[1] = 0; } if(TaskMake[2]){ led_work(); TaskMake[2] = 0; } if(TaskMake[3]){ fan_work(); TaskMake[3] = 0; } if(TaskMake[4]){ SLEEPING(); TaskMake[4] = 0; } if(TaskMake[5]){ timing(); TaskMake[5] = 0; } //if(TaskMake[6]){ // data_output(); // TaskMake[6] = 0; //} } if(j >= TASK_NUM) { j = 0; } } void main(void) { DISI(); GPIO_Init(); sleep_Init(); Time_Init(); PWM_Init(); ADC_Init(); ENI(); while(1) { CLRWDT(); taskScheduler(); } } void isr(void) __interrupt(0) { if(INTFbits.PABIF) { if(yy) { OSCCR = C_Normal_Mode | C_FHOSC_Sel; INTE = 0X0A; PCON = 0X98; //ADMD = 0x9B; AWUCON = 0X00; BWUCON = 0x00; //开启定时器1 3 T1CR1 |= 0X01; T3CR1 |= 0X80; //开启PWM3 P4CR1 |= 0X80; //开启PWM4 yy = 0; } INTFbits.PABIF = 0; } if(INTFbits.T1IF) { for(i=0;i<TASK_NUM;i++) { if(TaskCount[i]) { TaskCount[i]--; if(!TaskCount[i]) { TaskMake[i] = 1; //任务可以运行 TaskCount[i] = ltvTime[i]; //恢复计时器值 } } } if(i >= TASK_NUM) { i = 0; } data_output(); irin_work(); INTFbits.T1IF = 0; } } 这个程序的红外接收用不了了,接收引脚好像是把红外输出拉低了,一直是低电平。 #include <ny8.h> #include "NY8_constant.h" #define MCUO2 PA6 #define KEY PA7 #define LED PA5 #define TIM PA1 #define IRIN PB4 #define NM8_G PA0 #define M2O1 PB0 #define M2O2 PB1 #define M2O3 PB2 #define M2O4 PB3 #define MCUO PA4 #define OLED PA2 #define CTL_M PB5 #define Coil_A { M2O1 = 1; M2O2 = 0; M2O3 = 0; M2O4 = 0;} #define Coil_AB { M2O1 = 1; M2O2 = 1; M2O3 = 0; M2O4 = 0;} #define Coil_B { M2O1 = 0; M2O2 = 1; M2O3 = 0; M2O4 = 0;} #define Coil_BC { M2O1 = 0; M2O2 = 1; M2O3 = 1; M2O4 = 0;} #define Coil_C { M2O1 = 0; M2O2 = 0; M2O3 = 1; M2O4 = 0;} #define Coil_CD { M2O1 = 0; M2O2 = 0; M2O3 = 1; M2O4 = 1;} #define Coil_D { M2O1 = 0; M2O2 = 0; M2O3 = 0; M2O4 = 1;} #define Coil_DA { M2O1 = 1; M2O2 = 0; M2O3 = 0; M2O4 = 1;} #define TASK_NUM 7 //最大任务数 unsigned char TaskCount[TASK_NUM] = {1,30,30,100,100,125,1}; //任务计时器 unsigned char TaskMake[TASK_NUM] = {0,0,0,0,0,0,0}; //任务运行标志位 unsigned char const ltvTime[TASK_NUM]={1,30,30,100,100,125,1}; unsigned char S_Time=0,x=0; unsigned char i,j; unsigned char sleep_t=0; //电机 unsigned char Count=0; unsigned char Coil=0; unsigned char const Seepd=5; unsigned char Dir_Time=0; unsigned int StepNumber=4224; unsigned char Sleep_Time=0; unsigned int Step_conut=0; unsigned int tmp=0,LastValue=0; unsigned char DATA_LB=0,DATA_HB=0; unsigned int DATA=0; unsigned int V_E=0; unsigned char fan=0; unsigned char led_dat=0; unsigned char clock=0; unsigned char Motor_Go=0; unsigned char Motor_Stop=0; unsigned char dangwei_count=0; unsigned char tdangwei_count=0; unsigned char al=0xff; __sbit k1=al:0; __sbit k2=al:1; __sbit k3=al:2; __sbit k1_last=al:3; __sbit k2_last=al:4; __sbit k3_last=al:5; __sbit k4 = al:6; __sbit k4_last = al:7; unsigned char bl = 0x60; __sbit yy = bl:0; __sbit sleep_bit = bl:1; //__sbit Motor_Go = bl:2; __sbit close = bl:3; __sbit dangwei_go = bl:4; __sbit key_ir = bl:5; __sbit key_ir_last = bl:6; __sbit IR_AG = bl:7; unsigned char cl = 0x00; __sbit direction = cl:0; __sbit first = cl:1; __sbit tdangwei_go = cl:2; //__sbit Motor_Stop = cl:3; __sbit Motor_dc = cl:4; void Wait(void) { while (ADMDbits.EOC == 0) ; } void Delay(char count) { char m; for (m = 1; m <= count; m++) ; } void GPIO_Init(void){ BPHCON = 0XFF; ABPLCON = 0XFF; IOSTB = 0X10;//PB4 IOSTA = 0XE3;//PA0、1、5、6、7 APHCON = 0XFF; PORTA = 0X00; PORTB = 0X00; PACON = 0x02; //PA1纯模拟输入 } void sleep_Init(void) { INTFbits.PABIF = 0; AWUCON = 0X00; BWUCON = 0X00; INTE |= C_INT_PABKey; } void Time_Init(void) { //200us T1CR1 = C_TMR1_Dis; TMRH = 0x00; TMR1 = 0x7C; T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Div8; INTE = C_INTE_TMR1; T1CR1 = C_TMR1_Reload | C_TMR1_En; } void PWM_Init(void) { //100k TM3RH = 0x00; TMR3 = 49; PWM4DUTY = 0x00; T3CR2 = C_TMR3_ClkSrc_Inst | C_PS3_Dis; T3CR1 = C_PWM3_En | C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; P4CR1 = C_PWM4_En | C_PWM4_Active_Hi; } void ADC_Init(void) { DATA_LB = DATA_HB = 0X00; ADR = C_Ckl_Div8; ADCR = C_Sample_8clk | C_12BIT; Delay(50); } unsigned int ADC_ReadValue(void) { ADVREFH = 0x03; //参考电压:0x00:2V,0x02:4V,0x03:VCC ADMD = 0x91; ADMDbits.START = 1; Wait(); DATA_LB = ADR & 0X0F; DATA_HB = ADD; DATA = (DATA_HB << 4) | DATA_LB ; tmp = (8 * DATA + 2 * LastValue) / 10 + 1; LastValue = DATA; return tmp; } void Motor_work(void) { if(direction){ Count++; if(Count > Seepd){ // 每1.25ms切换一次线圈 Coil++; Count = 0; } if(Coil > 7){ Coil = 0; } switch(Coil){ case 0: Coil_A; break; case 1: Coil_AB; break; case 2: Coil_B; break; case 3: Coil_BC; break; case 4: Coil_C; break; case 5: Coil_CD; break; case 6: Coil_D; break; case 7: Coil_DA; break; } } else { Count++; if(Count > Seepd){ // 每1.25ms切换一次线圈 Coil++; Count = 0; } if(Coil > 7){ Coil = 0; } switch(Coil){ case 0: Coil_DA; break; case 1: Coil_D; break; case 2: Coil_CD; break; case 3: Coil_C; break; case 4: Coil_BC; break; case 5: Coil_B; break; case 6: Coil_AB; break; case 7: Coil_A; break; } } } void ULN2003A(void) { if(!fan && StepNumber != 4224) { Motor_Stop = 1; } // //回到中间: // //计算步进值,假设左到右走8448步,那么中间值是8448/2=4224步 // //如果当前步数大于4224步说明已超过中间值,这时控制步进电机走(当前步数-4224)的相反步数,回到中间。 // //如果当前步数小于4224步说明未超过中间值,这是控制步进电机走(4224-当前步数)的同向步数,回到中间。 if(Motor_Stop) { Motor_work(); if(StepNumber > 4224 && !Step_conut) { Motor_dc = 1; Step_conut = StepNumber; direction = !direction; } else if(StepNumber < 4224 && !Step_conut) { Motor_dc = 0; Step_conut = StepNumber; } if(Motor_dc) { Dir_Time++; if(Dir_Time > Seepd) { Dir_Time = 0; Step_conut--; //停止后是4224 StepNumber--; if(Step_conut <= 4224) { Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 4224; Motor_Stop = 0; Step_conut = 0; } } } else { Dir_Time++; if(Dir_Time > Seepd) { Dir_Time = 0; Step_conut++; //停止后是4224 StepNumber++; if(Step_conut >= 4224) { Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 4224; Motor_Stop = 0; Step_conut = 0; } } } } else if(Motor_Go){ Motor_work(); Dir_Time++; if(Dir_Time > Seepd){ Dir_Time = 0; StepNumber++; if(StepNumber > 8448){ //1056*8 // 关键修改:调整Coil确保相位连续 Coil = 7 - Coil; // 将线圈位置映射到反向序列的对应位置 direction = !direction; StepNumber = 0; } } } else { M2O1 = 0; M2O2 = 0; M2O3 = 0; M2O4 = 0; } } unsigned char k1_time=0,k2_time=0; unsigned char u1=0,u2=0,u3=0; unsigned long int timing_temp=0; unsigned int timing_count=0; unsigned char stop=0; unsigned char stop_time=0; unsigned char go_time=0; unsigned int key_value=0; void key_scanf(void) { //6ms key_value = ADC_ReadValue(); if(key_value < 200) { //TIM(0) k3 = 0; } if(key_value > 1200) { //YT(1/2) k4 = 0; } if(key_value > 3200) { //松开 k3 = 1; k4 = 1; } k1 = KEY;k2 = LED; if(!stop) { if(!k1 && k1_last) { k1_time = 0; u1 = 0; } if(!k1 && !k1_last && !u1) { k1_time++; if(k1_time > 250) { k1_time = 0; u1 = 1; } } if(k1 && !k1_last && !u1) { if(k1_time > 5) { fan++; } } if(!k2 && k2_last) { k2_time = 0; u2 = 0; } if(!k2 && !k2_last && !u2) { k2_time++; if(k2_time > 250) { k2_time = 0; u2 = 1; } } if(k2 && !k2_last && !u2) { if(k2_time > 5) { led_dat++; } } if(k3 && !k3_last) { clock++; tdangwei_go = 1; tdangwei_count = 0; timing_count = 0; } if(k4 && !k4_last) { Motor_Go = !Motor_Go; } } if(NM8_G) { go_time = 0; stop_time++; if(stop_time > 80) { //0.48s stop_time = 0; stop = 1; fan = 0; clock = 0; timing_count = 0; led_dat = 0; PWM3DUTY = 0; T3CR1 &= 0X7F; //关闭PWM3 } } if(!NM8_G) { stop_time = 0; go_time++; if(go_time > 80) { go_time = 0; stop = 0; T3CR1 |= 0X80; //开启PWM3 } } k1_last = k1;k2_last = k2;k3_last = k3;k4_last = k4; if(fan > 4) { fan = 0; led_dat = 0; } if(led_dat > 3) { led_dat = 0; } if(clock > 4) { clock = 0; } if(!fan) { Motor_Go = 0; clock = 0; } if(!clock) { tdangwei_go = 0; tdangwei_count = 0; } switch(clock) { case 0:timing_temp = 0;break; case 1:timing_temp = 14400;break; case 2:timing_temp = 28800;break; case 3:timing_temp = 57600;break; case 4:timing_temp = 115200;break; } if(tdangwei_go) { tdangwei_count++; if(tdangwei_count > 250) { tdangwei_go = 0; tdangwei_count = 0; } } else { tdangwei_count = 0; } } void led_work(void) { //6ms switch(led_dat) { case 0:PWM3DUTY = 0;break; case 1:PWM3DUTY = 25;break; case 2:PWM3DUTY = 35;break; case 3:PWM3DUTY = 49;break; } } unsigned char fan_time=0; unsigned char fan4_bit=0; void fan_work(void) { //20ms if(fan) { CTL_M = 1; }else { CTL_M = 0; } if(fan == 4) { //4-4 fan_time++; if(fan_time > 200) { //4s fan_time = 0; fan4_bit = !fan4_bit; } if(fan4_bit) { CTL_M = 1; if(MCUO2) PWM4DUTY = 10; else PWM4DUTY = 14; }else { PWM4DUTY = 0; CTL_M = 0; } } else { fan_time = 0; } if(MCUO2) switch(fan) { case 0:PWM4DUTY = 0;break; case 1:PWM4DUTY = 10;break; case 2:PWM4DUTY = 15;break; case 3:PWM4DUTY = 20;break; } else if(!MCUO2) switch(fan) { case 0:PWM4DUTY = 0;break; case 1:PWM4DUTY = 14;break; case 2:PWM4DUTY = 22;break; case 3:PWM4DUTY = 30;break; } } unsigned char cti=0; void timing(void) { //250ms if(clock) { cti++; if(cti > 10) { cti = 0; timing_count++; //250ms加一 } if(timing_count > timing_temp) { timing_count = 0; timing_temp = 0; fan = 0; led_dat = 0; clock = 0; } } else { timing_count = 0; } } unsigned char low_go=0; unsigned char hight_go=0; unsigned char low_t; unsigned char high_t; unsigned int IR_dat=0; unsigned int IR_dat_last=0; unsigned char Start=0; unsigned char on=1; unsigned int on_time=0; unsigned char low_count=0; //下降沿计数,12个为一组数 unsigned int ac_t=0; //高电平超过10ms数据清零 //低电平到下一个上升沿时间超过800us为数据1 //低电平到下一个上升沿时间小于800us为数据0 void irin_work(void) { key_ir = IRIN; if(!key_ir && key_ir_last) { //下降沿 IR_dat <<= 1; low_go = 1; hight_go = 0; low_t = 0; } if(key_ir && !key_ir_last) { //上升沿 hight_go = 1; low_go = 0; on_time = 0; if(low_t > 4) { //低电平持续时间超过800us IR_dat |= 0x01; } high_t = 0; } if(low_go) { low_t++; } if(hight_go) { high_t++; on_time++; } if(on_time > 250) { //50ms,高电平超过50ms时on为1,否则为0 on = 1; on_time = 251; }else { on = 0; } if(IR_AG) { if(high_t > 100) { //超过20ms松手 high_t = 0; IR_dat = 0; IR_AG = 0; } }else { if(high_t > 20) { //超过4ms数据清零 IR_dat = 0; high_t = 0; } } if(!IR_AG) { if(IR_dat == 0xd81) { //夜灯 IR_AG = 1; led_dat++; IR_dat = 0; } if(IR_dat == 0xd82 && Start) { //摇头 IR_AG = 1; Motor_Go = !Motor_Go; IR_dat = 0; } if(IR_dat == 0xdac) { //挡位短按(开) IR_dat_last = IR_dat; IR_dat = 0; } if(IR_dat_last == 0xdac) { //有波形的时候on为1,波形消失20ms后,on为0 ac_t++; if(ac_t > 5000) { //1.0s(5000) ac_t = 0; fan = 0; led_dat = 0; IR_dat_last = 0; IR_dat = 0; on = 1; IR_AG = 1; } else if(on) { fan++; dangwei_go = 1; dangwei_count = 0; IR_dat_last = 0; IR_dat = 0; ac_t = 0; } } if(IR_dat == 0xd88 && Start) { //定时 IR_AG = 1; clock++; timing_count = 0; tdangwei_go = 1; tdangwei_count = 0; IR_dat = 0; } } if(fan > 4) { fan = 0; led_dat = 0; } if(clock > 4) { clock = 0; } if(!clock) { tdangwei_go = 0; tdangwei_count = 0; } if(led_dat > 3) { led_dat = 0; } if(fan) { Start = 1; }else { Start = 0; Motor_Go = 0; clock = 0; dangwei_count = 0; dangwei_go = 0; } key_ir_last = key_ir; } unsigned int mcu_date=0; unsigned int out_count=0; unsigned char out_time=0; void data_output(void) { //200us if(!out_count) { mcu_date = 0; mcu_date |= ((unsigned int)fan << 12); if(!tdangwei_go) mcu_date |= (((unsigned int)clock) << 8); else mcu_date |= (((unsigned int)clock + 8) << 8); mcu_date |= ((unsigned int)led_dat << 4); mcu_date |= Motor_Go; out_time++; if(out_time > 125) { //125 * 200us = 50000us = 25ms out_time = 0; out_count = 1; } } else if(out_count < 17) { //16次 if(mcu_date & 0x8000) { //取高位,如果是1,高电平持续1.5ms out_time++; if(out_time < 8) { //1.5ms = 200 * 7.5 MCUO = 1; } else if(out_time > 25) { //5ms = 200us * 25 MCUO = 0; out_time = 0; out_count++; mcu_date <<= 0x0001; } else if(out_time > 8) { MCUO = 0; } } else { //如果是0,高电平持续3.5ms out_time++; if(out_time < 18) { //3.5ms = 200 * 17.5 MCUO = 1; } else if(out_time > 25) { //5ms = 200 * 25 MCUO = 0; out_time = 0; out_count++; mcu_date <<= 0x0001; } else if(out_time > 18) { MCUO = 0; } } } else { out_count = 0; } } void SLEEPING(void)//20 { if(!fan && IRIN && !MCUO2 && !led_dat && KEY && LED && !Motor_Stop) { sleep_t++; if(sleep_t > 100) { //2s sleep_t = 0; PWM3DUTY = 0; PWM4DUTY = 0; close = 1; sleep_bit = 1; } }else { sleep_t = 0; } if(sleep_bit) { sleep_bit = 0; yy = 1; PORTA = 0X00; PORTB = 0X00; ADMD &= 0X6F; //bit7清零,关闭ADC T1CR1 &= 0XFE; //关闭定时器1 T3CR1 &= 0X7F; //关闭PWM3 P4CR1 &= 0X7F; //关闭PWM4 INTE = 0X02; //只开启输入状态变化中断 PCON = 0X10; //关闭看门狗和低压复位,关闭PA5上拉 AWUCON = 0XE0;//PA5,6,7 BWUCON = 0X10;//PB4 dangwei_count = 0; dangwei_go = 0; sleep_t = 0; SLEEP(); } } void taskScheduler(void) //任务调度器 { for(j=0;j<TASK_NUM;j++) { if(TaskMake[0]){ ULN2003A(); TaskMake[0] = 0; } if(TaskMake[1]){ key_scanf(); TaskMake[1] = 0; } if(TaskMake[2]){ led_work(); TaskMake[2] = 0; } if(TaskMake[3]){ fan_work(); TaskMake[3] = 0; } if(TaskMake[4]){ SLEEPING(); TaskMake[4] = 0; } if(TaskMake[5]){ timing(); TaskMake[5] = 0; } //if(TaskMake[6]){ // data_output(); // TaskMake[6] = 0; //} } if(j >= TASK_NUM) { j = 0; } } void main(void) { DISI(); GPIO_Init(); sleep_Init(); Time_Init(); PWM_Init(); ADC_Init(); ENI(); while(1) { CLRWDT(); taskScheduler(); } } void isr(void) __interrupt(0) { if(INTFbits.PABIF) { if(yy) { OSCCR = C_Normal_Mode | C_FHOSC_Sel; INTE = 0X0A; PCON = 0X98; //ADMD = 0x9B; AWUCON = 0X00; BWUCON = 0x00; //开启定时器1 3 T1CR1 |= 0X01; T3CR1 |= 0X80; //开启PWM3 P4CR1 |= 0X80; //开启PWM4 yy = 0; } INTFbits.PABIF = 0; } if(INTFbits.T1IF) { for(i=0;i<TASK_NUM;i++) { if(TaskCount[i]) { TaskCount[i]--; if(!TaskCount[i]) { TaskMake[i] = 1; //任务可以运行 TaskCount[i] = ltvTime[i]; //恢复计时器值 } } } if(i >= TASK_NUM) { i = 0; } data_output(); irin_work(); INTFbits.T1IF = 0; } } 这个是他的上一个版本,红外功能是完善的,帮我找出问题,究竟是改了哪里导致的?
最新发布
08-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xiao艾扶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值