📄 chap6.c
字号:
// Chapter 6 6812 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.// MC68HC812A4// PT3 input = external signalunsigned int TIME; // incrementedvoid Init(void){asm(" sei"); // make atomic TIOS &= 0xF7; // PT3 input capture DDRT &= 0xF7; // PT3 is input TSCR = 0x80; // enable TCNT TMSK2= 0x32; // 500ns clock TCTL4 = (TCTL4&0x3F)|0x40; TMSK1 |= 0x08; // Arm IC3 TFLG1=0x08; // initially clear TIME=0; asm(" cli");}#pragma interrupt_handler IC3Hanvoid IC3Han(void){ if((TFLG1&0x08)==0) asm(" swi"); TFLG1=0x08; // acknowledge TIME++;} // Program 6.6. C language period measurement.// MC68HC812A4// PT1/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 TIOS &= 0xFD; // PT1 input capture DDRT &= 0xFD; // PT1 is input TSCR = 0x80; // enable TCNT TMSK2= 0x32; // 500ns clock TCTL4 = (TCTL4&0xF3)|0x04; // rising First = TCNT; // first will be wrong Done=0; // set on subsequent TFLG1 = 0x02; // Clear C1F TMSK1 |= 0x02; // Arm IC1 asm(" cli");}#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Period=TC1-First; First=TC1; // Setup for next TFLG1=0x02; // ack by clearing C1F Done=0xFF;}// Program 6.10. C language 32-bit period measurement.// MC68HC812A4unsigned 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 = TC1; Count=0; Mode=1; if(((TC1&0x8000)==0) &&(TFLG2&0x80)) Count--;} else { if(((TC1&0x8000)==0) &&(TFLG2&0x80))Count++; MsPeriod=Count; Mode=2; LsPeriod=TC1-First; if (TC1<First) MsPeriod--; TMSK1=0x00; TMSK2=0x00;} // Disarm TFLG1=0x02;} // ack, clear C1Fvoid Ritual(void){ asm(" sei"); // make atomic TIOS &= 0xFD; // PT1 input capture DDRT &= 0xFD; // PT1 is input TMSK2=0xB2 ; // Arm, TOF 30.517Hz TSCR=0x80; // enable counter TFLG1 = 0x02; // Clear C1F TMSK1 |= 0x02; // Arm IC1, C1I=1 TCTL4 = (TCTL4&0xFC)|0x04; // rising TFLG2 = 0x80; // Clear TOF Mode=0; asm(" cli"); }// Program 6.13. C language pulse width measurement.// MC68HC812A4unsigned int Measure(void) { unsigned int Rising; TCTL4=(TCTL4&0xCF)|0x10; // Rising edge TFLG1=0x04; // clear C2F PORTB&=0x7F; PORTB|=0x80; // rising edge on PB7 while(TFLG1&0x04==0){}; // Wait for rise Rising=TC2; // TCNT at rising edge TCTL4=(TCTL4&0xCF)|0x20; // Falling edge while(TFLG1&0x04==0){}; // Wait for fall return(TC2-Rising-1000); } void Init(void){ DDRB|=0x80; // PB7 is output TIOS&=0xFB; // clear bit 2 DDRT&=0xFB; // PT2 is input capture TSCR=0x90; // enable, fast clear TMSK2=0x32; // 500 ns clock TMSK1=0x00;} // no interrupts// Program 6.15. C language pulse width measurement.// MC68HC812A4unsigned int PW; // units of 500 ns unsigned int Rising; // TCNT at risingunsigned char Done; // Set each falling#define PT1 0x02 // the input signal #pragma interrupt_handler TIC1handler()void TIC1handler(void){ if(PORTT&PT1){ // PT1=1 if rising Rising=TC1;} // Setup for next else{ PW=TC1-Rising; // the measurement Done=0xFF;} // ack, fast clr C1F=0 void Ritual(void) { asm(" sei"); // make atomic TIOS&=~PT1; // clear bit 1 DDRT&=~PT1; // PT1 is input capture TSCR=0x90; // enable, fast clear TMSK2=0x32; // 500 ns clock TCTL4|=0x0C; // Both edges IC1 TMSK1|=0x02; // arm IC1 TFLG1=0x02; // clear C1F Done=0; asm(" cli");}// Program 6.17. C language pulse width measurement using two input captures.// MC68HC812A4unsigned int PW; // units of 500 ns unsigned char Done; // Set each falling#pragma interrupt_handler TIC1handler()void TIC1handler(void){ TFLG1=0x02; // ack C1F PW=TC1-TC2; // the measurement Done=0xFF;} void Ritual(void) { asm(" sei"); // make atomic TIOS&=0xF9; // clear bits 2,1 DDRT&=0xF9; // PT2,PT1 input captures TSCR=0x80; // enable TMSK2=0x32; // 500 ns clock TCTL4=(TCTL4&0xCF)|0x10; // IC2 Rise TCTL4=(TCTL4&0xF3)|0x08; // IC1 Fall Done=0; // set on the falling edge TMSK1|=0x02; // arm IC1, not IC2 TFLG1=0x02; // clear C1F asm(" cli");}// Program 6.21. C language periodic interrupt using output compare.// MC68HC812A4#define Rate 2000#define OC5 0x20unsigned int Time; // Inc every 1ms #pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1=OC5; // ack OC5F TC5=TC5+Rate; // Executed every 1 ms Time++; }void ritual(void) { asm(" sei"); // make atomic TIOS|=OC5; // enable OC5 TSCR|=0x80; // enable TMSK2=0x32; // 500 ns clock TMSK1|=OC5; // Arm output compare 5 Time = 0; TFLG1=OC5; // Initially clear C5F TC5=TCNT+Rate; // First one in 1 msasm(" cli"); }// Program 6.24. C language squarewave using output compare.// MC68HC812A4unsigned int Period; // Period in usec // Number of Cycles Low and number High #pragma interrupt_handler TOC3handler()void TOC3handler(void){ TFLG1=0x08; // ack OC3F TC3=TC3+Period;} // calculate Nextvoid ritual(void) { asm(" sei"); // make atomic TIOS|=0x08; // enable OC3 DDRT|=0x08; // PT3 is output TSCR=0x80; // enable TMSK2=0x32; // 500 ns clock TCTL2 = (TCTL2&0x3F)|0x40; // PT3 toggle on each interrupt TMSK1|=0x08; // Arm output compare 3 TFLG1=0x08; // Initially clear C3F TC3=TCNT+50; // First one in 25 usasm(" cli"); }// Program 6.27. C language pulse-width modulated squarewave using output compare.// MC68HC812A4unsigned int High; // Num of Cycles Highunsigned int Low; // Num of Cycles Low // Period is High+Low Cycles#pragma interrupt_handler TOC3handler()void TOC3handler(void){ TFLG1=0x08; // ack OC3F if(TCTL2&0x40){ // PT3 is now high TC3=TC3+High; // 1 for High cyc TCTL2&=0xBF;} // clear on next else { // PT3 is now low TC3=TC3+Low; // 0 for Low cycles TCTL2|=0x40;}} // set on next intvoid ritual(void){ asm(" sei"); // make atomic TIOS|=0x08; // enable OC3 DDRT|=0x08; // PT3 is output TSCR=0x80; // enable TMSK2=0x32; // 500 ns clock TMSK1|=0x08; // Arm output compare 3 TFLG1=0x08; // Initially clear C3F TCTL2|= 0xC0; // PT3 set on next int TC3 = 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.// MC68HC812A4void Pulse(unsigned int Delay, unsigned int Width){ asm(" sei"); // make atomic TIOS|=0x08; // enable OC3 DDRT|=0x08; // PT3 is output TSCR=0x90; // enable, fast clear TMSK2=0x32; // 500 ns clock TC7=TCNT+Delay; TC3=TC7+Width; OC7M=0x08; // connect OC7 to PT3 OC7D=0x08; // PT3=1 when TC7=TCNT TCTL2=(TCTL2&0x3F)|0x80; // PT3=0 when TC3=TCNT TFLG1 = 0x08; // Clear C3F TMSK1|= 0x08; // Arm C3F asm(" cli");}#pragma interrupt_handler TOC3handler()void TOC3handler(void){ OC7M=0; // disconnect OC7 from PT3/OC3 OC7D=0; TCTL2&=0x3F; // disable OC3 TMSK1&=0xF7;} // disarm C3F // Program 6.30. C language frequency measurement.// MC68HC812A4#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Count++; // number of rising edges TFLG1=0x02;} // ack, clear C1F#define Rate 20000 // 10 ms #pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1= 0x20; // Acknowledge TC5 = TC5+Rate; // every 10 ms Freq = Count; // 100 Hz units Done = 0xff; Count = 0; } // Setup for next void ritual(void) { asm(" sei"); // make atomic TIOS|=0x20; // enable OC5 TSCR=0x80; // enable TMSK2=0x32; // 500 ns clock TMSK1|=0x22; // Arm OC5 and IC1 TC5=TCNT+Rate; // First in 10 ms TCTL4 = (TCTL4&0xF3)|0x04; /* C1F set on rising edges */ Count = 0; // Set up for first Done=0; /* Set on the subsequent measurements */ TFLG1=0x22; // clear OC5F asm(" cli"); }// Program 6.33. C language implementation of period measurement.// MC68HC812A4#define resolution 2000#pragma interrupt_handler TOC3handler()void TOC3handler(void){ TFLG1= 0x08; // Acknowledge TC3=TC3+resolution; // every 1 ms Cnt++; if(Cnt==0) OverFlow=0xFF;}#pragma interrupt_handler TIC1handler()void TIC1handler(void){ TFLG1=0x02; // ack, clear C1F if(OverFlow){ Period=65535; OverFlow=0;} else Period=Cnt; Cnt=0; Done=0xFF;}void Ritual(void){ asm(" sei"); // make atomic TIOS| = 0x08; // enable OC3 TSCR = 0x80; // enable TMSK2 = 0x32; // 500 ns clock TFLG1 = 0x0A; // Clear C3F,C1F TMSK1 = 0x0A; // Arm OC3 and IC1 TCTL4 = (TCTL4&0xF3)|0x04; /* C1F set on rising edges */ while((TFLG1&0x02)==0); // wait rising TFLG1 = 0x02; // Clear C1F TC3=TCNT+resolution; Cnt=0; OverFlow=0; Done=0; asm(" cli"); } // Program 6.36. C language implementation of frequency measurement.// MC68HC812A4#pragma interrupt_handler TIC1handler()void TIC1handler(void){ Count++; // number of rising edges TFLG1=0x02;} // ack, clear C1F#define Rate 50000 // 25 ms #pragma interrupt_handler TOC5handler()void TOC5handler(void){ TFLG1= 0x20; // Acknowledge TC5 = TC5+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 TIOS| = 0x20; // enable OC5 TSCR = 0x80; // enable TMSK2 = 0x32; // 500 ns clock TMSK1 = 0x22; // Arm OC5 and IC1 TCTL4 = (TCTL4&0xF3)|0x04; /* C1F set on rising edges */ TC5=TCNT+Rate; // First in 25 ms Count = 0; // Set up for first Done=0; // Set on subsequent meas FourHundred=0; TFLG1 = 0x22; // Clear C5F,C1F asm(" cli"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -