You are on page 1of 23

Laboratory

HCS12 Programming
Multitasking and A/D Conversion

In this lab first you will write and download Assembly Language code into the CSM12D board.
This experiment helps you understand the Analog to Digital converter within the HCS12. Then
you will write a code to perform multitasking in C language for A/D conversion.

Objectives

Learn about the user interface module on the PBMCUSLK project board.
Write Assembly Language code that uses A/D conversion
Learn multitasking programming in C language

Components/Software

PBMCUSLK project board


CSM12D extension board
Code Warrior software
USB programming cable
LAB3 Instructions (This file)

Other Useful Information

Reference materials for the MC9S12DT256 microcontroller


Reference materials for the CSM12D module
Reference materials for the PBMCUSLK board
Reference materials for CodeWarrior

Pre-Lab Section

Pre-lab Tasks

In this pre-lab, you must become familiar with the way you implement A/D conversion using
beans within CodeWarrior.

Pre-lab Report
Part A:
In this part, you are required to write Assembly Language code in CodeWarrior to perform
Analog to Digital conversions. When your code starts running, you must perform one A/D
conversion and store the value. Subsequently, you will perform A/D conversions and subtract
from them, the initially stored A/D value. Once this is done, you must output the value to Port B
which will be wired to the 8 LEDs on the prototyping board. Vary the applied voltage and
observe the LEDs. Start your program under different initial applied voltages.
Comment your code.
Once you have your code working and demonstrated to your TA, modify it to control the
8 LEDs based on the following logic:
If A/D value-initial value is between 00000000 and 00011111, turn on LED 0
If A/D value-initial value is between 00100000 and 00111111, turn on LED 1
If A/D value-initial value is between 01000000 and 01011111, turn on LED 2
If A/D value-initial value is between 01100000 and 01111111, turn on LED 3
If A/D value-initial value is between 10000000 and 10011111, turn on LED 4
If A/D value-initial value is between 10100000 and 10111111, turn on LED 5
If A/D value-initial value is between 11000000 and 11011111, turn on LED 6
If A/D value-initial value is between 11100000 and 11111111, turn on LED 7
You must try out your code, on the simulator, before you come to the lab.

Part B:
In this part, you are required to write C code in CodeWarrior to perform Analog to Digital
conversions. Your program will perform the same functions described in Lab 3, but your
implementation will be multitasking. When your code starts running, you must perform one A/D

conversion and store the value. Subsequently, you will perform A/D conversions and subtract
from them, the initially stored A/D value. Once this is done, you must output the value to Port B
which will be wired to the 8 LEDs on the prototyping board. Vary the applied voltage and
observe the LEDs. Start your program under different initial applied voltages.
Comment your code.Once you have your code working and demonstrated to your TA, modify it
to control the 8 LEDs based on the following logic:

If A/D value-initial value is between 00000000 and 00011111, turn on LED 0


If A/D value-initial value is between 00100000 and 00111111, turn on LED 1
If A/D value-initial value is between 01000000 and 01011111, turn on LED 2
If A/D value-initial value is between 01100000 and 01111111, turn on LED 3
If A/D value-initial value is between 10000000 and 10011111, turn on LED 4
If A/D value-initial value is between 10100000 and 10111111, turn on LED 5
If A/D value-initial value is between 11000000 and 11011111, turn on LED 6
If A/D value-initial value is between 11100000 and 11111111, turn on LED 7

You must try out your code, on the simulator, before you come to the lab.

Lab Section

Lab Tasks

PartA:

Create a new C-code project using the following steps:


1. Start up the CodeWarrior IDE on one of the lab machines by clicking on the
desktop shortcut.

2. A new window will pop up, choose Create New Project

3. Choose MC9S12DT256B, from HCS12D Family and select Full Chip Simulation.
Click Next
4. Check the box for Relocatable Assembly.

5. Name the project Lab4 and choose a location where the files will be saved. Click
Next

6. Do NOT add any existing file to the project. Click Next

7. Select None for Rapid Application Development options. Click Finished


8. Open the main.asm file in the Sources node in the project window.

9. Edit the main Assembly Language file and add your code. Your code may need to
be similar to the one below, but not necessarily identical. Add your code to turn on
the appropriate LEDs based on the A/D value.
;**************************************************************
;* This stationery serves as the framework for a
*
;* user application. For a more comprehensive program that
*
;* demonstrates the more advanced functionality of this
*
;* processor, please see the demonstration applications
*
;* located in the examples subdirectory of the
*
;* Freescale CodeWarrior for the HC12 Program directory
*
;**************************************************************
; Include derivative-specific definitions
;INCLUDE 'derivative.inc'
; export symbols
XDEF Entry, _Startup, main
; we use export 'Entry' as symbol. This allows us to
; reference 'Entry' either in the linker .prm file
; or from C/C++ later on

XREF __SEG_END_SSTACK
; symbol defined by the linker for the end of the stack
; include derivative specific macros
INCLUDE 'mc9s12dt256.inc'
ATDRESULT EQU $91
; variable/data section
MY_EXTENDED_RAM: SECTION
; Insert here your data definition.
Counter
ds.w 1
A2Dval: ds.b 1
processedVal: ds.b 1
frozenVal: ds.b 1
; code section
MyCode:
SECTION
main:
_Startup:
Entry:
LDS #__SEG_END_SSTACK
CLI
JSR Init
BSR PortSetup
BSR ATDsetup

; initialize the stack pointer


; enable interrupts

mainLoop:
BSR
JSR
BSR
BSR
BRA

ATDread
DoPushButton
DoProcessing
DoLEDS
mainLoop

ATDsetup:
PSHA
LDAA #$80
STAA ATD0CTL2
LDAA #$FF

; start A/D

wait:
DECA
BNE wait
LDAA #$08
STAA ATD0CTL3
LDAA #$80
STAA ATD0CTL4
LDAA #$A0
STAA ATD0CTL5

; delay to wait for the start of A/D


; program CTL 3, 4, 5

wait2:
LDAA ATD0STAT0
ANDA #$80
BEQ wait2
PULA
RTS

; check if A/D finish converting


; wait until MSBit is set, end of conversion

ATDread:
PSHA
LDAA ATDRESULT
STAA A2Dval
PULA
RTS
PortSetup:
PSHA
LDAA
STAA
LDAA
STAA
PULA
RTS

#$11
DDRA
#$FF
DDRB

DoLEDS:
PSHA
LDAA processedVal
BRA OVER_THE_FANCY
ANDA #%11100000
CMPA #%00011111 ;#%00000000
BEQ LED0on
;ANDA #%00100000
CMPA #%00111111 ;#%00100000
BEQ LED1on
;ANDA #%01000000 ;#%01000000
CMPA #%01011111
BEQ LED2on
;ANDA #%01100000
CMPA #%01111111 ;#%01100000
BEQ LED3on
;ANDA #%10000000
CMPA #%10011111 ;#%10000000
BEQ LED4on
;ANDA #%10100000
CMPA #%10111111 ;#%10100000
BEQ LED5on
;ANDA #%11000000
CMPA #%11011111 ;#%11000000
BEQ LED6on
;ANDA #%11100000
CMPA #%11111111 ;#%11100000
BEQ LED7on
LED0on:
LDAA #%00000001
BRA LEDSon
LED1on:
LDAA #%00000011
BRA LEDSon
LED2on:
LDAA #%00000111
BRA LEDSon
LED3on:
LDAA #%00001111
BRA LEDSon
LED4on:

LDAA #%00011111
BRA LEDSon
LED5on:
LDAA #%00111111
BRA LEDSon
LED6on:
LDAA #%01111111
BRA LEDSon
LED7on:
LDAA #%11111111
LEDSon:
OVER_THE_FANCY:
STAA PORTB
PULA
RTS
DoProcessing:
PSHA
LDAA A2Dval
; read A/D value
SUBA frozenVal
; subtract reference value
STAA processedVal
; save it
PULA
RTS
;=========================
; routine to do processing
; inputs: A2Dval, frozenVal
; outputs: processedVal
; registers affected: none
;=========================
DoPushButton:
PSHA
LDAA PORTA
; detect pushed button
ANDA #$01
; pin 0
BNE NotPushed_PB0
; jump if not pushed
LDAA A2Dval
STAA frozenVal
NotPushed_PB0:
PULA
RTS
;=========================
; routine to Initialize variables
; inputs: none
; outputs: A2Dval, frozenVal, processedVal
; registers affected: none
;=========================
Init:
PSHA
LDAA #0
STAA A2Dval
STAA frozenVal
STAA processedVal
PULA
RTS

10. Make and start the debugger. If you run the debugger in Full Chip Simulation, you
must simulate the application of a voltage to the A/D converter. To do this, you
need to enter a debugger command in the command window:
The dedicated commands are ATD0_SETPAD and ATD1_SETPAD. The
command syntax is:
ATDx_SETPAD <ChannelNbr> <Value>
For example, to apply a voltage of 0.125 V on ATD0 channel 0, enter the
command:
ATD0_SETPAD 0 0.125
If you need to use push buttons connected to the input of a parallel port, you must
simulate the application of voltages to the parallel port. To so this start the
visualization tool from the debugger (Component/Open/Visualization Tool) and
configure the properties of a switch or DILswitch to control Port A, if the push
button is connected to Port A

Address:
PortA: 0x00
PortB: 0x01

Please keep in mind that when the code will run on the actual hardware, the pin
voltage connected to a push button will be 0V if the button is pushed, and 5V
(logic 1) if the button is not pushed. Therefore, in Full Chip Simulation, a switch
must be in the upper position (1) to simulate a push button which is NOT pushed.

Make sure you save your Visualization Tool window (this window will get
automatically closed each time the debugger is closed, or new code is being
compiled; you will lose this window unless you save it). Make sure you set the
Visualization Tool refresh mode to Periodical (right click within the Visualization
Tool window, Properties, Refresh Mode).
11. When downloading code into the Project Board, make sure the CSM12D module
is connected to the Project Board, and that the Project Board is plugged into the
USB port.
Start the debugger and use Component/Set Connection to switch from FCS (Full
Chip Simulation) to P&E hardware debugging. You will have to close the
debugger and restart it from CodeWarrior, to be able to run your software.
12. Click on the green tilted arrow Debug on the project window to start debugging.
Make sure you are applying a voltage to the pin of the A/D converter 0, channel 0.
Check document StudentLearningKit_UserGuide_APS12DT256SLKUG.pdf to
determine the location of the pin on the J1 connector of the SLK board. You must
connect this pin with a wire to pin POT of the User IO connector on the
prototyping board. This pin is controlled by a potentiometer on the board, and the
voltage on pin POT can be varied from 0V to 5V.

PartB:

In this part you will write and download C language code into the CSM12D board. This
experiment helps you understand how to perform the Analog to Digital conversion in a
multitasking scheme within the HCS12.

For the first part of the lab you do NOT need the Freescale board. You will use the
CodeWarrior Simulator.

Create a new C-code project using the following steps:


1. Start up the CodeWarrior IDE on one of the lab machines by clicking on the
desktop shortcut.
2. A new window will pop up, choose Create New Project

3. Choose MC9S12DT256B, from HCS12D Family and select Full Chip Simulation.
Click Next

4. Check the box for C-Programming.

5. Name the project Lab3 and choose a location where the files will be saved. Click
Next


6. Do NOT add any existing file to the project. Click Next

7. Select Processor Expert. Click Next

8. Select minimal startup code, Banked memory and None floating point option.
Click Next.

9. Choose No for PC-lint as we have no plugin to use in our project. Click Next.

10. After Processor Expert loads select MC9S12DT256CPV. And click OK

11. Select the Processor Expert tab and right click on the Components and choose
Add Components from the menu.
12. Click on Alphabet to expand the branch and then select all the components you
require:

You will need two ByteIO ports; one to connect the Push Buttons and one to
connect the LEDs. You will also need an A/D Converter, so click on Converter to
add an A/D.

13. Initialize the A/D with appropriate conversion time (20 sec).


14. Go to the properties tab and adjust the direction (Input/Output) of each port
accordingly. Also set up PBs to Port A and LEDs to Port B

15. Add the TimerInt component and initialize the interrupt period to 100ms.
16. Edit the Events.c and main function files, add your code. Your code may need to
be similar to the one below, but not necessarily identical. Add your code to turn on
the appropriate LEDs based on the A/D value.

Main Function

/** ###################################################################
**
Filename : Lab5.c
**
Project
: Lab5
**
Processor : MC9S12DT256BCPV
**
Version
: Driver 01.14
**
Compiler : CodeWarrior HC12 C Compiler
**
Date/Time : 27/06/2013, 12:43 PM
**
Abstract :
**
Main module.
**
This module contains user's application code.
**
Settings :
**
Contents :
**
No public methods
**
** ###################################################################*/
/* MODULE Lab5 */
/* Including used modules for compiling procedure */
#include "Cpu.h"
#include "Events.h"
#include "PBs.h"
#include "Timer.h"
#include "LEDs.h"
#include "A2D.h"
#include "Timer.h"
#include "PBs.h"
/* Include shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
void InitTask(void);
void DoMainLoop(void);
void Delay(void)
{
int i;
for (i=0;i<100;i++) {
}
}
void main(void)
{
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
A2D_Start();
Delay(); // wait a bit to make sure the A2D converter has started
for(;;){
DoMainLoop();
}
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
/* END Lab5 */

/*
** ###################################################################
**
**
This file was created by Processor Expert 3.02 [04.44]
**
for the Freescale HCS12 series of microcontrollers.
**
** ###################################################################
*/*/

Events.c
/** ###################################################################
**
Filename : Events.c
**
Project
: Lab5
**
Processor : MC9S12DT256BCPV
**
Component : Events
**
Version
: Driver 01.04
**
Compiler : CodeWarrior HC12 C Compiler
**
Date/Time : 27/06/2013, 12:43 PM
**
Abstract :
**
This is user's event module.
**
Put your event handler code here.
**
Settings :
**
Contents :
**
Timer_OnInterrupt - void Timer_OnInterrupt(void);
**
A2D_OnEnd
- void A2D_OnEnd(void);
**
** ###################################################################*/
/* MODULE Events */
#include "Cpu.h"
#include "Events.h"
int timer;
byte A2Dresult;
byte processingResult;
byte refA2Dvalue;
#pragma CODE_SEG DEFAULT
//
// Called from Main
// make a copy of the A/D value
//
void DoA2DFreeze(void) {
refA2Dvalue = A2Dresult;
}
//
// Called by Task1
// Refresh display
//
void UpdateLEDS(void) {
LEDs_PutVal(processingResult);
}
//
// Called by Task2
// Compute variable processingResult
//
void DoProcessing(void)
{
processingResult = A2Dresult - refA2Dvalue;

/*
processingResult = processingResult &0xE0; // keep only most significant 3 bits
switch (processingResult)
{
case 0x00:
processingResult = 0x01;
break;
case 0x20:
processingResult = 0x02;
break;
case 0x40:
processingResult = 0x04;
break;
case 0x60:
processingResult = 0x08;
break;
case 0x80:
processingResult = 0x10;
break;
case 0xA0:
processingResult = 0x20;
break;
case 0xC0:
processingResult = 0x40;
break;
case 0xE0:
processingResult = 0x80;
break;
}
*/
}
//
// Called by Task3
// If push button connected to PortA 0 is pushed, make a copy of the A/D value
//
void DoPushButton(void)
{
if (PBs_GetVal() == 0) {
refA2Dvalue = A2Dresult;
}
}
void DoMainLoop(void)
{
if (timer == 3){
UpdateLEDS();
}
if (timer == 5) {
DoProcessing();
}
if (timer == 7) {
DoPushButton();
}
if (timer >= 10) {
timer=0;
}
}

/*
** ===================================================================
** Event : Timer_OnInterrupt (module Events)
**
** From bean : Timer [TimerInt]
** Description :
** When a timer interrupt occurs this event is called (only
** when the bean is enabled - "Enable" and the events are
** enabled - "EnableEvent").
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void Timer_OnInterrupt(void)
{
/* Write your code here ... */
timer ++;
}
/*
** ===================================================================
** Event : A2D_OnEnd (module Events)
**
** From bean : A2D [ADC]
** Description :
** This event is called after the measurement (which
** consists of <1 or more conversions>) is/are finished.
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
void A2D_OnEnd(void)
{
byte status;
/* Write your code here ... */
/* after each A/D conversion, copy the result in an application variable, A2Dresult */
status = A2D_GetValue8(&A2Dresult);
}
/* END Events */
/*
** ###################################################################
**
**
This file was created by Processor Expert 3.02 [04.44]
**
for the Freescale HCS12 series of microcontrollers.
**
** ###################################################################
*/

17. Make and start the debugger. If you run the debugger in Full Chip Simulation, you
must simulate the application of a voltage to the A/D converter. To do this, you
need to enter a debugger command in the command window:
The dedicated commands are ATD0_SETPAD and ATD1_SETPAD. The
command syntax is:
ATDx_SETPAD <ChannelNbr> <Value>
For example, to apply a voltage of 0.125 V on ATD0 channel 0, enter the
command:
ATD0_SETPAD 0 0.125

Warning: If your simulation is not working you may need to make the
following change:
In PROCESSOR EXPERT double click on TIMERINT component and in
PROPERTIES tab, change the PERIODIC INTERRUPT SOURCE from
I TCO to MODULUSCOMP
f
you need to use push buttons connected to the input of a parallel port, you must
simulate the application of voltages to the parallel port. To so this start the

Address:
PortA: 0x00
PortB: 0x01

visualization tool from the debugger (Component/Open/Visualization Tool) and


configure the properties of a switch or DILswitch to control Port A, if the push
button is connected to Port A
Please keep in mind that when the code will run on the actual hardware, the pin
voltage connected to a push button will be 0V if the button is pushed, and 5V

(logic 1) if the button is not pushed. Therefore, in Full Chip Simulation, a switch
must be in the upper position (1) to simulate a push button which is NOT pushed.
Make sure you save your Visualization Tool window (this window will get
automatically closed each time the debugger is closed, or new code is being
compiled; you will lose this window unless you save it). Make sure you set the
Visualization Tool refresh mode to Periodical (right click within the Visualization
Tool window, Properties, Refresh Mode).
18. When downloading code into the Project Board, make sure the CSM12D module
is connected to the Project Board, and that the Project Board is plugged into the
USB port.
Start the debugger and use Component/Set Connection to switch from FCS (Full
Chip Simulation) to P&E hardware debugging. You will have to close the
debugger and restart it from CodeWarrior, to be able to run your software.
19. Click on the green tilted arrow Debug on the project window to start debugging.
Make sure you are applying a voltage to the pin of the A/D converter 0, channel 0.
Check document StudentLearningKit_UserGuide_APS12DT256SLKUG.pdf to
determine the location of the pin on the J1 connector of the SLK board. You must
connect this pin with a wire to pin POT of the User IO connector on the
prototyping board. This pin is controlled by a potentiometer on the board, and the
voltage on pin POT can be varied from 0V to 5V.

Lab Report
1. Describe the ways you have tested your application and any problems you encountered.
2. Save your project as a reference to your lab activity.
3. Submit your lab report and all the source files you have edited (Assembly files, the main
C file, Events.c, ASM files, etc.) as well as relevant screen shots which would have
pasted in your lab report.

You might also like