+ All Categories
Home > Documents > ECE 3567 Lab 4 Analog-to-Digital Converters · • This setting depends on which microcontroller...

ECE 3567 Lab 4 Analog-to-Digital Converters · • This setting depends on which microcontroller...

Date post: 20-Oct-2020
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
73
ECE 3567 Lab 4 Analog-to-Digital Converters Dr. Gregg J Chapman Autumn 2019 1
Transcript
  • ECE 3567

    Lab 4

    Analog-to-Digital Converters

    Dr. Gregg J ChapmanAutumn 2019

    1

  • The Users Manual

    Chapter 33 REF_A………………………………….pp 858-864Chapter 34 ADC12_B……………………………..pp 865-911

    2

  • Laboratory #4 Goals

    1. Implement a TWO channel conversion sequence, one channel for the RC_Voltage (A5), and a second channel for the internal Temperature Sensor (A30).

    2. Display the temperature in Fahrenheit on the Liquid Crystal Display.

    3. Measure the RC filtered voltage and set the LED color according to voltage values.

    4. Display the RC filtered voltage on the Liquid Crystal Display.

    5. Configure a Pushbutton to change the LCD display to either temperature or voltage.

  • The RC Circuit

    fcutoff = 6 Hz

    ADC A5

    A5 input on ADC12

    RC charging circuit P2.1 PWM output

  • The Temperature Sensor

  • LaunchPad LCD Display

    6

  • LaunchPad Pushbuttons

  • Lab #4 Downloaded Files

    NOTE: Save the RC voltage functions that you wrote last week and add them to the RCMode.c if necessary.

    8

  • ADC12.c

    void Init_ADC12(void)__interrupt void ADC12_ISR(void)

    Template with declarations and headers is included in the Lab 4 Code Additions download. Copy and ADD all files to your existing project directory.

    9

  • ADC12.cvoid Init_ADC12(void)

    10

  • ADC12 InitializationInit_ADC12()

    1. Set pin 8.6 as the ANALOG INPUT for A-to-D channel A52. Configure the Internal Voltage Reference.3. Set up Timer A1 as the ADC SAMPLE CLOCK4. Activate the internal Temperature Sensor (must ne on ADC12 channel A30)5. Configure the ADC12 for a 2-channel repeated sequence, beginning with A30 and

    ending with A5.6. Set up MEM0 buffer to receive channel A30 data values.7. Set up MEM1 buffer to receive channel A5 data values.8. Generate the ADC12 Interrupt whenever MEM1 receives a new conversion value.9. Clear any pending interrupts, enable interrupts, and start the repeated conversion

    sequence.

    NOTE: Don’t forget to call Init_ADC12() at the beginning of main().

    11

  • 1. Set-up P8.6 as Channel A5

    12

    1 1 Tertiary

    Note: It is not necessary to set the P8DIR register, bit 6, as an input when you select the A5 (Tertiary) function.

  • 2. Configure Internal Voltage Reference

  • 14

    2. Configure Internal Voltage ReferenceRegister – ADC12MCTLx

  • VCC - Positive Voltage, AnalogVEE - Negative Voltage (or GND), Analog

    VDD - Positive Voltage, DigitalVSS - Negative Voltage (or GND), Digital

    De-Mystifying Voltage Labels

  • 1. Clear TA1CTL2. Select ACLK and No Pre-Divide in TA1CTL

    3. Set-up Timer A1 as Sample Clock

  • 3. In TA1CCTL1, Select Compare Mode, Reset/Set Output Mode, Interrupts Disabled

    17

    3. Set-up Timer A1 as Sample Clock

  • 4. In TA1CCR0, Set Period for a Frequency of 32 Hz. This gets /8 later for a 4Hz sample rate5. In TA1CCR1, Set Duty Cycle to 50%

    18

    3. Set-up Timer A1 as Sample Clock

  • 6. Start Timer in UP Mode by writing Bits 5-4 to [01]3. Set-up Timer A1 as Sample Clock

  • 4. Activate Internal Temperature Sensor5. Configure ADC12 for 2-Channel Repeated Sequence

    There are FOUR Configuration Registers for the ADC12_B:

    ADC12CTL0 – ADC12CTL3.

  • ADC12 ConfigurationRegister – ADC12CTL0

    1. Set the clock cycles for sample-and-hold for MEM8-MEM23 to 256 (Bits 15-12) 1000

    21

  • ADC12 ConfigurationRegister – ADC12CTL0

    2. Set the clock cycles for sample-and-hold for MEM0-MEM7 to 4 (Bits 11-8) 0000

    22

  • ADC12 ConfigurationRegister – ADC12CTL0

    3. Set Bit 7 to cause the first rising edge of the SHI to initiate sampling and continue automatically4. Turn on the ADC12 Module (Bit 4)XX1X5. Disable Conversion (Bit 1)

    23

  • ADC12 ConfigurationRegister – ADC12CTL1

    24

    1. Pre-divide the clock source by 4 (Bit 14-13)

  • ADC12 ConfigurationRegister – ADC12CTL1

    25

    1. Pre-divide the clock source by 4 (Bit 14-13)2. Select Timer A1 as the clock source by configuring Bits 12-10 to [100] *

    * SEE NEXT SLIDE for this incredible example of the inefficiency in the TI documentation!

  • Register – ADC12CTL1

    • This setting depends on which microcontroller model you have. • The setting is in a completely different manual for each MCU!!• I have placed a copy of the MSP430FR6989.PDF on the course website

    Page 88

    * ADC12SHSx - Select Timer A1 as the clock source by configuring Bits 12-10 to [100] *

    = 0x100

    ADC12 Configuration

    26

  • ADC12 ConfigurationRegister – ADC12CTL1

    27

    1. Pre-divide the clock source by 4 (Bit 14-13)2. Select Timer A1 as the clock source by configuring Bits 12-10 to [100] *3. Configure the ADC12_B clock divider to 2 (Bits 7-5)

  • ADC12 ConfigurationRegister – ADC12CTL1

    28

    1. Pre-divide the clock source by 4 (Bit 14-13)2. Select Timer A1 as the clock source by configuring Bits 12-10 to [100] *3. Configure the ADC12_B clock divider to 2 (Bits 7-5)4. Configure Bits 4-3 to select ACLK as the source clock

  • ADC12 ConfigurationRegister – ADC12CTL1

    29

    1. Pre-divide the clock source by 4 (Bit 14-13)2. Select Timer A1 as the clock source by configuring Bits 12-10 to [100] *3. Configure the ADC12_B clock divider to 2 (Bits 7-5)4. Configure Bits 4-3 to select ACLK as the source clock5. Select the Repeated-Sequence-of-Channels option for Bits 2-1

  • ADC12 ConfigurationRegister – ADC12CTL2

    30

    This register controls bit resolution and data readback format.There are no changes from the default values in this register

  • Register – ADC12CTL31. Set Bit 7. This selects the Temperature Sensor for ADC channel A30

    ADC12 Configuration

    31

  • Register – ADC12MCTL0

    1. Disable the Comparator Window2. Enable Single-ended Mode

    32

    6. Set MEM0 Buffer for A30 Data

  • Register – ADC12MCTL03. Set voltage source combination to VR+ = VREF buffered, VR- = AVSS

    33

    6. Set MEM0 Buffer for A30 Data

  • Register – ADC12MCTL0

    4. MEM0 is NOT the end of the sequence

    34

    6. Set MEM0 Buffer for A30 Data

  • Register – ADC12MCTL05. Select A30 (the temperature probe) as the Input Source.

    6. Set MEM0 Buffer for A30 Data

  • Register – ADC12MCTL1

    36

    7. Set MEM1 Buffer for A5 Data

    1. Disable the Comparator Window2. Enable Single-ended Mode

  • Register – ADC12MCTL1

    3. Set voltage source combination to VR+ = AVCC, VR- = AVSS

    7. Set MEM1 Buffer for A5 Data

  • Register – ADC12MCTL14. MEM1 IS the end of the sequence

    38

    7. Set MEM1 Buffer for A5 Data

  • Register – ADC12MCTL15. Select A5 as the Input Source.

    39

    7. Set MEM1 Buffer for A5 Data

  • 9a. Clear Interrupts (write 0)

  • 8. Generate the ADC12 Interrupt whenever MEM1 receives a new conversion value.

    9b. Enable Interrupts

  • 9c. Enable Conversion

  • Please have your Init_ADC12() checked before proceeding

    43

    Checkpoint #1

  • 1. In the ADC12 Interrupt Service Routine, for the ADCMEM1 interrupt case:

    a. Clear the Interrupt:

    ADC12_B_clearInterrupt(ADC12_B_BASE, 0, ADC12_B_IFG1);

    b. Transfer MEM0 and MEM1 values to the following variables:

    ADCValue0 = ADC12MEM0;

    ADCValue1 = ADC12MEM1;

    2. Comment out the #pragma for the Timer A1 vector and the ADC12 vector

    ADC12 Configuration – Interrupt Service Routine

    44

  • The ADC12 Interrupt Service Routine

    45

  • ADC12 Configuration – Don’t forget to comment out used #pragmasin unused_interrupts.c

    46

  • TempSensorMode.c

    47

  • TempSensorMode.c Functions

    48

  • TempSensorMode.c Functions

    49

  • void displayTemp(){

    clearLCD();if (tempUnit == 0){

    showChar('C',pos6);}else{

    showChar('F',pos6);}

    // Handles displaying up to 999.9 degreesif (deg>=1000)

    showChar((deg/1000)%10 + '0',pos3);if (deg>=100)

    showChar((deg/100)%10 + '0',pos4);if (deg>=10)

    showChar((deg/10)%10 + '0',pos5);

    // Degree symbolLCDMEM[pos5+1] |= 0x04;

    }

    50

    //Uses Modulo Division to get Remainder// then adds 48 (‘0’) to convert to ASCII// One decimal place at a time

    TempSensorMode.c Functions

  • myLcd.c

    51

  • LaunchPad LCD Display

    52

  • myLcd.c Character Maps

    53

    // LCD memory map for uppercase lettersconst char alphabetBig[26][2] ={

    {0xEF, 0x00}, /* "A" LCD segments a+b+c+e+f+g+m */

    {0xF1, 0x50}, /* "B" */{0x9C, 0x00}, /* "C" */{0xF0, 0x50}, /* "D" */{0x9F, 0x00}, /* "E" */{0x8F, 0x00}, /* "F" */{0xBD, 0x00}, /* "G" */{0x6F, 0x00}, /* "H" */{0x90, 0x50}, /* "I" */{0x78, 0x00}, /* "J" */{0x0E, 0x22}, /* "K" */{0x1C, 0x00}, /* "L" */{0x6C, 0xA0}, /* "M" */{0x6C, 0x82}, /* "N" */{0xFC, 0x00}, /* "O" */{0xCF, 0x00}, /* "P" */{0xFC, 0x02}, /* "Q" */{0xCF, 0x02}, /* "R" */{0xB7, 0x00}, /* "S" */{0x80, 0x50}, /* "T" */{0x7C, 0x00}, /* "U" */{0x0C, 0x28}, /* "V" */{0x6C, 0x0A}, /* "W" */{0x00, 0xAA}, /* "X" */{0x00, 0xB0}, /* "Y" */{0x90, 0x28} /* "Z" */

    };

    // LCD memory map for numeric digitsconst char digit[10][2] ={

    {0xFC, 0x28}, /* "0" LCD segments a+b+c+d+e+f+k+q */{0x60, 0x20}, /* "1" */{0xDB, 0x00}, /* "2" */{0xF3, 0x00}, /* "3" */{0x67, 0x00}, /* "4" */{0xB7, 0x00}, /* "5" */{0xBF, 0x00}, /* "6" */{0xE4, 0x00}, /* "7" */{0xFF, 0x00}, /* "8" */{0xF7, 0x00} /* "9" */

    };

  • myLcd.c Functions

    54

    void Init_LCD(){

    LCD_C_initParam initParams = {0};initParams.clockSource = LCD_C_CLOCKSOURCE_ACLK;initParams.clockDivider = LCD_C_CLOCKDIVIDER_1;initParams.clockPrescalar = LCD_C_CLOCKPRESCALAR_16;initParams.muxRate = LCD_C_4_MUX;initParams.waveforms = LCD_C_LOW_POWER_WAVEFORMS;initParams.segments = LCD_C_SEGMENTS_ENABLED;

    LCD_C_init(LCD_C_BASE, &initParams);// LCD Operation - VLCD generated internally, V2-V4 generated internally, v5 to ground

    LCD_C_setPinAsLCDFunctionEx(LCD_C_BASE, LCD_C_SEGMENT_LINE_0,LCD_C_SEGMENT_LINE_21);

    LCD_C_setPinAsLCDFunctionEx(LCD_C_BASE, LCD_C_SEGMENT_LINE_26,LCD_C_SEGMENT_LINE_43);

    LCD_C_setVLCDSource(LCD_C_BASE, LCD_C_VLCD_GENERATED_INTERNALLY,LCD_C_V2V3V4_GENERATED_INTERNALLY_NOT_SWITCHED_TO_PINS,LCD_C_V5_VSS);

    // Set VLCD voltage to 3.20vLCD_C_setVLCDVoltage(LCD_C_BASE,

    LCD_C_CHARGEPUMP_VOLTAGE_3_02V_OR_2_52VREF);

    // Enable charge pump and select internal reference for itLCD_C_enableChargePump(LCD_C_BASE);LCD_C_selectChargePumpReference(LCD_C_BASE,

    LCD_C_INTERNAL_REFERENCE_VOLTAGE);

    LCD_C_configChargePump(LCD_C_BASE, LCD_C_SYNCHRONIZATION_ENABLED, 0);

    // Clear LCD memoryLCD_C_clearMemory(LCD_C_BASE);

    //Turn LCD onLCD_C_on(LCD_C_BASE);

    }

  • myLcd.c Functions

    55

    void showChar(char c, int position){

    if (c == ' '){

    // Display spaceLCDMEM[position] = 0;LCDMEM[position+1] = 0;

    }else if (c >= '0' && c = 'A' && c

  • myLcd.c Functions

    56

    /** Clears memories to all 6 digits on the LCD*/void clearLCD(){

    LCDMEM[pos1] = LCDBMEM[pos1] = 0;LCDMEM[pos1+1] = LCDBMEM[pos1+1] = 0;LCDMEM[pos2] = LCDBMEM[pos2] = 0;LCDMEM[pos2+1] = LCDBMEM[pos2+1] = 0;LCDMEM[pos3] = LCDBMEM[pos3] = 0;LCDMEM[pos3+1] = LCDBMEM[pos3+1] = 0;LCDMEM[pos4] = LCDBMEM[pos4] = 0;LCDMEM[pos4+1] = LCDBMEM[pos4+1] = 0;LCDMEM[pos5] = LCDBMEM[pos5] = 0;LCDMEM[pos5+1] = LCDBMEM[pos5+1] = 0;LCDMEM[pos6] = LCDBMEM[pos6] = 0;LCDMEM[pos6+1] = LCDBMEM[pos6+1] = 0;

    LCDM14 = LCDBM14 = 0x00;LCDM18 = LCDBM18 = 0x00;LCDM3 = LCDBM3 = 0x00;

    // LCDMEM[12] = LCDMEM[13] = 0;}

  • myLcd.c Functions

    57

  • Quiz Question

    What number do you subtract from the ASCII character for a number to convert from ASCII code to an actual numeric value?

    What is the number in Hexadecimal?

    What is the number in Decimal?

    What ASCII number can you subtract from another ASCII number to convert it to a decimal value?

    What do you add to a number to convert to the ASCII character?

    58

  • void displayTemp(){

    clearLCD();if (tempUnit == 0){

    showChar('C',pos6);}else{

    showChar('F',pos6);}

    // Handles displaying up to 999.9 degreesif (deg>=1000)

    showChar((deg/1000)%10 + '0',pos3);if (deg>=100)

    showChar((deg/100)%10 + '0',pos4);if (deg>=10)

    showChar((deg/10)%10 + '0',pos5);

    // Degree symbolLCDMEM[pos5+1] |= 0x04;

    }

    59

    //Uses Modulo Division to get Remainder// then adds 48 (‘0’) to convert to ASCII// One decimal place at a time

    TempSensorMode.c Functions

  • Checkpoint #2

    Demonstrate the temperature sensor on the LCD (display) in Fahrenheit with 16 averages and updating once every second. You may use the cold spray to change the temperature rapidly.

    60

  • RCMode.c

    61

  • RCMode.c

    62

    void RC_Voltage(){

    ISR_Flag = 0;// Calculate voltage from A5 ADC dataunsigned int tempRC = (ADCValue1);tempRC = ((((unsigned long)tempRC)*4/5) + 28);

    // Averaging Routinek2++;sum2 = sum2 + tempRC;if(k2 >= Vsize) // Vsize is the number of values to average. In 3567.h{

    volts = sum2/(Vsize);sum2 = 0;k2 = 0;

    // Display Voltageif(LCD_Control == TRUE)

    displayVolts();}

    }

  • RCMode.c

    63

  • Demonstrate the filtered RC voltage with 2 digits after the decimal, an average of 16 value, and updating once per second.

    64

    Checkpoint #3

  • //*********************The Initializations*************************************/Init_LCD();Init_GPIO();Init_Clocks();Init_PWM(); // This was written for you and should be in TempSensorMode.ctempSensorModeInit(); // Given. Add this.Init_ADC12(); // New. You write thisInit_RC(); // You wrote this last weekInit_LCD(); // Given. Add this.

    Update the main() Initializations

    65

  • Pushbutton Bounce

    • Software must require button to remain in a stable logic state for at least the duration of a worst case observed for switch bounce.

    • Multiple transitions causes many state changes or PB Interrupts.

    • Use multiple pin reads and a counter to verify that the logic level of the button has remained stable for the debounce duration.

    • Measure worst case with oscilloscope

    • Use delays, with or without ISR, to verify bounce duration has ended.

    66

    6 mS 6 mSTransition Verified

    INTERRUPTS

  • Pushbutton Code

    67

    1. Use BOTH pushbuttons. One to change the LCD to RC_Voltage and the other pushbutton to change the LCD to display temperature.

    2. Clear the LED and LCD when either button is pressed and held.

    3. Use the Booleans RC_Control and T_Control to select which process is displayed.

    if(Temp_Button_Press >=5) // Detect 500 mSec button press.{

    RC_Control= FALSE;T_Control = TRUE;PWM_null(); // Turn off LEDclearLCD(); // Clear out LCDTemp_Button_Press = 0;Volt_Button_Press = 0;while((P1IN & BIT1) == 0x00);

    }else if(Volt_Button_Press >=5){

    RC_Control= TRUE;T_Control = FALSE;

    PWM_null(); // Turn off LEDclearLCD(); // Clear out LCDTemp_Button_Press = 0;Volt_Button_Press = 0;while((P1IN & BIT2) == 0x00);

    }

  • Pushbutton Code

    68

    4. “Debounce” the button press by delaying action for 500 milliseconds. Note that this is 5 executions of the Timer A0 ISR.

  • Pushbutton Code

    69

    5. Comment out the Interrupt configurations for P1.1 and P1.2 in Init_GPIO():

  • Pushbutton Code

    70

    6. IN unused_interrupts.c, make sure the #pragma vector = PORT1_VECTOR // Port 1 is NOT commented out

    7. Configure BOTH pushbuttons as INPUTS with PULL_UP Resistors at the beginning of main():

    P1DIR &= ~BIT1; // Set as InputP1REN |= BIT1; // Configure Pull-up ResistorP1OUT |= BIT1; // Completes Pull-up Configuration

    NOTE: No Pull-up Rs here unless configured!

  • Pushbutton CodePolling Method

    71

    8. Modify main() to conditionally execute the RC voltage or Temperature Measurement using Booleans. Toggle the two control Booleans in main if the pushbutton is pressed. e.g.:

    if(RC_Control == TRUE) // Change PWM, measure voltage and display color range{

    update_RC();RC_Voltage();update_RGB();

    }else if(T_Control == TRUE) // Temperature in Fahrenheit on displayed on LCD{

    tempSensor();}

  • If-else for LED Color

    72

    1. Add if-else code to update_RGB() change the LED color every 500 mV.

    2. The voltage should be calculated from the AVERAGED A5 A-to-D value. This variable is called volts

    3. Use the following table:

    COLORVoltage Range

    Min Voltage (mV) Max Voltage (mV)

    RED 0 500

    ORANGE 501 1000

    YELLOW 1001 1500

    GREEN 1501 2000

    BLUE 2001 2500

    PURPLE 2501 3000

    WHITE > 3000 NA

  • Checkpoint #4 and #5

    #4 - Demonstrate that the two pushbuttons select either the RC_Voltage or the Temperature (F) function. The LED and LCD should remain off if either button is pressed and held.

    #5 - In the RC_Voltage mode, demonstrate that the LED changes color based on the filtered RC voltage according to the table provided.

    73

    ECE 3567��Lab 4��Analog-to-Digital Converters�The Users Manual�Laboratory #4 GoalsSlide Number 4The Temperature SensorLaunchPad LCD DisplayLaunchPad PushbuttonsLab #4 Downloaded FilesADC12.c�ADC12.c�ADC12 Initialization�Init_ADC12()Slide Number 12Slide Number 13Slide Number 14Slide Number 15Slide Number 16Slide Number 17Slide Number 18Slide Number 19Slide Number 20ADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationSlide Number 26ADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationADC12 ConfigurationSlide Number 32Slide Number 33Slide Number 34Slide Number 35Slide Number 36Slide Number 37Slide Number 38Slide Number 39Slide Number 40Slide Number 41Slide Number 42Checkpoint #1ADC12 Configuration – Interrupt Service RoutineSlide Number 45ADC12 Configuration – Don’t forget to comment out used #pragmas� in unused_interrupts.cSlide Number 47TempSensorMode.c FunctionsTempSensorMode.c FunctionsTempSensorMode.c FunctionsSlide Number 51LaunchPad LCD DisplaymyLcd.c Character MapsmyLcd.c FunctionsmyLcd.c FunctionsmyLcd.c FunctionsmyLcd.c FunctionsQuiz QuestionTempSensorMode.c FunctionsCheckpoint #2Slide Number 61Slide Number 62Slide Number 63Checkpoint #3Slide Number 65Slide Number 66Slide Number 67Slide Number 68Slide Number 69Slide Number 70Slide Number 71Slide Number 72Checkpoint #4 and #5


Recommended