⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap8.c

📁 摩托罗拉Mc6811利程
💻 C
字号:
// Chapter 8 6811 C programs// Jonathan W. Valvano// This software accompanies the book,// Embedded Microcomputer Systems: Real Time Interfacing// published by Brooks Cole, 1999// Program 8.1. The MC68HC812A4 Port J initialization.// MC68HC812A4 only// Program 8.3. Switch debouncing using C software.// MC68HC11A8void WaitPress(void){     while (PORTA&0x01);        // Loop here until switch is pressed      TOC5=TCNT+20000;    // 10ms delay      TFLG1=0x08;         // Clear OC5F     while((TFLG1&0x08)==0);} // wait for switch to stop bouncingvoid WaitRelease(void){     while ((PORTA&0x01)==0);        // Loop here until switch is released      TOC5=TCNT+20000;    // 10ms delay      TFLG1=0x08;         // Clear OC5F     while((TFLG1&0x08)==0); }   // wait for switch to stop bouncing// no ritual required// Program 8.5. Another example of switch debouncing using C software.// MC68HC11A8unsigned char ReadPA0(void){unsigned char old;  old=PORTA&0x01;   // Current value  TOC5=TCNT+20000;  // 10ms delay  TFLG1=0x08;       //  Clear OC5F   while((TFLG1&0x08)==0){  // unchanged for 10ms?     if(old<>(PORTA&0x01)){ // changed?       old=PORTA&0x01;   // New value        TOC5=TCNT+20000;  // restart delay       TFLG1=0x08; }     // Clear OC5F   }  return(old);}// no ritual required//Program 8.6. Switch debouncing using interrupts in C software.// MC68HC11A8// counts the number of button pushes// signal connected to IC3=PA0unsigned int count; // times pushed#define wait 20000  // bounce wait (cyc) #pragma interrupt_handler TOC5handler()void TOC5handler(void){    TMSK1=0x01;    // Arm IC3, disarm OC5    TFLG1=0x01;    // clear IC3F     if(PORTA&0x01==0) count++;} // new count if PA0=0 #pragma interrupt_handler TIC3handler()void TIC3handler(void){    TMSK1=0x08;   // Disarm IC3, Arm OC5    TOC5=TCNT+wait;    TFLG1=0x08;}   // clear OC5F void Ritual(void){     asm(" sei");  // make atomic      TMSK1=0x01;   // Arm IC3, disarm OC5     TFLG1=0x01;   // clear IC3F      TCTL2 = 0x01; // IC3F set on rising     count=0;      asm(" cli"); }// Program 8.7. Another example of switch debouncing using interrupts in C software.// MC68HC11A8// counts the number of button pushes// signal connected to IC3=PA0unsigned int count; // times pushedchar LastState; // looking for touch?// true means open, looking for a touch// false means closed, looking for release  #define wait 20000  // bounce wait (cyc) #pragma interrupt_handler TOC5handler()void TOC5handler(void){    TMSK1=0x01;    // Arm IC3, disarm OC5    TFLG1=0x01;}   // clear IC3F #pragma interrupt_handler TIC3handler()void TIC3handler(void){    if(LastState){       count++; // a touch has occurred        LastState=0;}     else       LastState=1; // release occurred    TMSK1=0x08;   // Disarm IC3, Arm OC5    TOC5=TCNT+wait;    TFLG1=0x08;}   // clear OC5F void Ritual(void){     asm(" sei");  // make atomic      TMSK1=0x01;   // Arm IC3, disarm OC5     TFLG1=0x01;   // clear IC3F      TCTL2 = 0x01; // IC3F set on rising     count=0;     LastState=PORTA&0x01;     asm(" cli"); }// Program 8.9. C software interface of a direct connection keyboard.// MC68HC11A8unsigned int KEY;    // current pattern #define wait 20000   // bounce time (cyc)void Ritual(void){     asm(" sei");     // make atomic      TMSK1=0x00;  // Disarm OC5     DDRC=0;          // PortC are inputs from the keyboard     PIOC=0x54;          // Input hndshk, fall, arm, STRB neg pulse     KeyBoard();     // Initially read      asm(" cli"); }void KeyBoard(void){     dummyRead=PIOC;  // read status     KEY=(PORTE<<8)+PORTCL;}  // Set global, clear STAF#pragma interrupt_handler IRQhandler()void IRQhandler(void){     PIOC=0x14;     // Disarm STAF      TMSK1=0x08;    // Arm OC5      TOC5=TCNT+wait;     TFLG1=0x08;}   // clear OC5F#pragma interrupt_handler TOC5handler()void TOC5handler(void){   TMSK1=0x00;  // Disarm OC5   PIOC=0x54;   // Rearm STAF    KeyBoard();} // Read keys, set LS374's// Program 8.10. C software interface of a direct connection keyboard using periodic polling.// MC68HC11A8unsigned int Key;     // current pattern #define period 20000  // 10ms pollingunsigned int KeyBoard(void){    return((PORTE<<8)+PORTC);} // patternvoid Ritual(void){    asm(" sei");  // make atomic     DDRC=0;       // inputs from keyboard    Key=KeyBoard();  // read 16 keys      TMSK1=0x08;      // Arm OC5     TOC5=TCNT+period;    TFLG1=0x08;      // clear OC5F      asm(" cli"); }#pragma interrupt_handler TOC5handler()void TOC5handler(void){      Key=KeyBoard();   // Current pattern     TOC5=TOC5+period;     TFLG1=0x08;}       // ack OC5F // Program 8.12. C software interface of a matrix scanned keyboard.// MC68HC11A8const struct Row{   unsigned char out;    unsigned char keycode[4];}#typedef const struct Row RowType;RowType ScanTab[5]={{   0x70, "abcd" },{   0xB0, "efgh" },{   0xD0, "ijkl" },{   0xE0, "mnop" },{   0x00, "    " }};void Ritual(void){ // PC3-PC0 are inputs    PIOC=0x40;     // CWOM=1     DDRC=0xF0;}    // PC7-PC4 are outputs/* Returns ASCII code for key pressed,    Num is the number of keys pressed     both equal zero if no key pressed */unsigned char Scan(unsigned int *Num){ RowType *pt; unsigned char column,key; int j;  (*Num)=0; key=0;    // default values    pt=&ScanTab[0];  while(pt->out){    PORTC=pt->out;  // select row     column=PORTC;   // read columns    for(j=3; j>=0; j--){      if((column&0x01)==0){         key=pt->keycode[j];         (*Num)++;}      column>>=1;} // shift into position     pt++; }  return key;}// Program 8.14. C software interface of a multiplexed keyboard.// MC68HC11A8// PC7-PC4 row output // PC3-PC0 column inputs unsigned char Key;    // current pattern unsigned char PreviousKey;  // 10ms ago #define period 20000        // 10 ms unsigned char KeyScan(void){      unsigned char key,row;    key=0;    // means no key pressed    for(row=0;row<16;row++){          PORTC=row<<4;  // Select row           if((PORTC&0x0F)!=0x0F){                key=PORTC^0x0F; }}       return(key);}void Ritual(void){     asm(" sei");   // make ritual atomic      DDRC=$F0;        PreviousKey=Key=KeyScan(); // read     TMSK1|=0x08;         // Arm OC5      TOC5=TCNT+wait;     TFLG1=0x08;         // clear OC5F      asm(" cli"); }#pragma interrupt_handler TOC5handler()void TOC5handler(void){ unsigned char NewKey;     NewKey=KeyScan(); // Current pattern       if(NewKey==PreviousKey) Key=NewKey;     PreviousKey=NewKey;     TOC5=TOC5+period;     TFLG1=0x08;}       // ack OC5F// Program 8.15. C software interface of a scanned LED display.// MC68HC11A8// PB7-PB0 output, 7 bit pattern // PC2-PC0 output, selects LED digit unsigned char code[3]; // binary codesstatic unsigned char select[3]={4,2,1};unsigned int index;    // 0,1,2#define OC5F 0x08#pragma interrupt_handler TOC5handler()void TOC5handler(void){   TFLG1=OC5F;      // Acknowledge    TOC5=TOC5+10000; // every 5 ms    PORTC=select[index]; // which LED?   PORTB=code[index];   // enable   if(++index==3) index=0;}void ritual(void) { asm(" sei");     // make atomic   index=0;   DDRC=0xFF;    // outputs   TMSK1|=OC5F;  // Arm OC5    TFLG1=OC5F;   // clear OC5F    TOC5=TCNT+10000; asm(" cli"); }// Program 8.16. C software interface of a multiplexed LED display.// MC68HC11A8unsigned int global; // 12 bit packed BCDconst struct LED{  unsigned char enable; // select   unsigned char shift;  // bits to shift    const struct LED *Next; };  // Link#typedef const struct LED LEDType;#typedef LEDType * LEDPtr;LEDType LEDTab[3]={{  0x04, 8, &LEDTab[1] },  // Most sig{  0x02, 4, &LEDTab[2] },{  0x01, 0, &LEDTab[0] }}; // least sigLEDPtr Pt;   // Points to current digit#define OC5F 0x08#pragma interrupt_handler TOC5handler()void TOC5handler(void){    TFLG1=OC5F;       // Acknowledge     TOC5=TOC5+10000;  // every 5 ms     PORTB=(Pt->enable)      +(global>>(pt->shift))<<4);    Pt=Pt->Next; }void ritual(void) { asm(" sei");        // make atomic     global=0;    TMSK1=OC5F;     // Arm OC5     Pt=&LEDTab[0];    TFLG1=OC5F;     // clear OC5F */    TOC5=TCNT+10000; asm(" cli"); }// Program 8.17. C software interface of an integrated LED display.// MC68HC11A8// PD3/MOSI = MC14489 DATA IN// PD4/SCLK = MC14489 CLOCK IN// PD5 (simple output) = MC14489 ENABLEvoid ritual(void) {     DDRD |= 0x38;  // outputs to MC14489    SPCR=0x50; // bit  meaning// 7 SPIE=0 no interrupts// 6 SPE=1  SPI enable// 5 DWOM=0 regular outputs// 4 MSTR=1 master// 3 CPOL=0 match timing with MC14489// 2 CPHA=0// 1 SPR1=0 E/2 is 1Mhz SCLK// 0 SPR0=0     PORTD|= 0x20; // ENABLE=1    PORTD&= 0xDF; // ENABLE=0    SPDR=0x01;    // hex format    while(SPSR&0x80)==0){};    PORTD|=0x20;} // ENABLE=1void LEDout(unsigned char data[3]){// 24 bit packed BCD    PORTD &= 0xDF;    // ENABLE=0    SPDR = data[2];   // send MSbyte    while(SPSR&0x80)==0){};    SPDR = data[1];   // send middle byte    while(SPSR&0x80)==0){};    SPDR = data[0];   // send LSbyte    while(SPSR&0x80)==0){};    PORTD |= 0x20;}   // ENABLE=1// Program 8.18. Helper function for a simple LCD display.void LCDOutDigit(unsigned char position, unsigned char data) { // position is 0x80, 0x40, 0x20, or 0x10  and data is the BCD digit	PORTB=0x0F&data;  // set BCD digit on the A-D inputs of the MC14543B	PORTB|=position;  // toggle one of the LD inputs high 	PORTB=0x0F&data;} // LD=0, latch digit into MC14543B// Program 8.19. C software interface of a simple LCD display.void LCDOutNum(unsigned int data){ unsigned int digit,num,i; unsigned char pos;      num=min(data,9999); // data should be unsigned from 0 to 9999      pos=0x10;   // position of first digit (ones)      for(i=0;i<4;i++){          digit=num%10; num=num/10; // next BCD digit 0 to 9          LCDOutDigit(pos,digit); pos=pos<<1;}}// Program 8.20. Bit-banged interface to a scanned LCD display.void LCDOut (unsigned char *pt) {unsigned int i;  unsigned char mask;     for(i=0;i<6;i++){         for(mask=0x80;mask;mask=mask>>1){  // look at bits 7,6,5,4,3,2,1,0          if((*pt)&mask) PORTB=1; else PORTB=0; // Serial data of the MC145000	    PORTB|=2;      // toggle the serial clock first high 	    PORTB&=0xFD;}  // then low       pt++; }}// Program 8.21. SPI interface to a scanned LCD display using a MC145000.// MC68HC11A8// PD3/MOSI = MC145000 DATA IN// PD4/SCLK = MC145000 CLOCK INvoid ritual(void) {     DDRD |= 0x18;  // outputs to MC145000     SPCR=0x50; }// bit  meaning// 7 SPIE=0 no interrupts// 6 SPE=1  SPI enable// 5 DWOM=0 regular outputs// 4 MSTR=1 master// 3 CPOL=0 match timing with MC14489// 2 CPHA=0// 1 SPR1=0 E/2 is 1Mhz SCLK// 0 SPR0=0 void LCDout(unsigned char data[6]){ unsigned int j;  for(j=5; j>=0 ; j--){    SPDR = data[j];   // Msbyte first    while(SPSR&0x80)==0){};}}// Program 8.22. Private functions for an HD44780 controlled LCD display.// MC68HC11A8// 1 by 16 char LCD Display (HD44780)//  ground = pin 1   Vss//  power  = pin 2   Vdd +5v//  10Kpot = pin 3   Vlc contrast adjust//  PB2    = pin 6   E  enable//  PB1    = pin 5   R/W 1=read, 0=write//  PB0    = pin 4   RS 1=data, 0=control//  PC0-7  = pins7-14 DB0-7 8 bit data#define LCDdata    1 // PB0=RS=1#define LCDcsr     0 // PB0=RS=0#define LCDread    2 // PB1=R/W=1#define LCDwrite   0 // PB1=R/W=0#define LCDenable  4 // PB2=E=1#define LCDdisable 0 // PB2=E=0void LCDcycwait(unsigned short cycles){    TOC5=TCNT+cycles; // 500ns cycles    TFLG1 = 0x08;     // clear C5F    while((TFLG1&0x08)==0){};}// Program 8.23. Public functions for an HD44780 controlled LCD display.// MC68HC11A8void LCDputchar(unsigned short letter){// letter is ASCII code    PORTC=letter;    PORTB=LCDdisable+LCDwrite+LCDdata;    PORTB=LCDenable+LCDwrite+LCDdata;  // E goes 0,1    PORTB=LCDdisable+LCDwrite+LCDdata; // E goes 1,0    LCDcycwait(80);} // 40 us waitvoid LCDputcsr(unsigned short command){    PORTC=command;    PORTB=LCDdisable+LCDwrite+LCDcsr;    PORTB=LCDenable+LCDwrite+LCDcsr;  // E goes 0,1    PORTB=LCDdisable+LCDwrite+LCDcsr; // E goes 1,0    LCDcycwait(80);} // 40 us waitvoid LCDclear(void){    LCDputcsr(0x01);   // Clear Display    LCDcycwait(3280);  // 1.64ms wait    LCDputcsr(0x02);   // Cursor to home    LCDcycwait(3280);} // 1.64ms waitvoid LCDinit(void){    DDRC=0xFF;    LCDputcsr(0x06);   // I/D=1 Increment, S=0 nodisplayshift    LCDputcsr(0x0C);   // D=1 displayon, // C=0 cursoroff, B=0 blinkoff    LCDputcsr(0x14);   // S/C=0 cursormove, R/L=0 shiftright    LCDputcsr(0x30);   // DL=1 8bit, N=0 1 line, F=0 5by7dots    LCDclear();}    // clear display// Program 8.27. C linked list and helper functions used to control the stepper motor.const struct State{   unsigned char Out;     /* Output for this state */    const struct State *Next[2]; /* Next state CW or CCW motion */};#typedef struct State StateType;#typedef StateType * StatePtr;unsigned char POS;  /* between 0 and 199 representing shaft angle */#define clockwise 0           /* Next index*/#define counterclockwise 1    /* Next index*/StateType fsm[4]={    {10,{&fsm[1],&fsm[3]}},    { 9,{&fsm[2],&fsm[0]}},    { 5,{&fsm[3],&fsm[1]}},    { 6,{&fsm[0],&fsm[2]}}};StatePtr Pt;  /* Current State */void CW(void){     Pt=Pt->Next[clockwise];    /* circulates around linked list */    PORTB=Pt->Out;              /* step motor */    if(POS++==200) POS=0;}       /* maintain shaft angle */ void CCW(void){    Pt=Pt->Next[counterclockwise]; /* circulates around linked list*/    PORTB=Pt->Out;                 /* step motor */    if(POS==0)POS=199;    else POS--; }               /* maintain shaft angle */void Init(void){    POS=0;    Pt=&fsm[0];}// Program 8.28. High-level C function to control the stepper motor.void SEEK(unsigned char New){ int CWsteps,i;     if((CWsteps=New-POS)<0)        CWsteps+=200;    if(CWsteps>100)        for(i=CWsteps;i<200;i++)           CCW();    else        for(i=0;i<CWsteps;i++)          CW(); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -