// Motorola 68HC12 Test Program TEST.C // Lee Rosenberg // January 13, 1999 // // This a series of test routines to check the functionality of the Motorola // HC12 and to determine if errors that are reported by the TAs and students. // The program will allow for differentiation between errors that are due to // hardware faults and those that result form errors in the students code. // The program tests the Ports, Timer Module, A/D Converter and Key Wakeups. // This is not fully comprehensive but should provide verifiation of most major // faults. // // This code was written and tested using Introl C 4.0. // #includes #include #include #include // function prototypes void keywakeup(void); void adconverter(void); void timer(void); void portio(void); // Global Interrupts int flag; // interrupt service routine declarations __mod2__ void RTIInt(); __mod2__ void AtoDInt(); __mod2__ void IRQInt(); __mod2__ void PortHKeyInt(); __mod2__ void PortJKeyInt(); void __main () { int choice; while(1) { DB12->printf("1 = Port I/O\n\r"); // Menu of choices DB12->printf("2 = Timer\n\r"); DB12->printf("3 = A/D converter\n\r"); DB12->printf("4 = Key wake up\n\n\r"); choice=DB12->getchar(); // select which option to run if (choice == 0x31) portio(); else if(choice == 0x32) timer(); else if(choice == 0x33) adconverter(); else if(choice == 0x34) keywakeup(); else DB12->printf("That is not a valid choice\n\r"); // inform the user how bright he is } } void portio(void) { // This function tests the port I/O operations int port; int direction; DB12->printf("Select the direction of the port being checked\n\r"); DB12->printf("Enter 1 for output and 2 for input\n\r"); direction=DB12->getchar(); if (direction == 0x31) // Check output { _H12DDRG=0xFF; // Set ports for output _H12DDRH=0xFF; _H12DDRJ=0xFF; _H12DDRS=0xFF; _H12DDRTT=0xFF; _H12PORTG=0xFF; // Output all ones _H12PORTH=0xFF; _H12PORTJ=0xFF; _H12PORTS=0xFF; _H12PORTT=0xFF; } else if(direction == 0x32) // Check input { DB12->printf("1 = Port G\n\r"); DB12->printf("2 = Port H\n\r"); DB12->printf("3 = Port J\n\r"); DB12->printf("4 = Port S\n\r"); DB12->printf("5 = Port T\n\r"); DB12->printf("0 = exit\n\r"); port=DB12->getchar(); while(port != 0x30) { // select the port to read and display it _H12DDRG=0x00; _H12DDRH=0x00; _H12DDRJ=0x00; _H12DDRS=0x00; _H12DDRTT=0x00; if (port==0x31) DB12->out2hex(_H12PORTG); else if(port==0x32) DB12->out2hex(_H12PORTH); else if(port==0x33) DB12->out2hex(_H12PORTJ); else if(port==0x34) DB12->out2hex(_H12PORTS); else if(port==0x35) DB12->out2hex(_H12PORTT); else DB12->printf("That is not a valid choice\n\r"); // inform the user how bright he is port=DB12->getchar(); } } } void timer(void) { // This module tests the timer module of the HC12. // The IRQ is used to exit this module // Set up interrupt vectors DB12->SetUserVector(RTI, RTIInt); DB12->SetUserVector(IRQ, IRQInt); DB12->printf("Use the IRQ to exit"); _H12RTICTL=0x87; // Set up RTI _H12INTCR=0xC0; // IRQ falling edge triggered // Timer output compare _H12TIOS=0xFF; // Select Timer Output Compare _H12TMSK1=0x00; // no hardware interrupts _H12TCTL1=0x55; // Set output pins to toggle _H12TCTL2=0x55; _H12TC0=0x0000; // Trigger timer at TCNT=0000 _H12TC1=0x0000; _H12TC2=0x0000; _H12TC3=0x0000; _H12TC4=0x0000; _H12TC5=0x0000; _H12TC6=0x0000; _H12TC7=0x0000; _H12TSCR=0x80; // turn on the timer module flag=0; while(1) { if(flag==1) // when the IRQ is triggered { _H12TSCR=0x00; // turn off the timer _H12RTICTL=0x00; // Turn off the RTI return; } } } void adconverter(void) { // This module tests the A/D converter on the HC12 // The IRQ is used to exit. _H12ADTCTL2=0x80; // turn on ATD and off the interrupt _H12ADTCTL3=0x00; // don't stop at breakpoints _H12ADTCTL4=0x43; DB12->printf("Use the IRQ to exit\n\r"); DB12->printf("AD0 AD1 AD2 AD3 AD4 AD5 AD6 AD7\n\r"); _H12INTCR=0xC0; // IRQ falling edge triggered flag=0; while(1) { if(flag==1) // if the IRQ is triggered exit return; _H12ADTCTL5=0x50; // check AD port while(!(_H12ADTSTAT & 0x8000)); // when conversion is complete.... DB12->out2hex(_H12ADR0H); // Display the values to the screen DB12->printf(" "); DB12->out2hex(_H12ADR1H); DB12->printf(" "); DB12->out2hex(_H12ADR2H); DB12->printf(" "); DB12->out2hex(_H12ADR3H); DB12->printf(" "); DB12->out2hex(_H12ADR4H); DB12->printf(" "); DB12->out2hex(_H12ADR5H); DB12->printf(" "); DB12->out2hex(_H12ADR6H); DB12->printf(" "); DB12->out2hex(_H12ADR7H); DB12->printf("\r"); } } void keywakeup(void) { // This module tests the Key Wakeup Interrupts. // q is used to exit. int key; key=0; //Set up the interrupt vectors DB12->SetUserVector(PortHKey, PortHKeyInt); DB12->SetUserVector(PortJKey, PortJKeyInt); DB12->printf("type q to exit"); _H12KWIEH=0x0F; // setup the keypad for the low bits _H12KPOLJ=0x0F; // rising edge _H12PUPSJ=0x00; // pulldown _H12PULEJ=0x0F; // pulldown enabled _H12KWIEJ=0x0F; // enable interrupt while(1) { key=DB12->getchar(); // when q is entered exit if(key==0x71) { _H12KWIEJ=0x00; // Turn off the interrupt. _H12KWIEH=0x00; return; } } } // RTI Interrupt routine __mod2__ void RTIInt() { DB12->printf("RTI triggered\n\r"); // display message when triggered _H12RTIFLG=0x80; // Clear flag } // IRQ interrupt routine __mod2__ void IRQInt() { flag=1; // Set flag for use in main program } // Port H Key Wakeup Interrupt routine __mod2__ void PortHKeyInt() { DB12->printf("Port H: "); // Display value on Port H DB12->out2hex(_H12KWIFH); DB12->printf("\n\r"); _H12KWIFH=_H12KWIFH; // Clear Flag } //Port J Key Wakeup Intteruptm routine __mod2__ void PortJKeyInt() { DB12->printf("Port J: "); // Display Value on Port J DB12->out2hex(_H12KWIFJ); DB12->printf("\n\r"); _H12KWIFJ=_H12KWIFJ; // Clear Flag }