Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********************************************************************************
- * ECE 362 - Experiment 7 - Fall 2012
- *********************************************************************************
- * The objective of this lab is to implement a simple digital volt meter (DVM).
- * Using the RTI as a sampling time base, this turn-key application program will
- * sample analog input channels 0 and 1 periodically (every 0.5 second),
- * convert the values read into 3-digit decimal numbers (N.NN), and update
- * the values displayed on the terminal screen, as follows:
- *
- * Ch 0 = N.NN v Ch 1 = N.NN v
- *
- * The right pushbutton will be used to start the DVM, and the left pushbutton
- * will be used to stop the DVM. The left LED will be illuminated when the
- * DVM is stopped, and the right LED will be illuminated when the DVM is running.
- *
- * In addition to the text display of the values on the terminal screen, a set
- * of three LEDs (YELLOW, GREEN, and RED) will be used to indicate the approximate
- * range of the voltage input on each channel (0 and 1). The YELLOW LED for a given
- * channel should be illuminated if the input voltage on that channel is greater
- * than THRESH1 but less than THRESH2. The GREEN LED should be illuminated if the
- * input voltage is greater than or equal to THRESH2 but less than THRESH3. The RED
- * LED should be illuminated if the input voltage is greater than or equal to
- * THRESH3. The external LEDs will be interfaced to pins on Port T.
- *********************************************************************************/
- #include <hidef.h> /* common defines and macros */
- #include "derivative.h" /* derivative-specific definitions */
- #include <mc9s12c32.h> /* microcontroller pin & register definitions */
- // custom re-defines
- #define RIGHTPB_PIN PTAD_PTAD6 //easy-to-read pushbutton right
- #define LEFTPB_PIN PTAD_PTAD7 //easy-to-read pushbutton left
- // function prototypes (info in comment headers)
- char inchar(void);
- void outchar(char x);
- void getATD(void);
- void vdisp(void);
- void ledbar0(void);
- void ledbar1(void);
- char charlookup(int);
- // ASCII character definitions
- char CR = 0x0D; // carriage return
- char LF = 0x0A; // linefeed
- // THRESHOLD specifications (8-bit, unsigned)
- int THRESH1 = 0x04; // 0.08v
- int THRESH2 = 0x40; // 1.28v
- int THRESH3 = 0xC0; // 3,84v
- // generic variable declarations
- int halfsec = 0; // half second flag
- // 0 -> 0.5sec has not passed
- // 1 -> 0.5sec has passed
- int leftpb = 0; // left pushbutton flag
- // 0 -> left pushbutton not pushed
- // 1 -> left pushbutton pushed
- int rightpb = 0; // right pushbutton flag
- // 0 -> right pushbutton not pushed
- // 1 -> right pushbutton pushed
- int prevpbl = 0; // previous left pushbutton state flag
- // 0 -> left pushbutton previously not pushed
- // 1 -> left pushbutton previously pushed
- int prevpbr = 0; // previous right pushbutton state flag
- // 0 -> right pushbutton previously not pushed
- // 1 -> right pushbutton previously pushed
- int runstop = 0; // run/stop flag
- // 0 -> programming is halted
- // 1 -> program is running
- int rticnt = 0; // # of interrupts accumulated
- int result_ch0 = 0; // result of channel 0 sampling
- int result_ch1 = 0; // result of channel 1 sampling
- int convregA = 0; // value A in voltage conversion of form A.BCv
- int convregB = 0; // value B in voltage conversion of form A.BCv
- int convregC = 0; // value C in voltage conversion of form A.BCv
- int cool = 0;
- /***********************************************************************
- * 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
- // Initialize Port AD pins 7 and 6 for use as digital inputs
- ATDDIEN = 0xC0; //program PAD7 and PAD6 pins as digital inputs
- // Add additional port pin initializations here
- DDRT = 0xFF; // set all digital pins (PTT) to input
- //interrupts enabled in main
- /***********************************************************************
- * Initialize the ATD to sample a D.C. input voltage (range: 0 to 5V)
- * on Channels 0 and 1 (unsigned, 8-bit). The ATD operates in
- * a program-driven fashion, sampling across multiple channels with normal
- * flag clear mode using nominal sample time and clock pre-scaler values.
- ***********************************************************************/
- ATDCTL2_ADPU = 1; // ATD enable | bit 7
- ATDCTL2_AFFC = 0; // normal mode set (manual flag clear) | bit 6
- ATDCTL2_ASCIE = 0; // ATD interrupt disabled | bit 1
- ATDCTL3_FIFO = 0; // non-FIFO | bit 2
- ATDCTL4_SRES8 = 1; // 8-bit resolution in sampling
- ATDCTL4_SMP = 0; // 2 ATD clock periods (nominal) | bit 6-5
- //ATDCTL4_PRS = 0x05; // max clock | bit 4-0
- ATDCTL4_PRS0 = 0;
- ATDCTL4_PRS1 = 0;
- ATDCTL4_PRS2 = 1;
- ATDCTL4_PRS3 = 0;
- ATDCTL4_PRS4 = 1;
- ATDCTL5_DJM = 0; // left justified data | bit 7
- ATDCTL5_DSGN = 0; // unsigned data | bit 6
- ATDCTL5_SCAN = 0; // single conversion | bit 5
- ATDCTL5_MULT = 1; // multi-channel sampling | bit 4
- // Add RTI/interrupt initializations here
- CRGINT = CRGINT | 0x80; // RTI enabled
- RTICTL = 0x42; // RTI every 0.5sec | 279 times | 1.792ms
- // Additional pins and compiler work arounds
- PTT = 0;
- PTT = PTT | 0x02; //tiny light D3 must be on while stopped
- THRESH1 = 0x04;
- THRESH2 = 0x40;
- THRESH3 = 0xC0;
- CR = 0x0D;
- result_ch0 = 0;
- result_ch1 = 0;
- }
- /***********************************************************************
- Main
- ***********************************************************************/
- void main(void) {
- initializations();
- EnableInterrupts;
- for(;;) {
- /***********************************************************************
- * Main program loop (state machine)
- *
- * Left pushbutton: stop DVM
- * Right pushbutton: start DVM
- * Left LED: on if DVM stopped
- * Right LED: on if DVM running
- *
- * On-screen (and LED bar graph) displays should be updated every 0.5 second
- * when "halfsec" flag set (and DVM is running)
- ***********************************************************************/
- //sample channels @0.5s | (must be running)
- if ((halfsec == 1) && (runstop == 1)) {
- halfsec = 0;
- //testver = 0xFF;
- getATD();
- vdisp();
- ledbar0();
- ledbar1();
- }
- //THIS IS THE START BUTTON
- if ((RIGHTPB_PIN == 0) && (rightpb == 1)) {//right pushbutton has been pushed!
- rightpb = 0; //toggle right pushbutton flag
- prevpbr = 0; //toggle previous pushbutton state
- if (runstop == 0) { //Program is stopped
- runstop = 1; //run DVM
- PTT = PTT | 0x01; //Activate tiny light D3
- PTT = PTT & 0xFD; //Silence tiny light D2
- }
- }
- //THIS IS THE STOP BUTTON
- if ((LEFTPB_PIN == 1) && (leftpb == 1)) {//left pushbutton has been pushed!
- leftpb = 0; //toggle left pushbutton flag
- prevpbl = 0; //toggle previous pushbutton state
- if (runstop == 1) { //Program is running
- runstop = 0; //stop DVM
- PTT = PTT | 0x02; //Activate tiny light D2
- PTT = PTT & 0xFE; //Silence tiny light D3
- rticnt = 0;
- halfsec = 0;
- }
- }
- _FEED_COP(); /* feeds the dog */
- } /* loop forever */
- /* please make sure that you never leave main */
- }
- /***********************************************************************
- * ATD device driver routine: getatd
- *
- * This routine will initiate an ATD conversion on input Channels 0 and 1
- * (by writing to register ATDCTL5), wait for the conversion of both to
- * complete (by monitoring the SCF in register ATDSTAT), read the corresponding
- * ATD result registers once the conversion completes, and return the
- * converted analog sample for Channel 0 and Channel 1.
- *
- * SENDING: void
- * RETURNING: [call vdisp, leddisp], void
- ************************************************************************/
- void getATD()
- {
- ATDCTL5_MULT = 1;
- do {
- // I make the chip hot :D
- } while (ATDSTAT0_SCF != 1);
- result_ch0 = ATDDR0H;
- result_ch1 = ATDDR1H;
- return;
- }
- /***********************************************************************
- ; RTI interrupt service routine: rti_isr
- ;
- ; This routine keeps track of when 0.5 seconds worth of
- ; RTI interrupts has passed and sets the "halfsec" flag
- ;
- ; Also, samples state of pushbuttons and sets "leftpb" and
- ; "rghtpb" flags accordingly, as well as updates "prevpb"
- ;***********************************************************************/
- interrupt 7 void RTI_ISR( void)
- {
- CRGFLG = CRGFLG | 0x80; // set CRGFLG bit
- rticnt++;
- if (rticnt == 279) {
- halfsec = 1;
- rticnt = 0;
- }
- if ((RIGHTPB_PIN == 0) && (prevpbr == 0)) {//pushed | previously not pushed
- rightpb = 1; //pushed
- prevpbr = 1; //previously pushed
- }
- if ((LEFTPB_PIN == 0) && (prevpbl == 0)) {//pushed | previously not pushed
- leftpb = 1; //pushed
- prevpbl = 1; //previously pushed
- }
- }
- /***********************************************************************
- ; Voltage conversion/display routine: vdisp
- ;
- ; This routine converts the 8-bit, unsigned sample passed to it
- ; (range: $00-$FF) into a 3-digit decimal number (N.NN), ranging from 0.00 to
- ; (approx.) 5.00 volts, which is then output to the terminal screen as a
- ; four-character ASCII string (e.g., "3.92")
- ;***********************************************************************/
- void vdisp()
- {
- cool = 2*result_ch0;
- convregC = cool % 10;
- cool = cool / 10;
- convregB = cool % 10;
- cool = cool / 10;
- convregA = cool % 10;
- outchar('C');
- outchar('h');
- outchar('a');
- outchar('n');
- outchar('n');
- outchar('e');
- outchar('l');
- outchar(' ');
- outchar('0');
- outchar(':');
- outchar(' ');
- outchar(charlookup(convregA));
- outchar('.');
- outchar(charlookup(convregB));
- outchar(charlookup(convregC));
- outchar(' ');
- cool = 2*result_ch1;
- convregC = cool % 10;
- cool = cool / 10;
- convregB = cool % 10;
- cool = cool / 10;
- convregA = cool % 10;
- outchar('C');
- outchar('h');
- outchar('a');
- outchar('n');
- outchar('n');
- outchar('e');
- outchar('l');
- outchar(' ');
- outchar('1');
- outchar(':');
- outchar(' ');
- outchar(charlookup(convregA));
- outchar('.');
- outchar(charlookup(convregB));
- outchar(charlookup(convregC));
- outchar(CR);
- //outchar(0x0A);
- return;
- }
- char charlookup(int anyvar) {
- //char anychar;
- switch(anyvar) {
- case(0):
- return('0');
- case(1):
- return('1');
- case(2):
- return('2');
- case(3):
- return('3');
- case(4):
- return('4');
- case(5):
- return('5');
- case(6):
- return('6');
- case(7):
- return('7');
- case(8):
- return('8');
- case(9):
- return('9');
- }
- }
- /***********************************************************************
- ; LED bar graph display routine for Channel 0: ledbar0
- ;
- ; This routine uses the 8-bit, unsigned sample passed to it
- ; to update the Channel 0 bar-graph display as follows:
- ;
- ; if THRESH1 < (A) < THRESH2, then turn on YELLOW LED (PTT.2)
- ; if THRESH2 <= (A) < THRESH3, then turn on GREEN LED (PTT.3)
- ; if THRESH3 <= (A), then turn on RED LED (PTT.4)
- ;***********************************************************************/
- void ledbar0()
- {
- //RED1 GRN1 YLW1 RED0 GRN0 YLW0
- // 7 6 5 4 3 2 1 0
- if (result_ch0 >= THRESH3) { //SET RED LED
- //PTT = PTT | 0x10; //PTT 4 on
- //PTT = PTT & 0xF3; //PTT 2,3 off
- PTT_PTT2 = 0;
- PTT_PTT3 = 0;
- PTT_PTT4 = 1;
- }
- if ((result_ch0 < THRESH3) && (result_ch0 >= THRESH2)) { //SET GREEN LED
- //PTT = PTT | 0x08; //PTT 3 on
- //PTT = PTT & 0xEB; //PTT 2,4 off
- PTT_PTT2 = 0;
- PTT_PTT3 = 1;
- PTT_PTT4 = 0;
- }
- if ((result_ch0 < THRESH2) && (result_ch0) > THRESH1) { //SET YELLOW LED
- //PTT = PTT | 0x04; //PTT 2 on
- //PTT = PTT & 0xE7; //PTT 3,4 off
- PTT_PTT2 = 1;
- PTT_PTT3 = 0;
- PTT_PTT4 = 0;
- }
- return;
- }
- /***********************************************************************
- ; LED bar graph display routine for Channel 1: ledbar1
- ;
- ; This routine uses the 8-bit, unsigned sample passed to it
- ; to update the Channel 1 bar-graph display as follows:
- ;
- ; if THRESH1 < (B) < THRESH2, then turn on YELLOW LED (PTT.5)
- ; if THRESH2 <= (B) < THRESH3, then turn on GREEN LED (PTT.6)
- ; if THRESH3 <= (B), then turn on RED LED (PTT.7)
- ;***********************************************************************/
- void ledbar1()
- {
- //RED1 GRN1 YLW1 RED0 GRN0 YLW0
- // 7 6 5 4 3 2 1 0
- if (result_ch1 >= THRESH3) { //SET RED LED
- //PTT = PTT | 0x80; //PTT 7 on
- //PTT = PTT & 0x9F; //PTT 5,6 off
- PTT_PTT5 = 0;
- PTT_PTT6 = 0;
- PTT_PTT7 = 1;
- }
- if ((result_ch1 < THRESH3) && (result_ch1 >= THRESH2)) { //SET GREEN LED
- //PTT = PTT | 0x64; //PTT 6 on
- //PTT = PTT & 0x5F; //PTT 5,7 off
- PTT_PTT5 = 0;
- PTT_PTT6 = 1;
- PTT_PTT7 = 0;
- }
- if ((result_ch1 < THRESH2) && (result_ch1) > THRESH1) { //SET YELLOW LED
- //PTT = PTT | 0x20; //PTT 5 on
- //PTT = PTT & 0x3F; //PTT 6,7 off
- PTT_PTT5 = 1;
- PTT_PTT6 = 0;
- PTT_PTT7 = 0;
- }
- return;
- }
- /***********************************************************************
- * Character I/O Library Routines for 9S12C32
- ************************************************************************
- * Name: inchar
- * Description: inputs ASCII character from SCI serial port and returns it
- ************************************************************************/
- 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
- ************************************************************************/
- void outchar(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