CodeCodeCode

ECE362 LAB7

Oct 31st, 2012
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.45 KB | None | 0 0
  1. /********************************************************************************
  2. * ECE 362 - Experiment 7 - Fall 2012                        
  3. *********************************************************************************
  4. * The objective of this lab is to implement a simple digital volt meter (DVM).  
  5. * Using the RTI as a sampling time base, this turn-key application program will
  6. * sample analog input channels 0 and 1 periodically (every 0.5 second),
  7. * convert the values read into 3-digit decimal numbers (N.NN), and update
  8. * the values displayed on the terminal screen, as follows:
  9. *
  10. *       Ch 0 = N.NN v   Ch 1 = N.NN v
  11. *
  12. * The right pushbutton will be used to start the DVM, and the left pushbutton
  13. * will be used to stop the DVM.  The left LED will be illuminated when the
  14. * DVM is stopped, and the right LED will be illuminated when the DVM is running.
  15. *
  16. * In addition to the text display of the values on the terminal screen, a set
  17. * of three LEDs (YELLOW, GREEN, and RED) will be used to indicate the approximate
  18. * range of the voltage input on each channel (0 and 1).  The YELLOW LED for a given
  19. * channel should be illuminated if the input voltage on that channel is greater
  20. * than THRESH1 but less than THRESH2.  The GREEN LED should be illuminated if the
  21. * input voltage is greater than or equal to THRESH2 but less than THRESH3. The RED
  22. * LED should be illuminated if the input voltage is greater than or equal to
  23. * THRESH3. The external LEDs will be interfaced to pins on Port T.
  24. *********************************************************************************/
  25. #include <hidef.h>       /* common defines and macros */
  26. #include "derivative.h"  /* derivative-specific definitions */
  27. #include <mc9s12c32.h>   /* microcontroller pin & register definitions */
  28.  
  29. // custom re-defines
  30. #define RIGHTPB_PIN PTAD_PTAD6  //easy-to-read pushbutton right
  31. #define LEFTPB_PIN PTAD_PTAD7   //easy-to-read pushbutton left
  32.  
  33. // function prototypes (info in comment headers)
  34. char inchar(void);
  35. void outchar(char x);
  36. void getATD(void);
  37. void vdisp(void);
  38. void ledbar0(void);
  39. void ledbar1(void);
  40. char charlookup(int);
  41.  
  42. // ASCII character definitions                  
  43. char CR = 0x0D; // carriage return
  44. char LF = 0x0A; // linefeed
  45. // THRESHOLD specifications (8-bit, unsigned)                                                  
  46. int THRESH1  =   0x04; // 0.08v
  47. int THRESH2  =   0x40; // 1.28v
  48. int THRESH3  =   0xC0; // 3,84v
  49.                                                        
  50. //  generic variable declarations                                                  
  51. int halfsec = 0;    // half second flag
  52.                     // 0 -> 0.5sec has not passed
  53.                     // 1 -> 0.5sec has passed
  54. int leftpb = 0;     // left pushbutton flag
  55.                     // 0 -> left pushbutton not pushed
  56.                     // 1 -> left pushbutton pushed
  57. int rightpb = 0;    // right pushbutton flag
  58.                     // 0 -> right pushbutton not pushed
  59.                     // 1 -> right pushbutton pushed
  60. int prevpbl = 0;    // previous left pushbutton state flag
  61.                     // 0 -> left pushbutton previously not pushed
  62.                     // 1 -> left pushbutton previously pushed
  63. int prevpbr = 0;    // previous right pushbutton state flag
  64.                     // 0 -> right pushbutton previously not pushed
  65.                     // 1 -> right pushbutton previously pushed
  66. int runstop = 0;    // run/stop flag
  67.                     // 0 -> programming is halted
  68.                     // 1 -> program is running                        
  69. int rticnt = 0;     // # of interrupts accumulated
  70. int result_ch0 = 0; // result of channel 0 sampling
  71. int result_ch1 = 0; // result of channel 1 sampling
  72. int convregA = 0;   // value A in voltage conversion of form A.BCv
  73. int convregB = 0;   // value B in voltage conversion of form A.BCv
  74. int convregC = 0;   // value C in voltage conversion of form A.BCv
  75. int cool = 0;      
  76.                
  77. /***********************************************************************
  78. * Initializations
  79. ***********************************************************************/
  80. void  initializations(void) {
  81.  
  82. // Set the PLL speed (bus clock = 24 MHz)
  83.   CLKSEL = CLKSEL & 0x80; // disengage PLL from system
  84.   PLLCTL = PLLCTL | 0x40; // turn on PLL
  85.   SYNR = 0x02;            // set PLL multiplier
  86.   REFDV = 0;              // set PLL divider
  87.   while (!(CRGFLG & 0x08)){  }
  88.   CLKSEL = CLKSEL | 0x80; // engage PLL
  89.  
  90. // Disable watchdog timer (COPCTL register)
  91.   COPCTL = 0x40; //COP off; RTI and COP stopped in BDM-mode
  92.  
  93. // Initialize asynchronous serial port (SCI) for 9600 baud, no interrupts
  94.   SCIBDH =  0x00; //set baud rate to 9600
  95.   SCIBDL =  0x9C; //24,000,000 / 16 / 156 = 9600 (approx)  
  96.   SCICR1 =  0x00; //$9C = 156
  97.   SCICR2 =  0x0C; //initialize SCI for program-driven operation
  98.   DDRB   =  0x10; //set PB4 for output mode
  99.   PORTB  =  0x10; //assert DTR pin on COM port
  100.          
  101. // Initialize Port AD pins 7 and 6 for use as digital inputs
  102.   ATDDIEN = 0xC0; //program PAD7 and PAD6 pins as digital inputs
  103.          
  104. // Add additional port pin initializations here
  105.   DDRT = 0xFF; // set all digital pins (PTT) to input
  106.   //interrupts enabled in main
  107.  
  108. /***********************************************************************
  109. * Initialize the ATD to sample a D.C. input voltage (range: 0 to 5V)
  110. * on Channels 0 and 1 (unsigned, 8-bit).  The ATD operates in
  111. * a program-driven fashion, sampling across multiple channels with normal
  112. * flag clear mode using nominal sample time and clock pre-scaler values.                        
  113. ***********************************************************************/
  114.   ATDCTL2_ADPU = 1;  // ATD enable | bit 7
  115.   ATDCTL2_AFFC = 0;  // normal mode set (manual flag clear) | bit 6
  116.   ATDCTL2_ASCIE = 0; // ATD interrupt disabled | bit 1
  117.  
  118.   ATDCTL3_FIFO = 0; // non-FIFO | bit 2
  119.  
  120.   ATDCTL4_SRES8 = 1;    // 8-bit resolution in sampling
  121.   ATDCTL4_SMP = 0;      // 2 ATD clock periods (nominal) | bit 6-5
  122.   //ATDCTL4_PRS = 0x05; // max clock | bit 4-0
  123.   ATDCTL4_PRS0 = 0;
  124.   ATDCTL4_PRS1 = 0;
  125.   ATDCTL4_PRS2 = 1;
  126.   ATDCTL4_PRS3 = 0;
  127.   ATDCTL4_PRS4 = 1;
  128.  
  129.   ATDCTL5_DJM = 0;  // left justified data | bit 7
  130.   ATDCTL5_DSGN = 0; // unsigned data | bit 6
  131.   ATDCTL5_SCAN = 0; // single conversion | bit 5
  132.   ATDCTL5_MULT = 1; // multi-channel sampling | bit 4
  133.  
  134. // Add RTI/interrupt initializations here
  135.   CRGINT = CRGINT | 0x80; // RTI enabled
  136.   RTICTL = 0x42; // RTI every 0.5sec | 279 times | 1.792ms
  137.    
  138. // Additional pins and compiler work arounds
  139.   PTT = 0;
  140.   PTT = PTT | 0x02; //tiny light D3 must be on while stopped
  141.   THRESH1  =   0x04;
  142.   THRESH2  =   0x40;
  143.   THRESH3  =   0xC0;
  144.   CR = 0x0D;
  145.   result_ch0 = 0;
  146.   result_ch1 = 0;
  147. }
  148.                                        
  149. /***********************************************************************
  150. Main
  151. ***********************************************************************/
  152. void main(void) {
  153.     initializations();                                 
  154.     EnableInterrupts;
  155.  
  156.   for(;;) {
  157.  
  158.  
  159. /***********************************************************************
  160. * Main program loop (state machine)
  161. *
  162. * Left pushbutton: stop DVM
  163. * Right pushbutton: start DVM
  164. * Left LED: on if DVM stopped
  165. * Right LED: on if DVM running
  166. *
  167. * On-screen (and LED bar graph) displays should be updated every 0.5 second
  168. *   when "halfsec" flag set (and DVM is running)
  169. ***********************************************************************/
  170.     //sample channels @0.5s | (must be running)
  171.     if ((halfsec == 1) && (runstop == 1)) {
  172.         halfsec = 0;
  173.       //testver = 0xFF;
  174.         getATD();
  175.         vdisp();
  176.         ledbar0();
  177.         ledbar1();
  178.     }
  179.    
  180.     //THIS IS THE START BUTTON
  181.     if ((RIGHTPB_PIN == 0) && (rightpb == 1)) {//right pushbutton has been pushed!
  182.       rightpb = 0; //toggle right pushbutton flag
  183.       prevpbr = 0; //toggle previous pushbutton state
  184.      
  185.       if (runstop == 0) { //Program is stopped
  186.         runstop = 1; //run DVM
  187.         PTT = PTT | 0x01; //Activate tiny light D3
  188.         PTT = PTT & 0xFD; //Silence tiny light D2      
  189.       }
  190.     }
  191.    
  192.     //THIS IS THE STOP BUTTON
  193.     if ((LEFTPB_PIN == 1) && (leftpb == 1)) {//left pushbutton has been pushed!
  194.       leftpb = 0; //toggle left pushbutton flag
  195.       prevpbl = 0; //toggle previous pushbutton state
  196.      
  197.       if (runstop == 1) { //Program is running
  198.         runstop = 0; //stop DVM
  199.         PTT = PTT | 0x02; //Activate tiny light D2
  200.         PTT = PTT & 0xFE; //Silence tiny light D3
  201.         rticnt = 0;
  202.         halfsec = 0;
  203.       }
  204.     }
  205.    
  206.     _FEED_COP(); /* feeds the dog */
  207.   } /* loop forever */
  208.   /* please make sure that you never leave main */
  209. }
  210.  
  211.  
  212.  
  213. /***********************************************************************
  214. * ATD device driver routine: getatd
  215. *
  216. * This routine will initiate an ATD conversion on input Channels 0 and 1
  217. * (by writing to register ATDCTL5), wait for the conversion of both to
  218. * complete (by monitoring the SCF in register ATDSTAT), read the corresponding
  219. * ATD result registers once the conversion completes, and return the
  220. * converted analog sample for Channel 0 and Channel 1.
  221. *
  222. * SENDING: void
  223. * RETURNING: [call vdisp, leddisp], void
  224. ************************************************************************/
  225. void getATD()
  226. {
  227.   ATDCTL5_MULT = 1;
  228.  
  229.   do {
  230.     // I make the chip hot :D
  231.   } while (ATDSTAT0_SCF != 1);
  232.  
  233.   result_ch0 = ATDDR0H;
  234.   result_ch1 = ATDDR1H;
  235.  
  236.   return;
  237. }
  238.  
  239. /***********************************************************************                      
  240. ; RTI interrupt service routine: rti_isr
  241. ;
  242. ; This routine keeps track of when 0.5 seconds worth of
  243. ; RTI interrupts has passed and sets the "halfsec" flag
  244. ;
  245. ; Also, samples state of pushbuttons and sets "leftpb" and
  246. ; "rghtpb" flags accordingly, as well as updates "prevpb"                                                  
  247. ;***********************************************************************/
  248. interrupt 7 void RTI_ISR( void)
  249. {
  250.     CRGFLG = CRGFLG | 0x80; // set CRGFLG bit
  251.     rticnt++;
  252.        
  253.     if (rticnt == 279) {
  254.         halfsec = 1;
  255.         rticnt = 0;
  256.     }
  257.  
  258.     if ((RIGHTPB_PIN == 0) && (prevpbr == 0)) {//pushed | previously not pushed
  259.         rightpb = 1; //pushed
  260.         prevpbr = 1; //previously pushed
  261.     }
  262.  
  263.     if ((LEFTPB_PIN == 0) && (prevpbl == 0)) {//pushed | previously not pushed
  264.         leftpb = 1; //pushed
  265.         prevpbl = 1; //previously pushed
  266.     }
  267. }
  268.  
  269. /***********************************************************************                        
  270. ; Voltage conversion/display routine: vdisp
  271. ;
  272. ; This routine converts the 8-bit, unsigned sample passed to it
  273. ; (range: $00-$FF) into a 3-digit decimal number (N.NN), ranging from 0.00 to
  274. ; (approx.) 5.00 volts, which is then output to the terminal screen as a
  275. ; four-character ASCII string (e.g., "3.92")  
  276. ;***********************************************************************/
  277. void vdisp()
  278. {
  279.   cool = 2*result_ch0;
  280.   convregC = cool % 10;
  281.   cool = cool / 10;
  282.   convregB = cool % 10;
  283.   cool = cool / 10;
  284.   convregA = cool % 10;
  285.   outchar('C');
  286.   outchar('h');
  287.   outchar('a');
  288.   outchar('n');
  289.   outchar('n');
  290.   outchar('e');
  291.   outchar('l');
  292.   outchar(' ');
  293.   outchar('0');
  294.   outchar(':');
  295.   outchar(' ');
  296.  
  297.   outchar(charlookup(convregA));
  298.   outchar('.');
  299.   outchar(charlookup(convregB));
  300.   outchar(charlookup(convregC));
  301.   outchar(' ');
  302.  
  303.   cool = 2*result_ch1;
  304.   convregC = cool % 10;
  305.   cool = cool / 10;
  306.   convregB = cool % 10;
  307.   cool = cool / 10;
  308.   convregA = cool % 10;
  309.   outchar('C');
  310.   outchar('h');
  311.   outchar('a');
  312.   outchar('n');
  313.   outchar('n');
  314.   outchar('e');
  315.   outchar('l');
  316.   outchar(' ');
  317.   outchar('1');
  318.   outchar(':');
  319.   outchar(' ');
  320.  
  321.   outchar(charlookup(convregA));
  322.   outchar('.');
  323.   outchar(charlookup(convregB));
  324.   outchar(charlookup(convregC));
  325.   outchar(CR);
  326.   //outchar(0x0A);
  327.   return;
  328. }
  329.  
  330. char charlookup(int anyvar) {
  331.   //char anychar;
  332.  
  333.   switch(anyvar) {
  334.     case(0):
  335.       return('0');
  336.     case(1):
  337.       return('1');
  338.     case(2):
  339.       return('2');
  340.     case(3):
  341.       return('3');
  342.     case(4):
  343.       return('4');
  344.     case(5):
  345.       return('5');
  346.     case(6):
  347.       return('6');
  348.     case(7):
  349.       return('7');
  350.     case(8):
  351.       return('8');
  352.     case(9):
  353.       return('9');
  354.   }
  355. }
  356.  
  357. /***********************************************************************                      
  358. ; LED bar graph display routine for Channel 0: ledbar0
  359. ;
  360. ; This routine uses the 8-bit, unsigned sample passed to it
  361. ; to update the Channel 0 bar-graph display as follows:
  362. ;
  363. ;  if THRESH1 <  (A) <  THRESH2,  then turn on YELLOW LED (PTT.2)
  364. ;  if THRESH2 <= (A) <  THRESH3,  then turn on GREEN LED  (PTT.3)
  365. ;  if THRESH3 <= (A),             then turn on RED LED    (PTT.4)
  366. ;***********************************************************************/
  367. void ledbar0()
  368. {
  369.    //RED1 GRN1 YLW1 RED0 GRN0 YLW0
  370.    // 7    6    5    4    3    2    1    0
  371.    if (result_ch0 >= THRESH3) { //SET RED LED
  372.       //PTT = PTT | 0x10; //PTT 4 on
  373.       //PTT = PTT & 0xF3; //PTT 2,3 off
  374.     PTT_PTT2 = 0;
  375.     PTT_PTT3 = 0;
  376.     PTT_PTT4 = 1;
  377.    }
  378.    if ((result_ch0 < THRESH3) && (result_ch0 >= THRESH2)) { //SET GREEN LED
  379.       //PTT = PTT | 0x08; //PTT 3 on
  380.       //PTT = PTT & 0xEB; //PTT 2,4 off
  381.       PTT_PTT2 = 0;
  382.       PTT_PTT3 = 1;
  383.       PTT_PTT4 = 0;
  384.    }
  385.    if ((result_ch0 < THRESH2) && (result_ch0) > THRESH1) { //SET YELLOW LED
  386.       //PTT = PTT | 0x04; //PTT 2 on
  387.       //PTT = PTT & 0xE7; //PTT 3,4 off
  388.       PTT_PTT2 = 1;
  389.       PTT_PTT3 = 0;
  390.       PTT_PTT4 = 0;
  391.  
  392.    }
  393.    return;
  394. }
  395.  
  396. /***********************************************************************                              
  397. ; LED bar graph display routine for Channel 1: ledbar1
  398. ;
  399. ; This routine uses the 8-bit, unsigned sample passed to it
  400. ; to update the Channel 1 bar-graph display as follows:
  401. ;
  402. ;  if THRESH1 <  (B) <  THRESH2,  then turn on YELLOW LED (PTT.5)
  403. ;  if THRESH2 <= (B) <  THRESH3,  then turn on GREEN LED  (PTT.6)
  404. ;  if THRESH3 <= (B),             then turn on RED LED    (PTT.7)
  405. ;***********************************************************************/
  406. void ledbar1()
  407. {
  408.    //RED1 GRN1 YLW1 RED0 GRN0 YLW0
  409.    // 7    6    5    4    3    2    1    0
  410.    if (result_ch1 >= THRESH3) { //SET RED LED
  411.       //PTT = PTT | 0x80; //PTT 7 on
  412.       //PTT = PTT & 0x9F; //PTT 5,6 off
  413.       PTT_PTT5 = 0;
  414.       PTT_PTT6 = 0;
  415.       PTT_PTT7 = 1;
  416.    }
  417.    if ((result_ch1 < THRESH3) && (result_ch1 >= THRESH2)) { //SET GREEN LED
  418.       //PTT = PTT | 0x64; //PTT 6 on
  419.       //PTT = PTT & 0x5F; //PTT 5,7 off
  420.       PTT_PTT5 = 0;
  421.       PTT_PTT6 = 1;
  422.       PTT_PTT7 = 0;
  423.    }
  424.    if ((result_ch1 < THRESH2) && (result_ch1) > THRESH1) { //SET YELLOW LED
  425.       //PTT = PTT | 0x20; //PTT 5 on
  426.       //PTT = PTT & 0x3F; //PTT 6,7 off
  427.       PTT_PTT5 = 1;
  428.       PTT_PTT6 = 0;
  429.       PTT_PTT7 = 0;
  430.    }
  431.    return;
  432. }
  433.  
  434. /***********************************************************************
  435. * Character I/O Library Routines for 9S12C32
  436. ************************************************************************
  437. * Name:         inchar
  438. * Description:  inputs ASCII character from SCI serial port and returns it
  439. ************************************************************************/
  440. char  inchar(void) {
  441.   /* receives character from the terminal channel */
  442.         while (!(SCISR1 & 0x20)); /* wait for input */
  443.     return SCIDRL;
  444.  
  445. }
  446.  
  447. /***********************************************************************
  448. * Name:         outchar
  449. * Description:  outputs ASCII character passed in outchar()
  450. *                  to the SCI serial port
  451. ************************************************************************/
  452. void outchar(char ch) {
  453.   /* sends a character to the terminal channel */
  454.     while (!(SCISR1 & 0x80));  /* wait for output buffer empty */
  455.     SCIDRL = ch;
  456. }
Advertisement
Add Comment
Please, Sign In to add comment