Example #1
0
void main(void) {
    long op1, op2;   //32-bit operands
    char* ptr;       //pointer to keypad buffer
    char* blanks;
    char kbuf[12];   //keypad buffer
    char c, a;
    int i;
    ptr = kbuf;
    blanks = "      ";


    PLL_init();           //set system clock freq to 24MHz
    lcd_init();         //enable lcd
    keypad_enable();    //enable keypad
    set_lcd_addr(0x00); //display on 1st line
    i = 0;
    while(1) {
        c = getkey();     //read keypad
        a = hex2asc(c);   //convert to ascii
        kbuf[i] = a;      // and store in kbuf
        if(c<10) {        //if 0 - 9
            data8(a);      //   display on lcd
            wait_keyup();  //   wait to release key
            i++;           //increment index
        } else {
            switch(c) {
            case 0xE:   //if enter (*) key
                op1 = number(ptr);  //convert to binary
                set_lcd_addr(0x40); //display on 2nd line
                write_long_lcd(op1);
                set_lcd_addr(0x00); //clear 1st line
                type_lcd(blanks);
                wait_keyup();      //wait to release key
                i = 0;             //reset kbuf index
                set_lcd_addr(0x00); //display on 2nd line
                break;

            case 0xA:   //if key A
                op2 = number(ptr);  //convert to binary
                op1 = op1 + op2;    //compete sum
                set_lcd_addr(0x40); //display on 2nd line
                write_long_lcd(op1);
                set_lcd_addr(0x00);  //clear 1st line
                type_lcd(blanks);
                wait_keyup();        //wait to release key
                i = 0;               //reset kbuf index
                set_lcd_addr(0x00);  //display on 1st line
                break;
            case 0xF:   //if clear (#) key
                clear_lcd();  //clear lcd display
                wait_keyup(); //wait to release key
                i = 0;        //reset kbuf index
                break;
            default:
                break;
            }
        }
    }
}
Example #2
0
const char* LcdI2c::print(const char *string){

    const char *c = string;
    while(*c)
        data8(*c++);
    //++ because we point to nex valid data and must skip \0 char   
    return (++c); 
}
Example #3
0
const char* LcdI2c::print(const char *string, uint8_t size){

   const char *c = string;
   while (size){
       data8(*c++);
       --size;
   }
   return (c);
}
void ComponentEventTest::testConvertSimpleUnits()
{
  std::map<std::string, std::string> attributes;
  attributes["id"] = "1";
  attributes["name"] = "DataItemTest1";
  attributes["type"] = "ACCELERATION";
  attributes["category"] = "SAMPLE";
  
  std::string time("NOW"), value("2.0");
  attributes["nativeUnits"] = "INCH";
  DataItem data1 (attributes);
  ComponentEvent event1 (data1, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 25.4f, event1.getFValue());
  CPPUNIT_ASSERT(event1.getSValue().empty());
  
  attributes["nativeUnits"] = "FOOT";
  DataItem data2 (attributes);
  ComponentEvent event2 (data2, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 304.8f, event2.getFValue());
  CPPUNIT_ASSERT(event2.getSValue().empty());
  
  attributes["nativeUnits"] = "CENTIMETER";
  DataItem data3 (attributes);
  ComponentEvent event3 (data3, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 10.0f, event3.getFValue());
  CPPUNIT_ASSERT(event3.getSValue().empty());
  
  attributes["nativeUnits"] = "DECIMETER";
  DataItem data4 (attributes);
  ComponentEvent event4 (data4, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 100.0f, event4.getFValue());
  CPPUNIT_ASSERT(event4.getSValue().empty());
  
  attributes["nativeUnits"] = "METER";
  DataItem data5 (attributes);
  ComponentEvent event5 (data5, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 1000.0f, event5.getFValue());
  CPPUNIT_ASSERT(event5.getSValue().empty());
  
  attributes["nativeUnits"] = "FAHRENHEIT";
  DataItem data6 (attributes);
  ComponentEvent event6 (data6, 123, "NOW", "2.0");
  CPPUNIT_ASSERT_EQUAL((2.0f - 32.0f) * (5.0f / 9.0f), event6.getFValue());
  CPPUNIT_ASSERT(event6.getSValue().empty());
  
  attributes["nativeUnits"] = "POUND";
  DataItem data7 (attributes);
  ComponentEvent event7 (data7, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 0.45359237f, event7.getFValue());
  CPPUNIT_ASSERT(event7.getSValue().empty());
  
  attributes["nativeUnits"] = "GRAM";
  DataItem data8 (attributes);
  ComponentEvent event8 (data8, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f / 1000.0f, event8.getFValue());
  CPPUNIT_ASSERT(event8.getSValue().empty());
  
  attributes["nativeUnits"] = "RADIAN";
  DataItem data9 (attributes);
  ComponentEvent event9 (data9, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 57.2957795f, event9.getFValue());
  CPPUNIT_ASSERT(event9.getSValue().empty());
  
  attributes["nativeUnits"] = "MINUTE";
  DataItem data10 (attributes);
  ComponentEvent event10 (data10, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 60.0f, event10.getFValue());
  CPPUNIT_ASSERT(event10.getSValue().empty());
  
  attributes["nativeUnits"] = "HOUR";
  DataItem data11 (attributes);
  ComponentEvent event11 (data11, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f * 3600.0f, event11.getFValue());
  CPPUNIT_ASSERT(event11.getSValue().empty());
  
  attributes["nativeUnits"] = "MILLIMETER";
  DataItem data12 (attributes);
  ComponentEvent event12 (data12, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f, event12.getFValue());
  CPPUNIT_ASSERT(event12.getSValue().empty());
  
  attributes["nativeUnits"] = "PERCENT";
  DataItem data13 (attributes);
  ComponentEvent event13 (data13, 123, time, value);
  CPPUNIT_ASSERT_EQUAL(2.0f, event13.getFValue());
  CPPUNIT_ASSERT(event13.getSValue().empty());
}
Example #5
0
void main(void){
                                   
unsigned long int edge1,edge2, edge3, period, duty;
unsigned long int r = 0, q = 0, i, n =0;
unsigned  int k[8] = {0,0,0,0,0,0,0,0};
char *msg1 = "period(ms):";
char *msg2 = "period(us):" ;
char *msg3 = "Duty:" ;
char *percent = "%";
char scale = 0x06;

 
begin:  
  TSCR1 = 0x90;		               //enable timer counter
  TIOS  = 0x00;			             //enable input-capture 0
  TSCR2 = scale;		             //disable TCNT overflow interrupt
  TCTL4 = 0x01;		               //capture rising edge
  TFLG1 = 0x00;		               //clear flags register
  

  while(!(TFLG1 & 0x01)){}		   //wait until rising edge
  edge1 = TC0;				           //save first rising edge
 
                                //decrease prescaler by 1
                                //if count less than value
  if((edge1 < 2000) || (edge1 < 1000)|| (edge1 < 500)|| (edge1 < 200) ||(edge1 < 100) || (edge1 < 50 )){
    if(scale == 0x00){          //if prescaler already 1 skip
      goto skip;
    }     
    scale = scale - 1;          //decrease prescaler by 1
    goto begin;                 //take input again
  }

skip:
  
  TCTL4 = 0x02;		               //caputre falling edge
  while(!(TFLG1 & 0x01)){}		   //wait until falling edge
  edge2 = TC0;				           //save first falling edge


  TCTL4 = 0x01;		               //detect second rising edge
  while(!(TFLG1 & 0x01)){}		   //wait until edge detected
  edge3 = TC0;                   //save value


  period =  edge3 - edge1;       //calculate period
  duty = (edge2 - edge1);        //calculate duty cycle
  duty = duty*100;               //calculate duty cycle
  duty = duty/period;            //calculate duty cycle

  lcd_init ();                   
  if(scale == 0){                //if prescaler is 1
    period = period *1;          //multiply period by scaler
    period = period/24;          //divide by 24 for us
    type_lcd(msg2);
  }
                

  if(scale == 0x01){             //if prescaler is 2
    period = period *2;          //multiply period by scaler
    period = period/24;
    type_lcd(msg2);
  }
                  
  if(scale == 0x02){             //if prescaler is 4
    period = period *4;          //multiply period by scaler
    period = period/24;          //divide by 24 for us
    type_lcd(msg2);
  }
                  
  if(scale == 0x03){             //if prescaler is 8
    period = period *8;          //multiply period by scaler
    period = period/24;          //divide by 24 for us
    type_lcd(msg2);
  }
                  
  if(scale == 0x04){             //if prescaler is 16
    period = period *16;         //multiply period by scaler
    period = period/24;          //divide by 24 for us
    type_lcd(msg2);
  }
                  
  if(scale == 0x05){             //if prescaler is 32
    period = period *32;         //multiply period by scaler
    period = period/24000;       //divide by 24000 for ms
    type_lcd(msg1);
  }
                 
  if(scale == 0x06){             //if prescaler is 64
    period = period *64;         //multiply period by scaler
    period = period/24000;       //divide by 24000 for ms
    type_lcd(msg1);
  }
                   

  do  {                          //convert period from hex to dec
    q = period/10;               
    r = period%10;               
    k[n] =r;                     //store values to be displayed
    period /= 10;                
    n++;                         //increase index
  }while(q != 0);                
                        
                                                   
  while (n != 0 )  {             //display decimal value of period
    k[n-1] = (char)k[n-1];       //convert to char
    k[n-1] = k[n-1]  + 0x30;     //convert to ASCII
    data8(k[n-1]);               //display to LCD
    n--;                         
  }
  
  
  n= 0;                          //reset n
  do  {                          //convert duty from hex to dec
    q = (duty/10);               
    r =(duty%10);                
    k[n] =r;                     //store values to be displayed
    duty /= 10;                   
    n++;                         //Increment index
  }while(q != 0);               
  
  set_lcd_addr(0x40);
  type_lcd(msg3);

                                                    
  while (n != 0 )  {              //display decimal value of duty
    k[n-1] = (char)k[n-1];        //convert to char
    k[n-1] = k[n-1]  + 0X30;      //convert to ASCII
    data8(k[n-1]);                //display to LCD
    n--;                          
  }

  type_lcd(percent);


}
Example #6
0
void TestLpdu::testBuildLpdu()
{

  /* application layer data for r1 */
  uint8_t a1[] = { 0xcd, 0xcc, 0x01, 0x3c, 0x02, 0x06, 0x3c, 0x03,
                         0x06, 0x3c, 0x04, 0x06 };

  /* application layer data for r2 */
  uint8_t a2[] = { 0xc1, 0xe3, 0x81, 0x96, 0x00, 0x02, 0x01, 0x28,
                         0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x28,
                         0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x28,
                         0x01, 0x00, 0x02, 0x00, 0x01, 0x02, 0x01, 0x28,
                         0x01, 0x00, 0x03, 0x00, 0x01, 0x20, 0x02, 0x28,
                         0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20,
                         0x02, 0x28, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
                         0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00,
                         0x00, 0x1e, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00,
                         0x01, 0x00, 0x00, 0x01, 0x00, 0x00 };

  /* these are known good DNP LPDUs */
  uint8_t r0[] = { 0x05, 0x64, 0x05, 0xc0, 0x02, 0x00, 0x01, 0x00,
                         0x9e, 0x59 }; /* header only */

  uint8_t r1[] = { 0x05, 0x64, 0x11, 0xc4, 0x15, 0x00, 0x17, 0x00,
                         0x63, 0x62, 0xcd, 0xcc, 0x01, 0x3c, 0x02, 0x06,
                         0x3c, 0x03, 0x06, 0x3c, 0x04, 0x06, 0x08, 0x9e };
    
  uint8_t r2[] = { 0x05, 0x64, 0x53, 0x73, 0x00, 0x04, 0x01, 0x00,
                         0x03, 0xfc, 0xc1, 0xe3, 0x81, 0x96, 0x00, 0x02,
                         0x01, 0x28, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
                         0x01, 0x28, 0x05, 0x24, 0x01, 0x00, 0x01, 0x00,
                         0x01, 0x02, 0x01, 0x28, 0x01, 0x00, 0x02, 0x00,
                         0x01, 0x02, 0x01, 0x28, 0xb4, 0x77, 0x01, 0x00,
                         0x03, 0x00, 0x01, 0x20, 0x02, 0x28, 0x01, 0x00,
                         0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0xa5, 0x25,
                         0x02, 0x28, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
                         0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00,
                         0x2f, 0xac, 0x00, 0x1e, 0x02, 0x01, 0x00, 0x00,
                         0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
                         0x16, 0xed };


  uint8_t twoLpdus[] = { 0x05, 0x64, 0x08, 0xc4, 0x02, 0x00, 0x2d, 0x00,
                         0xa4, 0x1c, 0xc0, 0xcd, 0x00, 0x23, 0x65, 0x05,
                         0x64, 0x0b, 0xc4, 0x02, 0x00, 0x2d, 0x00, 0xf4,
                         0x8f, 0xc0, 0xce, 0x01, 0x3c, 0x02, 0x06, 0x09,
                         0x7f };

  /* header only - no application data */
  uint8_t r3[] = { 0x05, 0x64, 0x05, 0xc0, 0x01, 0x00, 0x00, 0x04,
                         0xe9, 0x21 };

  /* header only - no application data */
  uint8_t r4[] = { 0x05, 0x64, 0x05, 0x00, 0x00, 0x04, 0x01, 0x00,
                         0x19, 0xa6 };

  uint8_t r5[] = { 0x05, 0x64, 0x0a, 0x44, 0x01, 0x00, 0x02, 0x00,
                   0xfa, 0x4a, 0xc1, 0xe1, 0x81, 0x10, 0x00, 0x6d,
                   0xd5 };

  /* known bad lpdu data */
  uint8_t r10[] ={ 108, 68, 3, 0, 17, 8, 127, 38, 193, 201 };
  uint8_t r11[] ={ 129, 144, 0, 20, 6, 0, 0, 8, 16, 0 };
  uint8_t r12[] ={ 0, 0, 16, 0, 48, 78, 16, 0, 7, 0 };
  uint8_t r13[] ={ 0, 0, 7, 0, 7, 0, 17, 0, 30, 4 };
  uint8_t r14[] ={ 0, 0, 156, 186, 34, 120, 0, 120, 0, 120 };
  uint8_t r15[] ={ 0, 120, 0, 48, 81, 66, 81, 69, 81, 61 };
  uint8_t r16[] ={ 76, 53, 81, 4, 0, 5, 0, 4, 0, 4 };
  uint8_t r20[] ={ 81, 48, 81, 48, 223, 36, 81, 4, 0, 5 };

  enum StatIndex { RX_START_OCTETS = 0,
                   RX_LPDUS,
                   LOST_BYTES,
                   CRC_ERRORS,
                   NUM_STATS };

  Stats::Element statElements[] =
  {
      { RX_START_OCTETS,       "Rx Start Octets",         Stats::NORMAL,0,0},
      { RX_LPDUS,              "Rx Lpdus",                Stats::NORMAL,0,0},
      { LOST_BYTES,            "Lost Bytes",            Stats::ABNORMAL,0,0},
      { CRC_ERRORS,            "CRC Errors",            Stats::ABNORMAL,0,0},
  };

  Stats stats;
  char name[Stats::MAX_USER_NAME_LEN];
  int debugLevel = -1;
  DummyDb db;

  assert(sizeof(statElements)/sizeof(Stats::Element) == NUM_STATS);
  snprintf(name, Stats::MAX_USER_NAME_LEN, "DL TEST");
  stats = Stats( name, 1, &debugLevel, statElements, NUM_STATS, &db);

  Lpdu lpdu = Lpdu( &stats);

  unsigned int i;
  bool lpduFound;

  lpdu.build( 1, 1, 0, 0, 0, 2, 1);
  lpduToArrayCmp( lpdu, r0);

  lpdu.build( 1, 1, 0, 0, 4, 21, 23, TO_BYTES(a1));
  lpduToArrayCmp( lpdu, r1);

  lpdu.build( 0, 1, 1, 1, 3, 1024, 1, TO_BYTES(a2));
  lpduToArrayCmp( lpdu, r2);

  lpdu.reset();
  /* test building from incoming bytes */
  Bytes data1( r5, r5 + 10);
  lpduFound = lpdu.buildFromBytes( data1);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 10);

  Bytes data2( &r5[10], &r5[10] + sizeof(r5) - 10);
  lpduFound = lpdu.buildFromBytes( data2);
  QVERIFY( lpduFound == true);
  QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS)    == 1);
  QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)         == 0);
  QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)         == 0);

  Bytes data3(TO_BYTES(r3));
  lpduFound = lpdu.buildFromBytes( data3);
  QVERIFY( lpduFound == true);

  Bytes data4(TO_BYTES(r4));
  lpduFound = lpdu.buildFromBytes( data4);
  QVERIFY( lpduFound == true);

  /* create 4x a good lpdu */
  Bytes data5(TO_BYTES(r1));
  Bytes data6(data5);
  data6.insert(data6.end(), data5.begin(), data5.end());
  data6.insert(data6.end(), data5.begin(), data5.end());
  data6.insert(data6.end(), data5.begin(), data5.end());

  /* ensure we receive 4 good ones */
  for (i=0; i<4; i++)
  {
    lpdu.reset();
    lpduFound = lpdu.buildFromBytes( data6);
    QVERIFY( lpduFound == true);
    QVERIFY (data6.size() == (sizeof(r1)*(3-i)));
    QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS) == (2+i));
    QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)      == 0);
    QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)      == 0);
  }
 
  /* header only lpdu */
  lpdu.reset();
  Bytes data7(TO_BYTES(r0));
  lpduFound = lpdu.buildFromBytes( data7);
  QVERIFY( lpduFound == true);
  QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS)   == 6);
  QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)        == 0);
  QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)        == 0);

  /* building of two lpdus coming in across two simulated reads */
  /* with the break on the last byte of the last CRC            */
  lpdu.reset();
  Bytes data8(TO_BYTES(twoLpdus));
  Bytes data9;
  data9.push_back(data8.back());
  data8.pop_back();

  lpduFound = lpdu.buildFromBytes( data8);
  QVERIFY( lpduFound == true);
  QVERIFY (lpdu.ab.size() == 15);  /* manually counted */
  QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS)   == 7);
  QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)        == 0);
  QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)        == 0);
  QVERIFY( data8.size() == 17);

  lpdu.reset(); 

  lpduFound = lpdu.buildFromBytes( data8);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 17);
  QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS)   == 8);
  QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)        == 0);
  QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)        == 0);

  lpduFound = lpdu.buildFromBytes( data9);
  QVERIFY( lpduFound == true);
  QVERIFY (lpdu.getStat(Lpdu::RX_START_OCTETS)   == 8);
  QVERIFY (lpdu.getStat(Lpdu::LOST_BYTES)        == 0);
  QVERIFY (lpdu.getStat(Lpdu::CRC_ERRORS)        == 0);

  lpdu.reset();

  /* test known bad cases */
  Bytes data10(TO_BYTES(r10));
  lpduFound = lpdu.buildFromBytes( data10);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data11(TO_BYTES(r11));
  lpduFound = lpdu.buildFromBytes( data11);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data12(TO_BYTES(r12));
  lpduFound = lpdu.buildFromBytes( data12);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data13(TO_BYTES(r13));
  lpduFound = lpdu.buildFromBytes( data13);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data14(TO_BYTES(r14));
  lpduFound = lpdu.buildFromBytes( data14);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data15(TO_BYTES(r15));
  lpduFound = lpdu.buildFromBytes( data15);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data16(TO_BYTES(r16));
  lpduFound = lpdu.buildFromBytes( data16);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);

  lpdu.reset();
  Bytes data20(TO_BYTES(r20));
  lpduFound = lpdu.buildFromBytes( data20);
  QVERIFY( lpduFound == false);
  QVERIFY (lpdu.ab.size() == 0);
}
Example #7
0
void main(){
long int n;
int i; 
float ix = 0.0,duty, period;
char j, scale = 0x06;
char *msg1 = "Period(us):";
char *msg2 = "Duty(%):";
char *msg3 = "Not valid";
char *msg4 = "Displaying...";
char *msg5 = "Go again?";

lcd_init();

type_lcd(msg1);

              
  
n = 0;  
  
getperiod:
    i= getkey1();               		//get key from keypad
    delayms(10);
    
    if(i == 0x0A){              		//if i=A (enter key)
      clear_lcd();                  //clear lcd
      type_lcd(msg2);               //diplay duty message
      delayms(1000);                //diplay message for 1s
      period = n;                   //save period value
      n= 0;                         //reset n to be used for duty
      goto getduty;             		//get duty cycle
    }
    else if (i > 0x0A) {        		//if i not a valid input
      clear_lcd();                  //clear lcd
      type_lcd(msg3);            		//display error message
      delayms(1000);                //display for 1s
      n = 0;                        //reset n
      clear_lcd();
      type_lcd(msg1);
      goto getperiod;               //get period again
    } 
    
    if((n*10+i) > 1360){        		//if n exceeds limit
      clear_lcd();                  //clear lcd
      type_lcd(msg3);            		//display error message
      delayms(1000);                //display for 1s
      n = 0;                        //reset n
      clear_lcd();
      type_lcd(msg1);
      goto getperiod;               //get period again
     }     
    
          
    j= (char)i;                			//turn i into char
    j=j+0x30;                 			//convert hex to ASCII
    data8(j);               			  //display ASCII to LCD

    n = n*10 +i;               			//keep track of decimal value
    goto getperiod;              		//get another key



getduty:
    i= getkey1();               		//get key from keypad
    delayms(10);
    
    if(i == 0x0A){              		//if i=A (enter key)
      clear_lcd();                  //clear lcd
      duty = n;                     //save duty value
      n = 0;                        //reset n
      goto signal;             		  //output signal
    }
    else if (i > 0x0A) {        		//if i not a valid input
      clear_lcd();                  //clear lcd
      type_lcd(msg3);            		//display error message
      delayms(1000);                //display for 1s
      n = 0;                        //reset n
      clear_lcd();
      type_lcd(msg2);
      goto getduty;                 //get duty cycle again
    } 
    
    
    if((n*10+i) > 100){        		  //if n exceeds limit
      clear_lcd();                  //clear lcd
      type_lcd(msg3);            		//display error message
      delayms(1000);                //display for 1s
      n = 0;                        //reset n
      clear_lcd();
      type_lcd(msg2);
      goto getduty;                 //get duty again
     }       
    
    
          
    j= (char)i;                			//turn i into char
    j=j+0x30;                 			//convert hex to ASCII
    data8(j);               			  //display ASCII to LCD

    n = n*10 +i;               			//keep track of decimal value
    goto getduty;              			//get another key

signal:
     
                                    
     
    if(period < 10){
      period= period*24;		          //calculate count
      duty = duty/100;               //calculate duty
      duty = duty*period;
      scale = 0x00;
    }else if(period >680){
      period= period*24;		          //calculate count
     period = period/128;            //calculate count
     duty = duty/100;               //calculate duty
     duty = duty*period;
     scale = 0x07;  
    }else{
     period= period*24;		          //calculate count
     period = period/64;            //calculate count
     duty = duty/100;               //calculate duty
     duty = duty*period;            //calculate duty
     scale = 0x06;
    }
    
    PWMCLK = 0;                     //select clock A as source
    PWMPRCLK = scale;                //set clock A prescaler to 64
    PWMPOL = 1;                     //channel 9 output high at start
    PWMCAE = 0;                     //left-aligned mode
    PWMCTL = 0x0C;                  //8-bit mode, stop in wait and freeze mode
    PWMPER0 = period;               //set period value
    PWMDTY0 = duty;                 //set duty value
    PWME = 0x01;                    //enalbe PWM0 to output signal
  


  while (1){
    type_lcd(msg4);                 //displaying signal
    set_lcd_addr(0x40);
    type_lcd(msg5);                 //ask if want to create new waveform
    
    i= getkey1();               		//get key from keypad
    delayms(10);
    
    if(i == 0x0A){                  //if i=A (enter key)
      clear_lcd();                  //clear lcd
      type_lcd(msg1);               //diplay period message
      delayms(1000);                //diplay message for 1s
      n= 0;                         //reset n 
      goto getperiod;             	//get new period
    
    }else{
      clear_lcd();
    }
    
  
  }                      
}