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

📄 chap4.c

📁 Motorola 6812芯片开发的接口程序。
💻 C
字号:
// Chapter 4 6812 C programs// Jonathan W. Valvano// This software accompanies the book,// Embedded Microcomputer Systems: Real Time Interfacing// published by Brooks Cole, 1999// Program 4.3. This C function is nonreentrant because of the read-modify-write access to a global. unsigned int Money;  /* bank balance implemented as a global *//* add 100 dollars */void more(void){	Money += 100;}// Program 4.5. This C function is nonreentrant because of the write-read access to a global. int temp;  /* global temporary *//* calculate x+2*d */int mac(int x, int d){	temp = x+2*d;    /* write to a global variable */       return (temp);}  /* read from global */// Program 4.7. This C function is nonreentrant because of the multi-step write access to a global. int info[2];  /* 32-bit global */void set(int x, int y){    info[0]=x;    info[1]=y;}// Program 4.11. This C function is reentrant because it disables interrupts during the critical section. int Empty;   /* -1 means empty, 0 means it contains something */int Message; /*  data to be communicated */int SEND(int data){ int OK;char SaveSP;   asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */   OK=0;          /* Assume it is not OK */   if(Empty){       Message=data;       Empty=0;  /*  signify it is now contains a message*/       OK=-1;}   /* Successfull */   asm(" ldaa %SaveSP\n tap");  /* end critical section */    return(OK);}// Program 4.14. Two pointer implementation of a FIFO. #define FifoSize 10    /* Number of 8 bit data in the Fifo less one */char *PutPt;    /* Pointer of where to put next */char *GetPt;    /* Pointer of where to get next               /* FIFO is empty if PutPt=GetPt */               /* FIFO is full  if PutPt+1=GetPt (with wrap) */char Fifo[FifoSize];     /* The statically allocated fifo data */void InitFifo(void) { char SaveSP; asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */ PutPt=GetPt=&Fifo[0];  /* Empty when PutPt=GetPt */ asm(" ldaa %SaveSP\n tap");      /* end critical section */}int PutFifo (char data) { char *Ppt; /* Temporary put pointer */char SaveSP;   asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */   Ppt=PutPt;          /* Copy of put pointer */   *(Ppt++)=data;      /* Try to put data into fifo */   if (Ppt == &Fifo[FifoSize]) Ppt = &Fifo[0];  /* Wrap */   if (Ppt == GetPt ) {      asm(" ldaa %SaveSP\n tap"); /* end critical section */      return(0);}    /* Failed, fifo was full */    else{       PutPt=Ppt;      asm(" ldaa %SaveSP\n tap");  /* end critical section */      return(-1);    /* Successful */      }}int GetFifo (char *datapt) { char SaveSP;   if (PutPt == GetPt ) {        return(0);}    /* Empty if PutPt=GetPt */   else{       asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical */       *datapt=*(GetPt++);       if (GetPt == &Fifo[FifoSize]) GetPt = &Fifo[0];       asm(" ldaa %SaveSP\n tap");  /* end critical section */       return(-1); }}// Program 4.18. C language routines to implement a two pointer with counter FIFO. /* Pointer,counter implementation of the FIFO */#define FifoSize 10    /* Number of 8 bit data in the Fifo */char *PutPt;    /* Pointer of where to put next */char *GetPt;    /* Pointer of where to get next */unsigned char Size;  /* Number of elements currently in the FIFO */               /* FIFO is empty if Size=0 */               /* FIFO is full  if Size=FifoSize */char Fifo[FifoSize];     /* The statically allocated fifo data */void InitFifo(void) { char SaveSP;  asm(" tpa\n staa %SaveSP\n sei");   /* make atomic, entering critical*/ PutPt=GetPt=&Fifo[0];   /* Empty when Size==0 */ Size=0; asm(" ldaa %SaveSP\n tap");  /* end critical section */}int PutFifo (char data) { char SaveSP;   if (Size == FifoSize ) {      return(0);}    /* Failed, fifo was full */    else{      asm(" tpa\n staa %SaveSP\n sei");   /* make atomic, entering critical*/      Size++;      *(PutPt++)=data;    /* put data into fifo */      if (PutPt == &Fifo[FifoSize]) PutPt = &Fifo[0];  /* Wrap */      asm(" ldaa %SaveSP\n tap");  /* end critical section */      return(-1);    /* Successful */      }}int GetFifo (char *datapt) { char SaveSP;   if (Size == 0 ){       return(0);}         /* Empty if Size=0 */   else{      asm(" tpa\n staa %SaveSP\n sei");   /* make atomic, entering critical*/      *datapt=*(GetPt++); Size--;      if (GetPt == &Fifo[FifoSize]) GetPt = &Fifo[0];      asm(" ldaa %SaveSP\n tap");  /* end critical section */      return(-1); }}// Program 4.22. C implementation of a two index with counter FIFO. /* Index,counter implementation of the FIFO */#define FifoSize 10    /* Number of 8 bit data in the Fifo */unsigned char PutI;    /* Index of where to put next */unsigned char GetI;    /* Index of where to get next */unsigned char Size;    /* Number of elements currently in the FIFO */               /* FIFO is empty if Size=0 */               /* FIFO is full  if Size=FifoSize */char Fifo[FifoSize];     /* The statically allocated fifo data */void InitFifo(void) {char SaveSP;  asm(" tpa\n staa %SaveSP\n sei");   /* make atomic, entering critical*/  PutI=GetI=Size=0;      /* Empty when Size==0 */  asm(" ldaa %SaveSP\n tap");  /* end critical section */}int PutFifo (char data) { char SaveSP;   if (Size == FifoSize )       return(0);     /* Failed, fifo was full */    else{       asm(" tpa\n staa %SaveSP\n sei");   /* make atomic, entering critical*/      Size++;      Fifo[PutI++]=data;      /*  put data into fifo */      if (PutI == FifoSize) PutI = 0;  /* Wrap */      asm(" ldaa %SaveSP\n tap");  /* end critical section */      return(-1);    /* Successful */      }}int GetFifo (char *datapt) { char SaveSP;   if (Size == 0 )         return(0);     /* Empty if Size=0 */   else{        asm(" tpa\n staa %SaveSP\n sei"); /* make atomic, entering critical*/        *datapt=Fifo[GetI++]; Size--;        if (GetI == FifoSize) GetI = 0;        asm(" ldaa %SaveSP\n tap");  /* end critical section */        return(-1); }}// Program 4.26. ICC12 C code to set interrupt vectors for the 6812. extern void _start();	/* entry point in crt12.s */extern void SCIhandler();extern void TC4handler();extern void TOFhandler();#define DUMMY_ENTRY	(void (*)())0xF000#pragma abs_address:0xffcevoid (*interrupt_vectors[])() = {	DUMMY_ENTRY,	/* ffce 812 KeyWakeUpH */	DUMMY_ENTRY,	/* ffd0 912 BDLC, 812 KeyWakeUpJ */	DUMMY_ENTRY,	/* ffd2 ATD */	DUMMY_ENTRY,	/* ffd4 812 SCI1 */	SCIhandler,	/* ffd6 SCI, 812 SCI0 */	DUMMY_ENTRY,	/* ffd8 SPI */	DUMMY_ENTRY,	/* ffda PAIE */	DUMMY_ENTRY,	/* ffdc PAO */	TOFhandler,	/* ffde TOF */	DUMMY_ENTRY,	/* ffe0 TC7 */	DUMMY_ENTRY,	/* ffe2 TC6 */	DUMMY_ENTRY,	/* ffe4 TC5 */	TC4handler,	/* ffe6 TC4 */	DUMMY_ENTRY,	/* ffe8 TC3 */	DUMMY_ENTRY,	/* ffea TC2 */	DUMMY_ENTRY,	/* ffec TC1 */	DUMMY_ENTRY,	/* ffee TC0 */	DUMMY_ENTRY,	/* fff0 RTI  */	DUMMY_ENTRY,	/* fff2 IRQ, 812 KeyWakeUpD*/	DUMMY_ENTRY,	/* fff4 XIRQ  */	DUMMY_ENTRY,	/* fff6 SWI   */	DUMMY_ENTRY,	/* fff8 ILLOP */	DUMMY_ENTRY,	/* fffa COP   */	DUMMY_ENTRY,	/* fffc CLM   */	_start	       /* fffe RESET, entry point into ICC12 */	};#pragma end_abs_address// Program 4.30. Interrupting keyboard software. // MC68HC812A4// PJ6-PJ0 inputs = keyboard DATA// PJ7=STROBE interrupt on risevoid Init(void){ asm(" sei");    DDRJ=0x00;   // PJ6-0 DATA    KPOLJ=0x80;  // rise on PJ7    KWIEJ=0x80;  // arm PJ7    KWIFJ=0x80;  // clear flag7    InitFifo();asm(" cli");}#pragma interrupt_handler ExtHan()void ExtHan(void){     if((KWIFJ&0x80)==0)asm(" swi");    KWIFJ=0x80;  // clear flag    PutFifo(PORTJ&0x7F);}// Program 4.34. C language software interrupt for the printer. // MC68HC812A4// PH6-PH0 outputs = printer DATA// PJ1=READY interrupt on rise// PJ0=START pulse outunsigned char OK;   // 0=busy, 1=doneunsigned char Line[20]; //ASCII dataunsigned char *Pt;  // pointer to linevoid Fill(unsigned char *p){   Pt=&Line[0];      while((*Pt++)=(*p++)); // copy   Pt=&Line[0];   // initialize pointer   OK=0;}unsigned char Get(void){   return(*Pt++);}void Out(unsigned char data){   PORTJ=0;    // START=0   PORTH=data; // write DATA   PORTJ=1;}   // START=1void Init(unsigned char *thePt){ asm(" sei");   // make atomic   Fill(thePt); // copy data into global   DDRH=0xFF;  // PH6-0 output DATA   DDRJ=0x01;  // PJ0=START output   KPOLJ=0x02; // rise on PJ1   KWIEJ=0x02; // arm PJ1   KWIFJ=0x02; // clear flag1   Out(Get()); // start firstasm(" cli");}#pragma interrupt_handler ExtHan()void ExtHan(void){     if((KWIFJ&0x02)==0)asm(" swi");    KWIFJ=0x02;  // clear flag1    if(data=Get())       Out(data);    // start next    else{       KWIEJ=0x00;   // disarm       OK=1;}}       // line complete // Program 4.36. C language software for the XIRQ interrupt. /* Power System interface    XIRQ requested on a rise of TooLow   PB0, negative logic pulse, will acknowledge XIRQ   PB1=1 will activate backup power */#pragma interrupt_handler PowerLow()void PowerLow(void){ PORTB=2; PORTB=3; }  /* Ack, turn on backup power */void Ritual(void){      DDRB=0xFF;        // Port B outputs (6812 only)      PORTB=0; PORTB=1; // Make XIRQ=1 asm(" ldaa #0x10\n"    "  tap");}// Program 4.42. C language implementation of interrupt polling on the 6812 using linked lists. const struct	Node{	unsigned char Mask;           /* And Mask */	void (*Handler)(void);        /* Handler for this task */              	const struct Node *NextPt;          /* Link to Next Node */};unsigned char Counter2,Counter1,Counter0;void PJ2Han(void){    // regular functions that return (rts) when done    KWIFJ=0x04;       // acknowledge    Counter2++;}void PJ1Han(void){    // regular functions that return (rts) when done    KWIFJ=0x02;       // acknowledge    Counter1++;}void PJ0Han(void){    // regular functions that return (rts) when done    KWIFJ=0x01;       // acknowledge    Counter0++;}typedef const struct Node NodeType;typedef NodeType * NodePtr;NodeType sys[3]={    {0x04, PJ2Han, &sys[1]},    {0x02, PJ1Han, &sys[2]},    {0x01, PJ0Han,   0    } };#pragma interrupt_handler IRQHan()void IRQHan(void){ NodePtr Pt; unsigned char Status; Pt=&sys[0]; while(Pt){		// executes device handlers for all requests    if(KWIFJ&(Pt->Mask)){        (*Pt->Handler)();}     /* Execute handler */    Pt=Pt->NextPt; } }  // returns after all devices have been polledvoid main(void){     while(1);} // Program 4.44. C language implementation of round robin polling on the 6812. NodeType sys[3]={    {0x04, PJ2Han, &sys[1]},    {0x02, PJ1Han, &sys[2]},    {0x01, PJ0Han, &sys[0]} };#pragma interrupt_handler IRQHan()NodePtr Pt=&sys[0];  // points to the one that got polled first at last interruptvoid IRQHan(void){ unsigned char Counter,Status; Counter=3;        // quit after three devices checked Pt=Pt->NextPt;    // rotates ABC BCA CAB polling orders while(Counter--){    if(KWIFJ&(Pt->Mask)){        (*Pt->Handler)();}     /* Execute handler */    Pt=Pt->NextPt; } }  // returns after all devices have been polled// Program 4.49. 6812 C language implementation of a periodic interrupt using real time interrupt. // Real Time Interrupt example 4.14.2 unsigned int Time;#pragma interrupt_handler RTIHan()void RTIHan(void){    if(RTIFLG!=0x80) asm(" swi"); //  Illegal interrupt    RTIFLG=0x80;      // Acknowledge by clearing RTIF    Time++;}void Ritual(void){     asm(" sei");    // Make ritual atomic      RTICTL=0x86;    // Arm, Set RTR to 6, 30.517Hz       Time=0;         // Initialize global data structures      asm(" cli");}void main(void){ unsigned int t;     Ritual();     for(t=0;t<10;) if (Time>=61*t){          printf("t= %d seconds\n", t);          t++;}     asm(" sei"); }// Program 4.51. 6812 C language implementation of a periodic interrupt using timer overflow. // TOF Interrupt example unsigned int Time;#pragma interrupt_handler TOFHan()void TOFHan(void){    if(TFLG2!=0x80) asm(" swi"); //  Illegal interrupt    TFLG2=0x80;       // Acknowledge by clearing TOF    Time++; }void Ritual(void){     asm(" sei");    // Make ritual atomic      TMSK2=0xB2 ;    // Arm, Set PR to 010, 30.517Hz       TSCR=0x80;      // enable counter     Time=0;         // Initialize global data structures      asm(" cli");}

⌨️ 快捷键说明

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