Digital timer using HCS08 MC09S08GB60

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Digital timer using HCS08 MC09S08GB60

1,713 Views
karmabobby
Contributor I
 
Hi, thanks to allawtterb and bigmac who helped me get my last program working correctly. Now I need some more advice. For another program I want to use the last program and modify it for a digital display timer. I have come up the general form of the program but I am confused of how to approach this. Here is my current code.
Code:
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#define MASK_BITS1 0xF00 //Masks bits 11-8 on#define MASK_BITS2 0x0F0 //Masks bits 7-4 on#define MASK_BITS3 0x00F //Masks bits 3-0 on  #define DIGIT_PORT  PTFD     //Port F used for digits//#define DIGIT_MASK  0xF0     //Used to mask bits 7,6 and 5 in Port F//#define SEG_PORT    PTBD       // Port B used for segments //#define SEG_MASK    0x7F       //Used to mask Port B for correct output//#define LED_DISPLAY PTAD_PTAD2#define Mask_Digits 0x03     //used to mask variable digits to 00000011#define SEVEN_SEG_0 0x3F     //digits 0 through 9 in display form#define SEVEN_SEG_1 0x06#define SEVEN_SEG_2 0x5B#define SEVEN_SEG_3 0x4F#define SEVEN_SEG_4 0x66#define SEVEN_SEG_5 0x6D#define SEVEN_SEG_6 0x7D#define SEVEN_SEG_7 0x07#define SEVEN_SEG_8 0x7F#define SEVEN_SEG_9 0x6F// Function Prototypes //void delay(long int);void Output_Seven_Segments(byte, byte);void main(void);int FixDigit2(int);EnableInterrupts; /* enable interrupts */  /* include your code here */   void delay(long int n){ long int i; unsigned int j; for (i=0; i<n; i++)   for (j=0; j<100; j++)     {}}  void Output_Seven_Segments (byte segments, byte digit){   //Remember: segments variable is formed as: //        DP g f e d c b a      digit &= Mask_Digits; //Mask variable digit to '00000011'       if (digit==0)   //This is the broken display     segments=FixDigit2(segments); //Call a subroutine to mangle all bits   DIGIT_PORT &= ~DIGIT_MASK;  // Set all digits OFF //      SEG_PORT = segments & SEG_MASK;  //Port B assigned vairable segments      DIGIT_PORT |= (0x10 << digit);       switch (digit)  {  case 0:                     DIGIT_PORT = 0x80;//Drive most significant digit on           break;  case 1:            DIGIT_PORT = 0x40;//Drive second digit on    break;  case 2:           DIGIT_PORT = 0x20;//Drive least significant digit on          break;   case 3:           LED_DISPLAY = 1;//Drive LED display on      break; }void main (void){  // Set DDRs for output ports   SOPT_COPE = 0;//Disable watchdog timer   PTADD = 0x02; // Replace XX with the hex value to set the PA2 and PA1 as outputs      PTFDD = 0xE0; // Same here, setting the inputs/outputs for port F   PTBDD = 0x7F; // Setting the input/outputs for Port B    time=0;  for (;;)  //Loop forever (as always!) {  time++; //increment variable time by one    //Convert to Segments and Output bits (11:8) of time  delay(1);  //Convert to Segments and Output bits (7:4) of time  delay(1);  //Convert ...  bits (3:0) of time  delay(1); }} int FixDigit2(int value) {    unsigned char newval;  newval=0;    newval=newval|(value&0x01)<<6;   //Bit 0 becomes 6  newval=newval|(value&0x02)>>1;   //Bit 1 becomes 0  newval=newval|(value&0x04)<<5;  //Bit 2 becomes 7  newval=newval|(value&0x40)>>4;  //Bit 6 becomes 2  newval=newval|(value&0x80)>>6;  //Bit 7 becomes 1  newval=newval|(value&0x38);    //And bits 543 are copied undisturbed    return (newval);}

 
I need to get the variable time which is an unsigned int. I then need to mask bits 11-8 off then convert it into the digital display form and display it on the board.
 
This will be the same for the other 2 digits but with bits 7-4 and bits 3-0 respectively.
 
I will need another delay routine for the incrementation of varaible time to get it to count every mili second. What is the best way to do this? Would a case statement be Ideal?
 
The part I get confused it after I mask the 12 bits into 3 seperate nibbles by ANDING them with the variables.
 
#define MASK_BITS1 0xF00 //Masks bits 11-8 on
#define MASK_BITS2 0x0F0 //Masks bits 7-4 on
#define MASK_BITS3 0x00F //Masks bits 3-0 on 

 
bits      11        10       9       8        7       6       5       4         3       2       1       0
 
value  2048   1024   512   256   128     64     32      16       8       4       2        1
             X         X        X       X       0       0        0        0        0       0       0       0             after applying MASK_BITS1
             0         0        0        0       X       X        X       X        0       0       0       0             after applying MASK_BITS2
             0         0        0        0       0       0         0       0        X       X       X      X             after applying MASK_BITS3
 
 What I want to do is to have the nibbles placed into a 10 way switch for assigning the digital output for digits 0-9. How do I go about this? Im really confused mainly because I'm a novice when it comes to C but I am getting better all the time. Any help would be greatly appreciated.


Message Edited by karmabobby on 2008-04-04 06:04 PM

Message Edited by karmabobby on 2008-04-04 06:05 PM
Labels (1)
0 Kudos
4 Replies

413 Views
karmabobby
Contributor I
Code:
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#define MASK_BITS1 0xF00 //Masks bits 11-8 on#define MASK_BITS2 0x0F0 //Masks bits 7-4 on#define MASK_BITS3 0x00F //Masks bits 3-0 on #define MASK_NIBBLE 0x0F // Masks buts 7-4 off #define DIGIT_PORT  PTFD     //Port F used for digits//#define DIGIT_MASK  0xF0     //Used to mask bits 7,6 and 5 in Port F//#define SEG_PORT    PTBD       // Port B used for segments //#define SEG_MASK    0x7F       //Used to mask Port B for correct output//#define Mask_Digits 0x03     //used to mask variable digits to 00000011// Function Prototypes //unsigned char NibbleToSegments(unsigned char);void delay(long int);void Output_Seven_Segments(unsigned char, unsigned char);void main(void);unsigned char NibbleToSegments (unsigned char nibble){  const byte Segment_Lookup[16] =   // Lookup table for hex numbers to segments on{    63,6,91,79,102,109,125,7,127,103,119,124,57,94,121,113}; nibble&=MASK_NIBBLE;  return Segment_Lookup[nibble];}   void delay(long int n){ long int i; unsigned int j; for (i=0; i<n; i++)   for (j=0; j<1000; j++)     {}}  void Output_Seven_Segments (unsigned char segments ,unsigned char digit){ //Remember: segments variable is formed as: //        DP g f e d c b a      digit &= Mask_Digits; //Mask variable digit to '00000011'      DIGIT_PORT &= ~DIGIT_MASK;  // Set all digits OFF //      SEG_PORT = segments & SEG_MASK;  //Port B assigned vairable segments      DIGIT_PORT = (0x80 >> digit);        // Turn on the proper digit}void main (void){   unsigned char segment;    unsigned int time;     EnableInterrupts; /* enable interrupts */  // Set DDRs for output ports   SOPT_COPE = 0;//Disable watchdog timer   PTADD = 0x02; // Replace XX with the hex value to set the PA2 and PA1 as outputs      PTFDD = 0xE0; // Same here, setting the inputs/outputs for port F   PTBDD = 0xFF; // Setting the input/outputs for Port B          time=0;        for (;;)  //Loop forever (as always!) {   time++;     segment=(time&MASK_BITS1);    NibbleToSegments(segment);    Output_Seven_Segments(segment,0);  //Convert to Segments and Output bits (11:8) of time  delay(1);        segment=(time&MASK_BITS2);    NibbleToSegments(segment);     Output_Seven_Segments(segment,1);  //Convert to Segments and Output bits (7:4) of time  delay(1);   segment=(time&MASK_BITS3);  NibbleToSegments(segment);    Output_Seven_Segments(segment,2);  //Convert ...  bits (3:0) of time  delay(1); }}

 
Hi, I didn't really understand how to implement your code so I tried something else. Its almost working! However its still just showing as a binary counter on the segment display, instead of picking the values from the lookup table(which is correct it was given to me). Any suggestions?!
0 Kudos

413 Views
allawtterb
Contributor IV
First of all, it seems like you are doing some unnecessary things in your code. 
 
You are setting DIGIT_PORT 3 times in a row, this only needs to be done once.  There is no need to turn off the digits then turn on digits.  Just turning on is fine.  You then have 2 methods for turning digits, a switch and a shifting method.  I would get rid of the switch and just use the shifting method but change how you are doing it.  The OR with itself seems like it is not needed and the shifting method is broken.  I would change it to:
 
Code:
if (digit == 0x03)   // If the LED display is to be used{   LED_DISPLAY = 1;  // Enable the LED display   DIGIT_PORT = 0x00; // Make sure the 7-segment displays are disabled}else                 // Otherwise, use a 7-segment display{   LED_DISPLAY = 0;  // Ensure the LED display is off   DIGIT_PORT = (0x80 >> digit);        // Turn on the proper digit}
 
 
It seems like you want to do 2 different things, one being display a 3 digit hex value on your 3 seven segment displays and two being create some sort of or counter.  I don't exactly understand what you are trying to do with counting miliseconds, do you have to do something after you reach the count? Update the display? 
 
You have 10 defines of the format SEVEN_SEG_# where '#' appears to the number that should be displayed.  If you want to display hex you need A-F as well.  B will be a problem, perhaps you can put it in lower case as otherwise it looks just like 8.   I would suggest you use a look up table to go from 0-F to turning on the proper segments.   
0 Kudos

413 Views
karmabobby
Contributor I
I am trying to develop a reaction timer to show how long a button was depressed by the user. The coding inconsitancies came about when combining bigmac's and my existing code together I will sort that out.
 
What I am wanting to do is to count in milliseconds how long PTA0 which is a push button has been pressed, eventually that is. I thought getting the counter/timer working correctly first would be the best approach as the "reaction timer" is simply a switch or an if, I would go with a switch for it.
 
What would be the best way to extract the 3 nibbles and convert the three into the hexadecimal seven segment display form? The source code I have posted is a slightly altered version of what I had with the seven segment display. Its just my way of trying to get across what I am trying to do.
 
 
0 Kudos

413 Views
allawtterb
Contributor IV


karmabobby wrote:
What would be the best way to extract the 3 nibbles and convert the three into the hexadecimal seven segment display form? The source code I have posted is a slightly altered version of what I had with the seven segment display. Its just my way of trying to get across what I am trying to do.

I would mask the value, use a lookup table then shift it to get the seven segment value,  something like this:
 
Code:
...
const byte Segment_Lookup[16] =   // Lookup table for hex numbers to segments on{   SEVEN_SEG_0, SEVEN_SEG_1, SEVEN_SEG_2, SEVEN_SEG_3,    SEVEN_SEG_4, SEVEN_SEG_5, SEVEN_SEG_6, SEVEN_SEG_7,    SEVEN_SEG_8, SEVEN_SEG_9, SEVEN_SEG_A, SEVEN_SEG_B,   SEVEN_SEG_C, SEVEN_SEG_D, SEVEN_SEG_E, SEVEN_SEG_F};...byte segment;   // Value to update the seven segment display withbyte i;         // Counter in for loopword value;     // Value you are wanting to convert and displayfor (i=0;i<3;i++){   segment = Segment_Lookup[((byte)value & 0x0F)]; // Mask value and find segment value in lookup table   Output_Seven_Segments(segment,i);               // Display on the digit   value >>= 4;                                    // shift for next nibble}
...

 You can add a delay at the end of the for loop if you want one inbetween displays.

 
Edit: Typo in code


Message Edited by allawtterb on 2008-04-04 03:59 PM
0 Kudos