Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

// LAB B 340 wk5 // Freescale MC9s12g128 ATD using analog temp sensor input // u

ID: 3814115 • Letter: #

Question

// LAB B 340 wk5
// Freescale MC9s12g128 ATD using analog temp sensor input
// using LCD dispaly for readout of temperature in Celsius
// *** pax 4/1/2017 Code Warrior IDE ver 5.9.0 build 5294 ***
// 1. place your name on LCD by modifying line 3 of LCD
// 2. take picture of LCD display showing temperature without touching sensor.
// 3. then place finger, breathe, place a cold drink on sensor and take another picture
// with description of how you changed temperature readout value.

#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <stdio.h>

void initLCD(void);
void initPorts(void);
void cmdwrt(unsigned char);
void datawrt(char);
void delay1u(void);
void delay100u(void);
void delay2m(void);
void delays(int);
void LCDputs(char *);
void position(int, int);
void init_ATD(void);

//globals - 4-bit initialization sequence for LCD - data: PC7,6,5,4 E: PC2 , RS: PC0
const unsigned char cInit_commands[20] = {0x30,0x30,0x30,0x20,0x20,0x90,0x10,0x50,0x70,0x80,0x50,0xE0,
0x60,0xA0,0x00,0xE0,0x00,0x10,0x00,0x60};

const unsigned char cE = 0x04; // PC2
const unsigned char cRS = 0x01; // PC0


void main(void)
{
char xyz[3];
unsigned int SensorTemp, Temp;

initPorts( ); // port initializations
initLCD( ); // LCD inititialization
init_ATD();


cmdwrt(0x00); // disable the cursor
cmdwrt(0xC0);


for(;;)
{
  
ATDCTL5 = 0x01; // start a new conversion  
   while(!(ATDSTAT0_SCF)) // wait for conversion to complete
       ;;
      
       SensorTemp = ATDDR0 ; //read ATD1 data and store result to variable
   Temp = ((SensorTemp * 125) /256) - 50; //convert voltage to temperature value
  
   ATDSTAT0_SCF = 1; // clear conv seq complete flag

(void)sprintf(xyz,"%2d",Temp);
position(1,0);
LCDputs(xyz);
LCDputs(" Degree C.");
position(2,0);
LCDputs("340 ATD Prof Pax");
position(3,0);
LCDputs("DeVryENGineering");
delays(500);   
}
}


// initialize ATD converter
void init_ATD()
{
ATDCTL1_SRES = 1; //10-bit results  
ATDCTL3_DJM = 1; //right justified data
ATDCTL3_S8C = 0; //one conversion per sequence
ATDCTL3_S4C = 0; //one conversion per sequence
ATDCTL3_S2C = 0; //one conversion per sequence
ATDCTL3_S1C = 1; //one conversion per sequence
ATDCTL4_PRS = 5; //bus clk div 24, = ATD clock ---this should be between 500k & 2MHz!!!
// formula is 6.25MHz/(2(1+ATDCTL4_PRS)), see figure 13-8 in text
// [ATDCTL4_PRS=11; note original lab uses bus clk div 24, = ATD clock freq, 6.25MHz/2(PRS+1)=260kHz TOO LOW!!!]
// CHANGE so that fATDCLK = 500kHz-2MHz range, ATDCTL4_PRS=1; 6.25MHz/2(1+1)=1.56MHz VALID!!!
// ATDCTL4_PRS=5; 6.25MHz/2(5+1)=520kHz VALID!!! Try setting this register to 1 & then 5 and see how sensor behaves.
// ref page 440-1 ”A/D Conversion Frequency” in textbook.

ATDCTL4_SMP = 4; //12 ATD clock cycle to sample
// 12 ATD clock cycle to sample PHASE 1:2 CYCLES, PHASE 2: 12 CYCLES, PHASE 3: 8 CYCLES
// = 22 CYCLES total(1/1.56MHz) = 14.7us & 22 CYCLES(1/520kHz) = 42.3us
// ref page 442 ”Calculating Conversion Time” in textbook. And Freescale User Manual
// Try setting this register to 7 for phase 2 cycles = 24 (the slowest) phase 1+2+3 = 2+24+8=34 34(1/520kHz)= 65.4us

ATDSTAT0_SCF = 1;   //clear flag
ATDCTL5_MULT = 0; //sample doesn't across multiple channels   
ATDCTL5_CA = 1; // select channel 0 as first conversion
}

void position(int iRow_value, int iCol_value)
{
int iPos_h, iPos_l, iValue;

if(iRow_value == 1)
iValue = (0x80+0x00);

if(iRow_value == 2)
iValue = (0x80+0x10);

if(iRow_value == 3)
iValue = (0x80+0x20);

iPos_h = ((iValue + iCol_value) & 0xF0);
iPos_l = ((iValue + iCol_value) & 0x0F) << 4;

cmdwrt(iPos_h);
cmdwrt(iPos_l);
}
  
//Sends a string of characters to the LCD;...
void LCDputs(char *sptr)
{
while(*sptr)
{ //...the string must end in a 0x00 (null character)
datawrt(*sptr); // sptr is a pointer to the characters in the string
++sptr;
}
}
  
// sends initialization commands one-by-one
void initLCD( )
{
unsigned char i;
  
for (i=0;i<20;i++)
{
cmdwrt(cInit_commands[i]);
}
}


void initPorts( )
{
unsigned char cValue;
  
DDRB = 0x80; //LCD CSB active low
DDRC = 0xFF; // PC7-PC4 - 4-bit LCD data bus, PC2 - E, PC1 - R/W~, PC0 - RS: all outputs
cValue = PORTB;
PORTB = (cValue & ~0x80); // LCD CSB (PORT B7) enabled with a logic low
DDRP = 0x01;
PTP |= 0x01;
}
  

// sends a control word to LCD bus
void cmdwrt(unsigned char cCtrlword)
{
PORTC = cCtrlword; // output command onto LCD data pins
PORTC = cCtrlword + cE; // generate enable pulse to latch it (xxxx x100)
  
delay1u( ); // hold it for 1us
  
PORTC = cCtrlword; // end enable pulse (xxxx x000)
  
delay2m(); // allow 2ms to latch command inside LCD
  
PORTC = 0x00;
  
delay2m(); // allow 2ms to latch command inside LCD
}

// sends the character passed in by caller to LCD
void datawrt(char cAscii)
{   
char cAscii_high, cAscii_low;
  
cAscii_high = (cAscii & 0xF0);
cAscii_low = (cAscii & 0x0F) << 4; // Shift left by 4 bits
PORTC = cAscii_high; // output ASCII character upper nibble onto LCD data pins
PORTC = cAscii_high + cRS + cE; // generate enable pulse to latch it (0xxx x101)
  
delay1u( ); // hold it for 1us
  
PORTC = cAscii_high + cRS; // end enable pulse (0xxx x001)
  
delay1u( ); // hold it for 1us
  
PORTC = cAscii_low; // output ASCII character lower nibble onto LCD data pins
PORTC = cAscii_low + cRS + cE; // generate enable pulse to latch it (0xxx x101)
  
delay1u( ); // hold it for 1us
  
PORTC = cAscii_low + cRS; // end enable pulse (0xxx x001)
  
delay100u( ); // allow 100us to latch data inside LCD
}


void delay1u( )
{
unsigned int i;
  
for(i=0;i<=0x0f;i++)
{ /* adjust condition field for delay time */
asm("nop");
}
}

void delay100u( )
{
unsigned int i,j;
  
for(i=0;i<=0x02;i++)
{ /* adjust condition field for delay time */
for(j=0;j<=0xff;j++)
{
asm("nop");
}
}
}

void delay2m( )
{
unsigned int i,j;

for (i=0;i<=0x20;i++)
{ /* adjust condition field for delay time */
for (j=0;j<=0xff;j++)
{
asm("nop");
}   
}
}   


void delays(int k )
{
unsigned int i,j;

for (i=0;i<=k;i++)
{ /* adjust condition field for delay time */
for (j=0;j<=0xff;j++)
{
asm("nop");
}   
}
}   
  

1. What SFRs commands are utilized for the configuration of the ADC? How does each affect the operation of the ADC?

Explanation / Answer

LCD_DATA = LCD_DATA | x;MSDelay(1);LCD_CTRL = LCD_CTRL | RS;MSDelay(1);LCD_CTRL = LCD_CTRL | EN;MSDelay(1);LCD_CTRL = LCD_CTRL & ~EN;MSDelay(15);x = (data & 0x0F);x= x<<4;LCD_DATA = LCD_DATA & 0x0F;//clear PC7-PC4 pins before you send it anythingLCD_DATA = LCD_DATA | x;LCD_CTRL = LCD_CTRL | EN;MSDelay(1);LCD_CTRL = LCD_CTRL & ~EN;MSDelay(15);}void MSDelay(unsigned int itime){for(i=0;i<itime;i++)for(j=0;j<1000;j++);}Course Number: ECET-340Laboratory Number: 5Page8of11