📄 chap6.c
字号:
// Chapter 6 6811 C programs// Jonathan W. Valvano// This software accompanies the book,// Embedded Microcomputer Systems: Real Time Interfacing// published by Brooks Cole, 1999// Program 6.3. Periodic interrupt using input capture and an external clock.// MC68HC11A8// PA0 input = external signalunsigned int TIME; // incrementedvoid Init(void){asm(" sei"); // make atomic TCTL2 = (TCTL2&0xFC)|0x01; TMSK1 |= 0x01; // Arm IC3 TFLG1=0x01; // initially clear TIME=0; asm(" cli");}#pragma interrupt_handler IC3Hanvoid IC3Han(void){ if((TFLG1&0x01)==0) asm(" swi"); TFLG1=0x01; // acknowledge TIME++;} // Program 6.6. C language period measurement.// MC68HC11A8// PA2/IC1 input = external signal// rising edge to rising edge// resolution = 500ns // Range = 36 祍 to 32 ms, // no overflow checking// IC1 interrupt each period,unsigned int Period; // units of 500 nsunsigned int First; // TCNT first edgeunsigned char Done; // Set each rising void Ritual(void){ asm(" sei"); // make atomic TCTL2 = (TCTL2&0xCF)|0x10; // rising First = TCNT; // first will be wrong Done=0; // set on subsequent TFLG1 = 0x04; // Clear IC1F TMSK1 |= 0x04; // Arm IC1 asm(" cli");}#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Period=TIC1-First; First=TIC1; // Setup for next TFLG1=0x04; // ack by clearing IC1F Done=0xFF;}// Program 6.10. C language 32-bit period measurement.// MC68HC11A8unsigned int MsPeriod,LsPeriod; unsigned int First; unsigned int Count; unsigned char Mode;#pragma interrupt_handler TOhandler()void TOhandler(void){ TFLG2=0x80; Count++; if(Count==65535){ // 35 minutes MsPeriod=LsPeriod=65535; TMSK1=0x00; TMSK2=0x00; // Disarm Mode=2;}}#pragma interrupt_handler TIC1handler()void TIC1handler(void){ if(Mode==0){ First = TIC1; Count=0; Mode=1; if(((TIC1&0x8000)==0) &&(TFLG2&0x80)) Count--;} else { if(((TIC1&0x8000)==0) &&(TFLG2&0x80))Count++; MsPeriod=Count; Mode=2; LsPeriod=TIC1-First; if (TIC1<First) MsPeriod--; TMSK1=0x00; TMSK2=0x00;} // Disarm TFLG1=0x04;} // ack, clear IC1Fvoid Ritual(void){ asm(" sei"); // make atomic TFLG1 = 0x04; // Clear IC1F TMSK1 |= 0x04; // Arm IC1 TCTL2 = (TCTL2&0xCF)|0x10; // rising TFLG2 = 0x80; // Clear TOF TMSK2 |= 0x80; // Arm TOF Mode=0; asm(" cli"); }// Program 6.13. C language pulse width measurement.// MC68HC11A8unsigned int Measure(void) { unsigned int Rising; TCTL2=(TCTL2&0xF3)|0x04; // Rising edge TFLG1=0x02; // clear IC2F PORTB&=0x7F; PORTB|=0x80; // rising edge on PB7 while(TFLG1&0x02==0){}; // wait rise Rising=TIC2; // TCNT at rising edge TCTL2=(TCTL2&0xF3)|0x08; // Falling edge TFLG1=0x02; // clear IC2F while(TFLG1&0x02==0){}; // wait fall return(TIC2-Rising-1000); } void Init(void){ TMSK1=0x00;} // no interrupts TMSK1=0x00;} // no interrupts// Program 6.15. C language pulse width measurement.// MC68HC11A8unsigned int PW; // units of 500 ns unsigned int Rising; // TCNT at risingunsigned char Done; // Set each falling#define PA2 0x04 // the input signal #pragma interrupt_handler TIC1handler()void TIC1handler(void){ if(PORTA&PA2){ // PA2=1 if rising Rising=TIC1;} // Setup for next else{ PW=TIC1-Rising; // the measurement Done=0xFF;} TFLG1=0x04;} // ack, IC1F=0 void Ritual(void){ asm(" sei"); // make atomic TCTL2 |= 0x30; // IC1F set on both rising and falling Rising = TCNT; // current TCNT Done=0; // set on falling TFLG1 = 0x04; // Clear IC1F TMSK1|= 0x04; // Arm IC1 asm(" cli");}// Program 6.17. C language pulse width measurement using two input captures.// MC68HC11A8unsigned int PW; // units of 500 ns unsigned char Done; // Set each falling#pragma interrupt_handler TIC1handler()void TIC1handler(void){ PW=TIC1-TIC2; // time from rise to fall Done=0xFF; TFLG1=0x04;} // ack by clearing IC1Fvoid Ritual(void){ asm(" sei"); // make atomic TCTL2=(TCTL2&0xCF)|0x20; // falling edges of IC1, TCNT->TIC1 TCTL2=(TCTL2&0xF3)|0x04; // rising edges of IC2, TCNT->TIC2 Done=0; // set on the falling edge TFLG1 = 0x04; // Clear IC1F TMSK1|= 0x04; // Arm IC1, not IC2 asm(" cli");}// Program 6.21. C language periodic interrupt using output compare.// MC68HC11A8#define Rate 2000#define OC5 0x08unsigned int Time; // Inc every 1ms #pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1=OC5; // Ack interrupt TOC5=TOC5+Rate; // Executed every 1 ms Time++; }void ritual(void) { asm(" sei"); // make atomic TMSK1|=OC5; // Arm output compare 5 Time = 0; TFLG1=OC5; // Initially clear OC5F TOC5=TCNT+Rate; // First one in 1 msasm(" cli"); }// Program 6.24. C language squarewave using output compare.// MC68HC11A8unsigned int Period; // Period in usec // Number of Cycles Low and number High #pragma interrupt_handler TOC3handler()void TOC3handler(void){ TOC3=TOC3+Period; // calculate Next TFLG1=0x20;} // ack, OC3F=0void ritual(void){ asm(" sei"); // make atomic TFLG1 = 0x20; // clear OC3F TMSK1|= 0x20; // arm OC3 TCTL1 = (TCTL1&0xCF)|0x10; // PA5 toggle on each interrupt TOC3 = TCNT+50; // first right away asm(" cli"); }// Program 6.27. C language pulse-width modulated squarewave using output compare.// MC68HC11A8unsigned int High; // Num of Cycles Highunsigned int Low; // Num of Cycles Low // Period is High+Low Cycles#pragma interrupt_handler TOC3handler()void TOC3handler(void){ if(TCTL1&0x10){ // PA5 is now high TOC3=TOC3+High; // 1 for High cyc TCTL1&=0xEF;} // clear on next else { // PA5 is now low TOC3=TOC3+Low; // 0 for Low cycles TCTL1|=0x10;} // set on next int TFLG1=0x20;} // ack, clear OC3F void ritual(void){ asm(" sei"); // make atomic TFLG1 = 0x20; // initially OC3F=0 TMSK1|= 0x20; // arm OC3 TCTL1|= 0x30; // PA5 set on next int TOC3 = TCNT+50; // first right away asm(" cli"); }void main(void){ High=8000; Low=2000; ritual(); while(1);}// Program 6.28. C language delayed pulse output using output compare.// MC68HC11A8void Pulse(unsigned int Delay, unsigned int Width){ asm(" sei"); // make atomic TOC1=TCNT+Delay; TOC3=TOC1+Width; OC1M=0x20; // connect OC1 to PA5/OC3 OC1D=0x20; // PA5=1 when TOC1=TCNT TCTL1=(TCTL1&0xCF)|0x20; // PA5=0 when TOC3=TCNT TFLG1 = 0x20; // Clear OC3F TMSK1|= 0x20; // Arm OC3F asm(" cli");}#pragma interrupt_handler TOC3handler()void TOC3handler(void){ OC1M=0; // disconnect OC1 from PA5 OC1D=0; TCTL1&=0xCF; // disable OC3 TMSK1&=0xDF;} // disarm OC3F // Program 6.30. C language frequency measurement.// MC68HC11A8#define IC1F 0x04 // connected here#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Count++; // number of rising edges TFLG1=IC1F;} // ack, clear IC1F#define Rate 20000 // 10 ms #define OC5F 0x08#pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1= OC5F; // Acknowledge TOC5 = TOC5+Rate; // every 10 ms Freq = Count; // 100 Hz units Done = 0xff; Count = 0; } // Setup for next void ritual(void) { asm(" sei"); // make atomic TMSK1|=OC5F+IC1F; // Arm OC5 and IC1 TOC5=TCNT+Rate; // First in 10 ms TCTL2 = (TCTL2&0xCF)|0x10; /* IC1F set on rising edges */ Count = 0; // Set up for first Done=0; /* Set on the subsequent measurements */ TFLG1=OC5F+IC1F; // clear OC5F, IC1F asm(" cli"); }// Program 6.33. C language implementation of period measurement.// MC68HC11A8#define resolution 2000#pragma interrupt_handler TOC3handler()void TOC3handler(void){ TOC3=TOC3+resolution; // every 1 ms TFLG1=0x20; // ack, clear OC3F Cnt++; if(Cnt==0) OverFlow=0xFF;}#pragma interrupt_handler TIC1handler()void TIC1handler(void){ TFLG1=0x04; // ack, clear IC1F if(OverFlow){ Period=65535; OverFlow=0;} else Period=Cnt; Cnt=0; Done=0xFF;}void Ritual(void){ asm(" sei"); // make atomic TFLG1 = 0x24; // Clear OC3F,IC1F TMSK1 = 0x24; // Arm OC3 and IC1 TCTL2 = 0x10; // rising edges while((TFLG1&0x04)==0); // wait for first rising TFLG1 = 0x04; // Clear IC1F TOC3=TCNT+resolution; Cnt=0; OverFlow=0; Done=0; asm(" cli"); } // Program 6.36. C language implementation of frequency measurement.// MC68HC11A8#define IC1F 0x04 // connected here#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Count++; // number of rising edges TFLG1=IC1F;} // ack, clear IC1F#define Rate 50000 // 25 ms #define OC5F 0x08#pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1= OC5F; // Acknowledge TOC5 = TOC5+Rate; // every 25 ms if (++FourHundred==400){ Freq = Count; // 0.1 Hz units FourHundred=0; Done = 0xff; Count = 0; }} // Setup for nextvoid ritual(void) { asm(" sei"); // make atomic TMSK1|=OC5F+IC1F; // Arm OC5 and IC1 TOC5=TCNT+Rate; // First in 25 ms TCTL2 = (TCTL2&0xCF)|0x10; /* IC1F set on rising edges */ Count = 0; // Set up for first Done=0; // Set on subsequent meas FourHundred=0; TFLG1 = OC5F+IC1F; // Clear OC5F IC1Fasm(" cli"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -