Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***********************************************************************
- ; ECE 362 - Experiment 8 - Fall 2012
- ;***********************************************************************
- ;***********************************************************************
- ;
- ; The objective of this experiment is to implement a reaction time assessment
- ; tool that measures, with millisecond accuracy, response to a visual
- ; stimulus -- here, both a YELLOW LED and the message "Go Team!" displayed on
- ; the LCD screen. The TIM module will be used to generate periodic
- ; interrupts every 1.000 ms, to serve as the time base for the reaction measurement.
- ; The RTI module will provide a periodic interrupt at a 2.048 ms rate to serve as
- ; a time base for sampling the pushbuttons and incrementing the variable "random"
- ; (used to provide a random delay for starting a reaction time test). The SPI
- ; will be used to shift out data to an 8-bit SIPO shift register. The shift
- ; register will perform the serial to parallel data conversion for the LCD.
- ;
- ; The following design kit resources will be used:
- ;
- ; - left LED (PT1): indicates test stopped (ready to start reaction time test)
- ; - right LED (PT0): indicates a reaction time test is in progress
- ; - left pushbutton (PAD7): starts reaction time test
- ; - right pushbutton (PAD6): stops reaction time test (turns off right LED
- ; and turns left LED back on, and displays test results)
- ; - LCD: displays status and result messages
- ; - Shift Register: performs SPI -> parallel conversion for LCD interface
- ;
- ; When the right pushbutton is pressed, the reaction time is displayed
- ; (refreshed in place) on the first line of the LCD as "RT = NNN ms"
- ; followed by an appropriate message on the second line
- ; e.g., 'Ready to start!' upon reset, 'Way to go HAH!!' if a really
- ; fast reaction time is recorded, etc.). The GREEN LED should be turned on
- ; for a reaction time less than 250 milliseconds and the RED LED should be
- ; turned on for a reaction time greater than 1 second.
- ;
- ;***********************************************************************/
- #include <hidef.h> /* common defines and macros */
- #include "derivative.h" /* derivative-specific definitions */
- #include <mc9s12c32.h>
- //Additional Defines
- #define RIGHT_BTN PTAD_PTAD6 //Right pushbutton
- #define LEFT_BTN PTAD_PTAD7 //Left pushbutton
- #define RIGHT_LED PTT_PTT0 //Right LED
- #define LEFT_LED PTT_PTT1 //Left LED
- #define LCD_RS PTT_PTT2 //
- #define LCD_RW PTT_PTT3 //
- #define LCD_CLK PTT_PTT4 //LCD clock
- #define RED_LED PTT_PTT5 //red led
- #define YLW_LED PTT_PTT6 //yellow led
- #define GRN_LED PTT_PTT7 //green led
- // All funtions after main should be initialiezed here
- char inchar(void);
- void outchar(unsigned char);
- void tdisp(int, int);
- void shiftout(unsigned char);
- void lcdwait(void);
- void send_byte(unsigned char);
- void send_i(unsigned char);
- void chgline(int);
- void print_c();
- void pmsglcd();
- void special(void);
- unsigned char charlookup(int);
- // Variable declarations
- int goteam = 0; // "go team" flag (used to start reaction timer)
- int leftpb = 0; // left pushbutton flag
- int rightpb = 0; // right pushbutton flag
- int prevrightpb = 0; // previous right pushbutton state
- int prevleftpb = 0; // previous left pushbutton state
- int runstop = 0; // run/stop flag
- int random= 0; // random variable (2 bytes)
- int react = 0; // reaction time (3 packed BCD digits)
- int tin = 0; // SCI transmit display buffer IN pointer
- int tout = 0; // SCI transmit display buffer OUT pointer
- int tsize = 0; // size of transmit buffer
- int tbuf = 0; // SCI transmit display buffer
- //int cutter = 0;
- int cutA = 0;
- int cutB = 0;
- int cutC = 0;
- int test = 0;
- // ASCII character definitions
- char CR = 0x0D;//Return
- //;LCD COMMUNICATION BIT MASKS
- //int RS = 0x04; //;RS pin mask (PTT[2])
- //int RW = 0x08; //;R/W pin mask (PTT[3])
- //int LCDCLK = 0x10; //;LCD EN/CLK pin mask (PTT[4])
- //;LCD INSTRUCTION CHARACTERS
- unsigned char LCDON = 0x0F; //;LCD initialization command
- unsigned char LCDCLR = 0x01; //;LCD clear display command
- unsigned char TWOLINE = 0x38; //;LCD 2-line enable command
- unsigned char CURMOV = 0xFE; //;LCD cursor move instruction
- unsigned char LINE1 = 0x80; //;LCD line 1 cursor position
- unsigned char LINE2 = 0xC0; //;LCD line 2 cursor position
- unsigned char line_offset = 0x00;
- int cutter = 0;
- //;LED BIT MASKS
- //int GREEN = 0x20;
- //int RED = 0x40;
- //int YELLOW = 0x80;
- /***********************************************************************
- Initializations
- ***********************************************************************/
- void initializations(void) {
- //; Set the PLL speed (bus clock = 24 MHz)
- CLKSEL = CLKSEL & 0x80; //; disengage PLL from system
- PLLCTL = PLLCTL | 0x40; //; turn on PLL
- SYNR = 0x02; //; set PLL multiplier
- REFDV = 0; //; set PLL divider
- while (!(CRGFLG & 0x08)){ }
- CLKSEL = CLKSEL | 0x80; //; engage PLL
- // Disable watchdog timer (COPCTL register)
- COPCTL = 0x40 ; //COP off; RTI and COP stopped in BDM-mode
- // Initialize asynchronous serial port (SCI) for 9600 baud, no interrupts
- SCIBDH = 0x00; //set baud rate to 9600
- SCIBDL = 0x9C; //24,000,000 / 16 / 156 = 9600 (approx)
- SCICR1 = 0x00; //$9C = 156
- SCICR2 = 0x0C; //initialize SCI for program-driven operation
- DDRB = 0x10; //set PB4 for output mode
- PORTB = 0x10; //assert DTR pin on COM port
- // Add additional port pin initializations here
- DDRT = 0xFF; //all digital pins as input
- ATDDIEN = 0xC0;
- PTT = 0;
- DDRM = 0xFF;
- // Initialize the SPI to 6.25 MHz
- //SPICR1_SPE = 1; //SPI enabled
- //SPICR1_SPTIE = 1;
- //SPICR1_LSBFE = 0; //data tranfered most significant bit first
- //SPICR1_MSTR = 1;
- SPICR1 = 0x52;
- //SPIBR_SPR = 0; //24MHz/4 = 6MHz
- //SPIBR_SPPR = 0x01;
- SPIBR = 0x1;
- // Initialize digital I/O port pins
- /* Initialize the LCD
- ; - pull LCDCLK high (idle)
- ; - pull R/W' low (write state)
- ; - turn on LCD (LCDON instruction)
- ; - enable two-line mode (TWOLINE instruction)
- ; - clear LCD (LCDCLR instruction)
- ; - wait for 2ms so that the LCD can wake up
- */
- LCD_CLK = 1; //lcd clk idle
- LCD_RW = 0; //LCD read/write
- special();
- //send_i(LCDON); //turn it on
- //lcdwait();
- //send_i(TWOLINE); //multiline
- //lcdwait();
- //send_i(LCDCLR); //clear it
- //lcdwait(); //wait for LCD to boot
- // Initialize RTI for 2.048 ms interrupt rate
- CRGINT = CRGINT | 0x80; //RTI enabled
- RTICTL = 0x1F; //RTI every 2.048ms
- /*
- Initialize TIM Ch 7 (TC7) for periodic interrupts every 1.000 ms
- ; Enable timer subsystem
- ; Set channel 7 for output compare
- ; Set appropriate pre-scale factor and enable counter reset after OC7
- ; Set up channel 7 to generate 1 ms interrupt rate
- ; Initially disable TIM Ch 7 interrupts
- */
- TSCR1_TEN = 1; //TIM enabled
- TIOS_IOS7 = 1; //ch7 set for output compare
- TSCR2_TCRE = 1; //TCNT reset when OC7 occurs
- TSCR2_PR2 = 1; //24MHz/16 = 1.5MHz
- TSCR2_PR1 = 0;
- TSCR2_PR0 = 0;
- TC7 = 1500; //interrupt every 1ms
- TIE_C7I = 0; //TIM ch7 interrupt disabled
- LEFT_LED = 1; //kk
- }
- /***********************************************************************
- Main
- ***********************************************************************/
- void main(void) {
- DisableInterrupts;
- initializations();
- EnableInterrupts;
- for(;;) {
- //loop
- /* write your code here */
- /*
- ; If the left pushbutton ("start reaction test") flag is set, then:
- ; - clear left pushbutton flag
- ; - set the "run/stop" flag
- ; - display message "Ready, Set..." on the first line of the LCD
- ; - turn off the left LED (PT1)
- ; - turn on the right LED (PT0)
- ; Endif
- */
- if ((LEFT_BTN == 0) && (leftpb == 1)) {
- //left pb has been pushed
- //Game is ready for input
- leftpb = 0; //toggle left pushbutton flag
- prevleftpb = 0; //toggle previous pushbutton state
- if (runstop == 0) {
- runstop = 1; //start running
- goteam = 0;
- LEFT_LED = 0; //kill left LED
- RIGHT_LED = 1; //on right LED
- tdisp(0,2); //disp for type READYING
- }
- }
- /*
- ; If the "run/stop" flag is set, then:
- ; - If the "goteam" flag is NOT set, then:
- ; + If "random" = $0000, then:
- ; - set the "goteam" flag
- ; - clear TCNT register (of TIM)
- ; - clear "react" variable (2 bytes)
- ; - enable TIM Ch7 interrupts
- ; - turn on YELLOW LED
- ; - display message "Go Team!" on the second line of the LCD
- ; + Endif
- ; - Endif
- ; Endif
- */
- if ((runstop == 1) && (goteam == 0)) {
- if (random == 0) {
- goteam = 1; //react timer start
- TCNT = 0; //clear TCNT
- react = 0; //reset react timer
- TIE_C7I = 1; //TIM ch7 interrupt enabled
- YLW_LED = 1;
- RED_LED = 0;
- GRN_LED = 0;
- tdisp(0,1); //disp for type GOING
- }
- }
- /*
- ; If the right pushbutton ("stop reaction test") flag is set, then:
- ; - clear right pushbutton flag
- ; - clear the "run/stop" flag
- ; - clear the "goteam" flag
- ; - turn off yellow LED
- ; - disable TIM Ch 7 interrupts
- ; - call "tdisp" to display reaction time message
- ; - turn off right LED (PT0)
- ; - turn on left LED (PT1)
- ; Endif
- */
- if ((RIGHT_BTN == 0) && (rightpb == 1) && (goteam == 1)) {
- rightpb = 0;
- prevrightpb = 0;
- runstop = 0;
- goteam = 0;
- //random = 0;
- YLW_LED = 0;
- TIE_C7I = 0; //TIM ch7 interrupt disabled
- tdisp(react, 0); //TYPE REACTING
- RIGHT_LED = 0; //right LED on
- LEFT_LED = 1; //left LED on
- react = 0;
- }
- /*
- ; If "react" = 999 (the maximum 3-digit BCD value), then:
- ; - clear the "run/stop" flag
- ; - turn off yellow LED, turn on red LED
- ; - disable TIM Ch 7 interrupts
- ; - display message "Time = 999 ms" on the first line of the LCD
- ; - display message "Too slow!" on the second line of the LCD
- ; - turn off right LED (PT0)
- ; - turn on left LED (PT1)
- ; Endif
- */
- if ((react == 999) && (runstop == 1) && (goteam == 1)) {
- runstop = 0;
- YLW_LED = 0;
- RED_LED = 1;
- TIE_C7I = 0; //TIM ch7 interrupt disabled
- tdisp(react, 0); //TYPE REACTING
- RIGHT_LED = 0;
- LEFT_LED = 1;
- react = 0;
- }
- _FEED_COP(); /* feeds the dog */
- } /* loop forever */
- /* please make sure that you never leave main */
- }
- /***********************************************************************
- ; RTI interrupt service routine: RTI_ISR
- ;
- ; Initialized for 2.048 ms interrupt rate
- ;
- ; Samples state of pushbuttons (PAD7 = left, PAD6 = right)
- ;
- ; If change in state from "high" to "low" detected, set pushbutton flag
- ; leftpb (for PAD7 H -> L), rghtpb (for PAD6 H -> L)
- ; Recall that pushbuttons are momentary contact closures to ground
- ;
- ; Also, increments 2-byte variable "random" each time interrupt occurs
- ; NOTE: Will need to truncate "random" to 12-bits to get a reasonable delay
- ;***********************************************************************/
- interrupt 7 void RTI_ISR(void)
- {
- // set CRGFLG bit
- CRGFLG = CRGFLG | 0x80;
- if (goteam == 0) {
- random++;
- random = random % 800;
- } else if (goteam == 1) {
- if (random != 0) {
- random--;
- }
- }
- if ((RIGHT_BTN == 0) && (prevrightpb == 0)) {//pushed | previously not pushed
- rightpb = 1; //pushed
- prevrightpb = 1; //previously pushed
- }
- if ((LEFT_BTN == 0) && (prevleftpb == 0)) {//pushed | previously not pushed
- leftpb = 1; //pushed
- prevleftpb = 1; //previously pushed
- }
- }
- /***********************************************************************
- ; TIM interrupt service routine
- ;
- ; Initialized for 1.00 ms interrupt rate
- ;
- ; Increment (3-digit) variable "react" by one
- ;***********************************************************************/
- interrupt 15 void TIM_ISR(void)
- {
- // set TFLG1 bit
- TFLG1 = TFLG1 | 0x80;
- react++;
- }
- void special(){
- LCD_RS = 0;
- while (SPISR_SPTEF != 1) {
- //aaaaaaaaaaaaa
- }
- if (SPISR_SPTEF == 1) {
- SPIDR = LCDON;
- //SPISR_SPTEF = 0;
- asm { //it's nop time
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- }
- LCD_CLK = 1;
- lcdwait();
- LCD_CLK = 0;
- LCD_RS = 1;
- LCD_RS = 0;
- while (SPISR_SPTEF != 1) {
- //aaaaaaaaaaaaa
- }
- if (SPISR_SPTEF == 1) {
- SPIDR = TWOLINE;
- //SPISR_SPTEF = 0;
- asm { //it's nop time
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- }
- LCD_CLK = 1;
- lcdwait();
- LCD_CLK = 0;
- LCD_RS = 1;
- LCD_RS = 0;
- while (SPISR_SPTEF != 1) {
- //aaaaaaaaaaaaa
- }
- if (SPISR_SPTEF == 1) {
- SPIDR = LCDCLR;
- // SPISR_SPTEF = 0;
- asm { //it's nop time
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- }
- LCD_CLK = 1;
- lcdwait();
- LCD_CLK = 0;
- LCD_RS = 1;
- }
- /***********************************************************************
- ; tdisp: Display "RT = NNN ms" on the first line of the LCD and display
- ; an appropriate message on the second line depending on the
- ; speed of the reaction. This routine should use the
- ; "react" variable to determine which number and which message
- ; to display. pmsglcd will be useful for doing this.
- ; Convert react to ASCII before printing.
- ;
- ; Also, this routine should set the green LED if the reaction
- ; time was less than 250 ms.
- ;
- ; NOTE: The messages should be less than 16 characters since
- ; the LCD is a 2x16 character LCD.
- ;***********************************************************************/
- void tdisp(int val, int type)
- {
- send_i(LCDCLR);
- if (type == 0) { //TYPE REACTING
- //val is react
- cutC = val % 10;
- val = val / 10;
- cutB = val % 10;
- val = val / 10;
- cutA = val % 10;
- //print vals
- chgline(1);
- send_byte(charlookup(cutA));
- chgline(1);
- send_byte(charlookup(cutB));
- chgline(1);
- send_byte(charlookup(cutC));
- chgline(1);
- send_byte(0x6D); //m
- chgline(1);
- send_byte(0x73); //s
- chgline(1);
- send_byte(0x73); //m
- line_offset = 0x00;
- if (react <= 250) {
- //print happy things
- chgline(2);
- send_byte(0xCA); //ha
- chgline(2);
- send_byte(0xD4); //ya
- chgline(2);
- send_byte(0xB2); //i
- chgline(2);
- send_byte(0x21); //!
- /*
- send_byte(0x46); //F
- chgline(2);
- send_byte(0x61); //a
- chgline(2);
- send_byte(0x73); //s
- chgline(2);
- send_byte(0x74); //t
- */
- line_offset = 0x00;
- RED_LED = 0;
- YLW_LED = 0;
- GRN_LED = 1;
- } else if (react == 999) {
- chgline(2);
- send_byte(0xD2); //me
- chgline(2);
- send_byte(0xDC); //wo
- chgline(2);
- send_byte(0xBB); //sa
- chgline(2);
- send_byte(0xCF); //ma
- chgline(2);
- send_byte(0xBD); //su
- chgline(2);
- send_byte(0x21); //!
- /*
- send_byte(0x57); //W
- chgline(2);
- send_byte(0x61); //a
- chgline(2);
- send_byte(0x6B); //k
- chgline(2);
- send_byte(0x65); //e
- */
- line_offset = 0x00;
- } else {
- //print neutral things
- chgline(2);
- send_byte(0x4D); //M
- chgline(2);
- send_byte(0x65); //e
- chgline(2);
- send_byte(0x68); //h
- line_offset = 0x00;
- }
- } else if (type == 1) { //TYPE GOING
- chgline(2);
- send_byte(0xB2); //i
- chgline(2);
- send_byte(0xB8); //ku
- chgline(2);
- send_byte(0x21); //!
- /*
- send_byte(0x47); //G
- chgline(2);
- send_byte(0x6F); //o
- chgline(2);
- send_byte(0x21); //!
- //chgline(0);
- */
- line_offset = 0x00;
- } else if (type == 2) { //TYPE READYING
- chgline(1);
- send_byte(0x52); //R
- chgline(1);
- send_byte(0x65); //e
- chgline(1);
- send_byte(0x61); //a
- chgline(1);
- send_byte(0x64); //d
- chgline(1);
- send_byte(0x79); //y
- chgline(1);
- send_byte(0x3F); //?
- line_offset = 0x00;
- }
- return;
- }
- /***********************************************************************
- ; look up ascii vals
- ;***********************************************************************/
- unsigned char charlookup(int anyvar) {
- switch(anyvar) {
- case(0):
- return(0x30); //0000 0011
- case(1):
- return(0x31); //0001 0011
- case(2):
- return(0x32); //0010 0011
- case(3):
- return(0x33); //0011 0011
- case(4):
- return(0x34); //0100 0011
- case(5):
- return(0x35); //0101 0011
- case(6):
- return(0x36); //0110 0011
- case(7):
- return(0x37); //0111 0011
- case(8):
- return(0x38); //1000 0011
- case(9):
- return(0x39); //1001 0011
- }
- }
- /***********************************************************************
- ; shiftout: Transmits the contents of register A to external shift
- ; register using the SPI. It should shift MSB first.
- ;
- ; MISO = PM[4]
- ; SCK = PM[5]
- ;***********************************************************************/
- void shiftout(unsigned char output)
- {
- while (SPISR_SPTEF != 1) {
- //aaaaaaaaaaaaa
- }
- if (SPISR_SPTEF == 1) {
- SPIDR = output;
- asm { //it's nop time
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- }
- //read the SPTEF bit, continue if bit is 1
- //write data to SPI data register
- //wait for 30 cycles for SPI data to shift out
- }
- /***********************************************************************
- ; lcdwait: Delay for 2 ms
- ;***********************************************************************/
- void lcdwait()
- {
- int i = 0;
- for (i = 0; i<=2500;i++) {
- asm {//+10cy for 25000cy loop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- }
- }
- }
- /***********************************************************************
- ; send_byte: writes contents of register A to the LCD
- ;***********************************************************************/
- void send_byte(unsigned char character)
- {
- //Shift out character
- //Pulse LCD clock line low->high
- //Wait 2 ms for LCD to process data
- shiftout(character);
- LCD_CLK = 0;
- LCD_CLK = 1;
- lcdwait();
- }
- /***********************************************************************
- ; send_i: Sends instruction passed in register A to LCD
- ;***********************************************************************/
- void send_i(unsigned char instruction)
- {
- //Set the register select line low (instruction data)
- LCD_RS = 0;
- //Send byte
- send_byte(instruction);
- LCD_RS = 1;
- }
- /***********************************************************************
- ; chgline: Move LCD cursor to the cursor position passed in A
- ; NOTE: Cursor positions are encoded in the LINE1/LINE2 variables
- ;***********************************************************************/
- void chgline(int linetype)
- {
- if (linetype == 1) { //first line
- send_i(LINE1 + line_offset);
- } else if (linetype == 2) { // second line
- send_i(LINE2 + line_offset);
- }
- line_offset = line_offset + 0x01;
- }
- /***********************************************************************
- ; print_c: Print character passed in register A on LCD
- ; -> A sub of pmsglcd
- ;***********************************************************************/
- void print_c()
- {
- }
- /***********************************************************************
- ; pmsglcd: pmsg, now for the LCD! Expect characters to be passed
- ; by call. Registers should return unmodified. Should use
- ; print_c to print characters.
- ;***********************************************************************/
- void pmsglcd()
- {
- }
- /***********************************************************************
- ; Character I/O Library Routines for 9S12C32
- ;***********************************************************************
- ; Name: inchar
- ; Description: inputs ASCII character from SCI serial port and returns it
- ; Example: char ch1 = inchar();
- ;***********************************************************************/
- char inchar(void) {
- /* receives character from the terminal channel */
- while (!(SCISR1 & 0x20)); /* wait for input */
- return SCIDRL;
- }
- /***********************************************************************
- ; Name: outchar
- ; Description: outputs ASCII character passed in outchar()
- ; to the SCI serial port
- ; Example: outchar('x');
- ;***********************************************************************/
- void outchar(unsigned char ch) {
- /* sends a character to the terminal channel */
- while (!(SCISR1 & 0x80)); /* wait for output buffer empty */
- SCIDRL = ch;
- }
Advertisement
Add Comment
Please, Sign In to add comment