A/D Converter using the C Language
Introduction
In this demo we will create a Code Warrior project which uses the C language and the A/D converter. The program will light up port B leds as the trimpot is turned.
Before proceeding with this demo, review the A/D overview and the C demo if needed.
Steps to Create the Project
First, create a project called 'c_adc_demo' using the _ee3376_C stationery. Then, in the project you just created open up the source code file called 'c_demo.c' and Save As 'c_adc_demo.c'. Then, simply cut/paste the code below into the 'c_adc_demo.c' file. So, we basically just replaced the 'c_demo'c' code in the stationery project with the 'c_adc_demo.c' code below. In the Target Settings under "Linker for HC12", set the application filename to 'c_adc_demo.abs'. All other files and target settings are as in the stationery and do not need to be changed.
Once you have completed the above steps, click on the 'Make' button to build the project. Using DBug12, download 'c_adc_demo.abs.s1' to the Dragon12, and type 'g 1829' to start the program running. As you turn the orange VR2 trimpot CW, the LEDs should light up and should all be lit once the trimpot is fully turned CW. As you turn the trimpot CCW, the LEDs should turn off, and should all be off once the trimpot is turned fully CCW.
If you have any problems or questions, call on the TA for assistance.
Source Code for 'c_adc_demo.c'
Note that you need to add the following Port J code for Rev. E boards to enable the Port B LEDs (add the code at the beginning of the program):
line 1: DDRJ = 0xFF; /* set Port J ddr to output */
line 2: PTJ = 0x00; /* set Port J low to enable Port B LEDs */.
/****************************************************************
*
* UTEP EE3376
* c_adc_demo.c
* Code Warrior v.3 on the Dragon12 Board
* 3 Sept 2004
*
* This code uses the Port B LEDs and the A/D Converter. The number
* of Port B LEDs lit depends on strength of A/D signal from trimpot
* VR2 (tied to pin AN7) on the Dragon12 board. We use 8 bit A/D
* conversion.
*
* The code is for an external OSCCLK running at 4 MHz, as it does on the
* Dragon12 board. The program is based on the RTI interrupt, and
* the interrupt vector table is remapped to $3E00 since we are
* running DBug12.
*
*
****************************************************************/
/****************************************************************
* Include files
****************************************************************/
#include <mc9s12dp256.h> /* 9S12DP256 register definitions */
/***************************************************************
* Function prototypes
****************************************************************/
__interrupt void RealTimeInterrupt(void);
/****************************************************************
* Local data definitions
****************************************************************/
static volatile unsigned char rtiCnt; /* to count number of RTIs */
/****************************************************************
* Main part of the program
* The register definitions are all in mc9s12dp256.h
****************************************************************/
void main(void)
{
/* set up Port B */
DDRB = 0xFF; /* set portb pins all to output */
PORTB = 0x00; /* turn Port B LEDs off */
/* Set up the A/D converter and start it running; we use 8 bit resolution. Note that
* the ATD registers have a "0" signifier - thus we have ATD0CTL2 instead of ATDCTL2 as
* used in some parts of the HCS12 hardware manual */
ATD0CTL2 = 0x80; /* turn on ADC */
ATD0CTL3 = 0x08; /* 1 AD conversion/sequence */
ATD0CTL4 = 0xEB; /* 8 bit, 16 AD clocks/conversion, 1 MHz clock */
ATD0CTL5 = 0x27; /* left justify, unsigned, sample only specified channel */
/* set up RTI */
RTICTL = 0x31; /* (2*2^12)/(4x10^6) = 2.048 ms per RTI */
CRGINT |= 0x80; /* enable RTI interrupt */
rtiCnt = 0; /* RTI counter to 0 */
asm("cli"); /* enable global interrupts */
for (;;) { /* our infinite loop */
if (rtiCnt == 10) /* check the AD registers every 20 msec */
{
/* light LEDs according to range in AD result register; since 8 bit,
* we need only to look at the high byte, ATD0DR0H, of the result register*/
if(ATD0DR0H <= 0x20) /* no LEDs lit if less than $20 */
PORTB = 0x00;
if(ATD0DR0H > 0x20)
PORTB = 0x01;
if(ATD0DR0H > 0x40)
PORTB = 0x03;
if(ATD0DR0H > 0x60)
PORTB = 0x07;
if(ATD0DR0H > 0x80)
PORTB = 0x0f;
if(ATD0DR0H > 0xa0)
PORTB = 0x1f;
if(ATD0DR0H > 0xc0)
PORTB = 0x3f;
if(ATD0DR0H > 0xe0)
PORTB = 0x7f;
if(ATD0DR0H == 0xff) /* all LEDs lit if max value $ff */
PORTB = 0xff;
rtiCnt = 0; /* reset rti counter */
}
}
} /* end main() */
__interrupt void RealTimeInterrupt(void)
{
rtiCnt++; /* increment the counter */
CRGFLG = 0x80; /* clear rti flag */
} /*end RealTimeInterrupt() */
/***** end c_adc_demo.c ****/