메뉴 바로가기

서브메뉴 바로가기

본문 바로가기

logo

묻고 답하기
조회 수 12,378 추천 수 0 댓글 12
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 쓰기 목록
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 쓰기 목록
?
  • WhiteAT 2008.01.09 11:53
    이 내용은 제가 앞에서 언급했던 내용인데..... 제 소스를 추가해드릴테니
    참고해서 수정해 보세요.^^.
    지금이라도 전체 구조를 변경하셔야 할듯합니다ㅡㅡ;

     //    250uS 마다 동작하고 4번 동작시 1ms 가 된다.
    // Timer 0 output compare interrupt service routine
    interrupt [TIM0_COMP] void OnTimer0_comp_isr(void)
    {
    
            
            // 256uS X 4 마다 수행
            if(stateKeyInput.uiTimer0)        stateKeyInput.uiTimer0--;
            if(stateLedOut.uiTimer0)        stateLedOut.uiTimer0--;
        TCNT0    =0x00;    //위치 주의// 시간계산이 정확히 1mS로 안되기 때문에..
            if(stateDisplayLCD.uiTimer0)    stateDisplayLCD.uiTimer0--;
    
            if(stateOneSecond.uiTimer0)        stateOneSecond.uiTimer0--;
    
    
            if(stateOperLED.uiTimer0)        stateOperLED.uiTimer0--;
            if(statePIDCOOL.uiTimer0)        statePIDCOOL.uiTimer0--;
            if(statePIDHEAT.uiTimer0)        statePIDHEAT.uiTimer0--;
            if(statePIDHUMI.uiTimer0)        statePIDHUMI.uiTimer0--;
            if(stateFAN.uiTimer0)            stateFAN.uiTimer0--;
    
    
            if(stateMainClock.uiTimer0)        stateMainClock.uiTimer0--;
            if(stateADC.uiTimer0)            stateADC.uiTimer0--;
            if(infoReadTempHumi.uiTimer0)    infoReadTempHumi.uiTimer0--;
        
            if(stateOUT_main.uiTimer0)        stateOUT_main.uiTimer0--;
            if(stateCOMPCheck.uiTimer0)        stateCOMPCheck.uiTimer0--;
            if(stateComp1.uiTimer0)            stateComp1.uiTimer0--;
            if(stateComp2.uiTimer0)            stateComp2.uiTimer0--;
    
    
            if(stateDefrost.uiTimer0)        stateDefrost.uiTimer0--;
            if(stateDrain.uiTimer0)            stateDrain.uiTimer0--;
    
            
            if(stateHEATCheck.uiTimer0)        stateHEATCheck.uiTimer0--;
            if(stateHUMICheck.uiTimer0)        stateHUMICheck.uiTimer0--;
    
            if(stateErrorCheckWaterLeak.uiTimer0)        stateErrorCheckWaterLeak.uiTimer0--;
            if(stateErrorCheckRM.uiTimer0)        stateErrorCheckRM.uiTimer0--;
            if(stateErrorCheckFire.uiTimer0)        stateErrorCheckFire.uiTimer0--;
            
        
    //    }
    }


         while(1) { 
    
            #asm("WDR")
            OperatingOneSecond(&stateOneSecond);
            
              OperatingDisplayLCD();
            OperatingLedOut();
             OperatingRxFromMonitor();
             OperatingPID(&statePIDCOOL);
               OperatingRxFromPC();
            OperatingTxToPC();
    
    
             OperatingLED();
            OperatingADC();
            
        }


     void OperatingOneSecond(struct _FUNC_INFO *structThisState){
        if(structThisState->uiTimer0) return;
        structThisState->uiTimer0=1000;
    
    
    
        // ALARM OUT 
        if (IsSystemError())
        {
            OUTA_ON(OUTA_AL);
        }else{
            OUTA_OFF(OUTA_AL);
    
        }
    }
    






  • 러빙유 2008.01.09 12:13 글쓴이

    그런데요. 제가 궁금한게 있는데요..저같은 경우에는 OperatingADC(); 하면 ADC 를 해가지고 오는데, 약간의 딜레이가 있습니다.

    왜냐하면, 제가 사용하고 있는 16-BIT ADC 같은 경우에는 한번 읽어 올때마다 calibration을 하는 것이 정형화 되어 있어

    calibration 딜레이가 있어 값을 읽어오는 데 약간의 딜레이를 주고 있습니다. 이렇게 되면, fnd, LED 업데이트에 영향이

    있어요..

    참고로 ad7705.c 를 첨부합니다.

    -ad7705.c-----------

    /ad7705 초기화 루틴 while문 이전에 선언initailaization routine
    void adc_init()
    {       //hw reset
            SETBIT(PORTE,5); //Reset ad7705A, B
            delay_ms(1);
     CLEARBIT(PORTE,5);//Set high
     //interface reset
     //Init Clock register
     write_adc_byte_A( 0x20 );//Communications Register set to write of clock register
     write_adc_byte_A( 0x04 );//Clock Register info here
     write_adc_byte_A( 0x21 );//Communications Register set to write of clock register
     write_adc_byte_A( 0x04 );//Clock Register info here
     write_adc_byte_B( 0x20 );//Communications Register set to write of clock register
     write_adc_byte_B( 0x04 );//Clock Register info here
     //Init Setup register
     setup_adc_device_A_ch1();
     setup_adc_device_A_ch2();
     setup_adc_device_B();
            delay_ms(2000);
    }

    //while문안에서 계속 호출하게 될 함수 <---딜레이 필요함.
    unsigned int read_adc_value_A(unsigned int ch)

       unsigned int value;
         
       if(ch==1){
          setup_adc_device_A_ch1();
          delay_ms(2000);
          write_adc_byte_A(0x38);//communications register set to read of data register of channel 1
          delay_ms(2000); }
       else {
          setup_adc_device_A_ch2();
          delay_ms(2000);
          write_adc_byte_A(0x39);//communications register set to read of data register of channel 2
          delay_ms(2000); }
         
       value=read_adc_word_A();
      
       return (value);
    }
     

  • WhiteAT 2008.01.09 12:56
    앗. OperatingOneSecond 대신 다른 함수를 예로 들었어야 했는데... 괜한 것을 올렸네요 ;;


    그런데요. 제가 궁금한게 있는데요..저같은 경우에는 OperatingADC(); 하면 ADC 를 해가지고 오는데, 약간의 딜레이가 있습니다.

    여기서 딜레이라는게  2000mS를 말하는 건가요?
    저럴 경우에는 2000mS를 status를 사용하면 됩니다.

    void OperatingADC1(){ // ch = 1 일경우에만 생각해보면

        struct _FUNC_INFO structThisState;
        structThisState= stateOperLED;

        if(structThisState.uiTimer0) return; // 일정시간이 경과하지 않아서 리턴되는건 아시죠?

        structThisState.uiTimer0=1000; // 이거는 디폴트 값입니다. 

        switch(structThisState.uiState){
            case 0:    // 처음
                setup_adc_device_A_ch1();
                structThisState.uiState=1;  // 다음엔 state가 1일 경우로 가라.
     structThisState.uiTimer0=2000; // 2000mS 이후에 들어 와라. 그 동안에는 다른 일을 해라.

                break;
            case 1:    // B positive
                write_adc_byte_A(0x38);
                structThisState.uiState=0;  // 다음엔 state가 0일 경우로 가라.
     structThisState.uiTimer0=2000; // 2000mS 이후에 들어 와라.   그 동안에는 다른 일을 해라.


                break;
            default: // 혹시라도 잘못되면....
                structThisState.uiTimer0=1;
                structThisState.uiState=0;
                break;
           
        }
        stateOperLED = structThisState;   
    }

  • 러빙유 2008.01.09 13:09

    맞네요. 이제 대충 감이 오네요. 이런 구조와 원리이군요. 오늘 또 집에 늦게 가겠네요..^^'

    정말 감사합니다.

  • 러빙유 2008.01.09 16:21 글쓴이

    주인장님..제안하신 구조로 했는데, 인터럽트 주기 타임이 150us 까지 내려갔습니다.

    기존의 isr에 구현할 때는 2ms면 충분했는데, 150us정도 되어야지 fnd,led가 깜빡이지 않고 들어옵니다.

    첫번째 Disp_operation() 만 while에서 돌릴때는 1ms 만 되어도 잘 들어오느데, 갑자기 SW_operation()

    이 들어가니 150us가지 가야 되고 맙니다.

    맞는 건지...ㅜㅜ

    코드를 첨부합니다.

    #pragma vector = TIMER0_COMP_vect  //1ms interrupt isr
    __interrupt void timer0_compare_isr(void)

    {    
          if(Disp_timer) Disp_timer--; //fnd,led timer
          if(LED_timer) LED_timer--;//LED blink timer
          if(Key_timer) Key_timer--; //key input timer       
    }

    void Disp_operation(void) {
     
      if(Disp_timer>0) return;
     
      Disp_timer =1;
     
          DIGM = 1<<icounter;
            ////////////////////////////
            if(icounter == 3){
              if(blink_flag >0 && blink_flag < 9){
                  if(LED_timer>0) return;
                 
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_one = Led_one & ~(1<<(blink_flag-1));//ON  
                    SEGM = Led_one;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_one = Led_one | (1<<(blink_flag-1));//OFF
                    SEGM = Led_one;}               
              }
              else {
                SEGM = Led_one; }
            }
            ////////////////////////////// 
            else if(icounter == 7){
              if(blink_flag >8){
                  if(LED_timer>0) return;
                 
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_two = Led_two & ~(1<<(blink_flag-9));//ON  
                    SEGM = Led_two;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_two = Led_two | (1<<(blink_flag-9));//OFF
                    SEGM = Led_two;}               
              }
              else {
                SEGM = Led_two; }
            }
            ////////////////////////////////
            else{SEGM =fnd_data[icounter];}
       ++icounter;
       if(icounter ==8) icounter=0;
    }   

    void SW_operation(void) {
      if(Key_timer>0) return;
     
      Key_timer =1;
      key = KEYM;
     
           if(key&0xff == 0xff){
              if(key_flag==0) return;
                 else{
                    if(++key_counter==4){
                        key_flag=0;
                        key_counter=0;
                        return;
                     }
                 }
            }
            else{
               if(key_flag==0){
                  if(++key_counter==4){
                     key_flag=1;
                     key_counter=0;
                     sw_input=key;
                     return;
                  }
               } 
               
                else return;
            }


    ------------------------------------------------------------------------------
    main while 입니다.

    while(1) {
    Disp_operation();
    SW_operation();

      }

  • WhiteAT 2008.01.09 17:00
    1.
    __interrupt void timer0_compare_isr(void)

    {    
          if(Disp_timer) Disp_timer--; //fnd,led timer
          if(LED_timer) LED_timer--;//LED blink timer
          if(Key_timer) Key_timer--; //key input timer       
    }
    =>Disp_timer 를 unsigned 로 선언하셨죠?
    signed 로 선언하였을 경우에는 if(Disp_timer>0) Disp_timer--;

    2.
    void Disp_operation(void) {
     
      if(Disp_timer>0) return;
     
      Disp_timer =1;
    }
    함수에 Disp_timer  , LED_timer 2개를 동시에 사용하였는데
    그러면 로드가 많이 걸릴수 있으므로, 서로 다른 함수로 사용하시는게..

    타이머를 Disp_timer =1;로 했기 때문에 main()의 루프가 실행될때마다 실행이 되겠죠?(즉 150uS마다)

    LED_timer 는 사용되지 않고 있네요.^^  
    if(Disp_timer>0) return;  <== 요놈만 체크를 하니까요^^.


    3.
    Key_timer =1;

        키 함수도딜레이를 충분히 주세요. 1로 주면 150uS마다 키를 검색할테니까요.
        200mS 정도는 주는게 좋을거 같은데  Key_timer =1000; 정도 해보세요.^^



  • 러빙유 2008.01.09 17:26 글쓴이
    아. 스위치 입력부는 그렇게 하면 될 것 같은데요..

    말씀하신대로 LED_timer가 들어가는 깜빡깜빡 시켜주는 부분을 분리화를 못 시키겠습니다.

    암만 생각해도요..


    제가 생각할 때는 특정 스위치 입력이 들어오면, 특정 led를 0.5초 간격으로 깜빡깜빡 시켜 주야 하는데..

    제가 생각한 로직은 아래와 같습니다.


    Disp_timer=1;

    if(LED_timer>0) return;

    if(특정 스위치 입력 flag ==1) { //blink mode

     LED_timer = 800; //0.5초 입력

      if(LED(num) ==1) OFF; 
      if(LED(num)==0)  ON; }
     
    else  {
      
      LED_PORT = LED_value; //원래 값 출력 150us 간격

    }

    입니다. 이걸 분리를 못하겠어요. 저도 이제 정말 힘드네요..하....통신도 맞추어야 하는데..

    처자식 먹여 살리기 정말 힘드네요.
  • WhiteAT 2008.01.10 05:56

    이 정도면 어떨까요?

    void Disp_operation(void) {
      
     // if(Disp_timer>0) return;  
      //Disp_timer =1;
    
        if(LED_timer>0) return;
      LED_timer=1;
    
          DIGM = 1<<icounter;
            ////////////////////////////
            if(icounter == 3){
              if(blink_flag >0 && blink_flag < 9){
       //           if(LED_timer>0) return;
                  
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_one = Led_one & ~(1<<(blink_flag-1));//ON   
                    SEGM = Led_one;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_one = Led_one | (1<<(blink_flag-1));//OFF
                    SEGM = Led_one;}                
              }
              else {
                SEGM = Led_one; }
            }
            //////////////////////////////  
            else if(icounter == 7){
              if(blink_flag >8){
         //         if(LED_timer>0) return;
                  
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_two = Led_two & ~(1<<(blink_flag-9));//ON   
                    SEGM = Led_two;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_two = Led_two | (1<<(blink_flag-9));//OFF
                    SEGM = Led_two;}                
              }
              else {
                SEGM = Led_two; }
            }
            ////////////////////////////////
            else{SEGM =fnd_data[icounter];}
       ++icounter;
       if(icounter ==8) icounter=0;
    }    


     

  • 러빙유 2008.01.10 10:18 글쓴이

    혹시 위에 올리신게 분리시키신 것인지요?.. 일단 저렇게 하면 icounter == 3 이. ,blink 모드일때 800이후에 다시 들어오기

    때문에..

     else{SEGM =fnd_data[icounter];} fnd와 icounter==7 일때 led 그룹이 제대로 들어오지 않게 됩니다.


    그래서...제가 이런식으로도 해봤는데, 스위치 누르면 이상하케 led들이 들어오고 이상한 것이 깜빡이고 난리납니다.--'

    void Disp_operation(void) {
     
      if(Disp_timer>0) return;
      Disp_timer =2;
     
        if(++icounter ==8) icounter=0;
          DIGM = 1<<icounter;
            ////////////////////////////
            if(icounter == 3){
              if(blink_flag !=0) return;
              else {
                SEGM = Led_one; }
            }
            ////////////////////////////// 
            else if(icounter == 7){
              if(blink_flag !=0) return;
              else {
                SEGM = Led_two; }
            }
          
            ////////////////////////////////
            else{SEGM =fnd_data[icounter];}
           //else SEGM =fnd_data[icounter];
    }   

    void Disp_suboperation(void) {
     
        if(LED_timer>0) return;
         LED_timer =2;
     
          
            ////////////////////////////
            if(icounter == 3){
            DIGM = 1<<icounter;
              if(blink_flag >0 && blink_flag < 9){
                 
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_one = Led_one & ~(1<<(blink_flag-1));//ON  
                    SEGM = Led_one;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_one = Led_one | (1<<(blink_flag-1));//OFF
                    SEGM = Led_one;}               
              }
              else return;
            }
         
            ////////////////////////////// 
            else if(icounter== 7){
             DIGM = 1<<icounter;
              if(blink_flag >8){
                 
                  LED_timer = 800;
                    if(LEDST[blink_flag-1]==1){ //LED OFF
                    Led_two = Led_two & ~(1<<(13-blink_flag));//ON  
                    SEGM = Led_two;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_two = Led_two | (1<<(13-blink_flag));//OFF
                    SEGM = Led_two;}               
              }
              else  return;
            }
          
     ////////////////////////////////
    }          

    while(1) {
    Disp_operation();
    Disp_suboperation();
    SW_operation();

    if(SwInput()==4)LedDisp(12,2); //스위치 입력값이 4이면, 12번째 led만 깜빡 깜빡해라.. 스위치 입력값은 정상으로 들어오는데..--

     }
    }

  • WhiteAT 2008.01.10 13:01
    혹시 위에 올리신게 분리시키신 것인지요?.. 일단 저렇게 하면 icounter == 3 이. ,blink 모드일때 800이후에 다시 들어오기
    때문에..
     else{SEGM =fnd_data[icounter];} fnd와 icounter==7 일때 led 그룹이 제대로 들어오지 않게 됩니다.

     => 로직에 대해서는 잘모르겠지만 ㅡㅡ;
         왜 7과 else가왜 실행이 안된다고 하는 거죠?

        count==3일 경우 해당 루틴을 실행하고 
    아래 것도(++icounter;      if(icounter ==8) icounter=0;  ) 실행이 됩니다.
        다음에는
    LED_timer 가 되면 count==4로 들어오고
                                         다시 count==5로 들어옵니다.


    작은 기능에서 시작해서 살을 붙여 가세요^^
    - 한번에 저렇게 모두 코딩해서 잡으려고 하면 무지 힘듭니다.
       물론 다른 사람이 봐서는 이해가 전혀 안되고요 ㅡㅡ.

    - (다른 사람이 보기에)변수명이 헤갈리게 되어 있습니다.
        (처음에는 LED만 제어하는 줄 알았는데,  지금은 FND 와LED 를 동시에 제어 해야 하는건가요?)

    - 변수가 어떤 기능을 하는지 알수가 없어서 변수의 의미를 생각하는데 노력이 더 필요하네요.^^.
                   LED_timer = 800; //   LED 를 제어하는 변수?
                    if(LEDST[blink_flag-1]==1){ //LED OFF  // LED 상태?
                    Led_one = Led_one & ~(1<<(blink_flag-1));//ON  
                    SEGM = Led_one;}  // FND?
                     
         - (답이 없으셨는데) 변수는 signed로 하신거죠?


    일단 스위치는 재껴두고 FND 만 생각하고, FND 가 깜박이는지만 확인해보세요.
    (여기서 문제가 없다면 다른 것을 추가하기가 쉬워질 겁니다.
     여기서 문제가 있다면 해결하면 되겠죠?)

     void Disp_operation(void) {
    // Led_two, LED_one 는 무엇인가요?
      
    // icount = 0 ===> blink 에서 FND OFF 인상태
    // icount = 1 ===> blink 에서 FND ON 인상태
    
    
    
        if(LED_timer>0) return;
      LED_timer=100;
    
         // DIGM = 1<<icounter; <== 이거 뭐죠?
            ////////////////////////////
            if(icounter == 0){   // ON 하자
              if(blink_flag >0 && blink_flag < 9){
       //           if(LED_timer>0) return;
                  
                  LED_timer = 800;
                  //  if(LEDST[blink_flag-1]==1){ //LED OFF
                 //   Led_one = Led_one & ~(1<<(blink_flag-1));//ON   
              //      SEGM = Led_one;
                   
               //     else if(LEDST[blink_flag-1]==0) { //LED ON
                    Led_one = Led_one | (1<<(blink_flag-1));//OFF
                    SEGM = Led_one;
                      }                
              }
              else {
                SEGM = Led_one; 
                }
      
            }
            //////////////////////////////  
            else if(icounter == 1){   // OFF 하자
             if(blink_flag >0 && blink_flag < 9){    //  if(blink_flag >8){
         //         if(LED_timer>0) return;
                  
                  LED_timer = 800;
                      Led_one = Led_one & ~(1<<(blink_flag-1));//ON   
                    SEGM = Led_one;
    
             //     if(LEDST[blink_flag-1]==1){ //LED OFF
                //    Led_two = Led_two & ~(1<<(blink_flag-9));//ON   
                //    SEGM = Led_two;}
                 //   else if(LEDST[blink_flag-1]==0) { //LED ON
                  //  Led_two = Led_two | (1<<(blink_flag-9));//OFF
                  //  SEGM = Led_two;
                     }                
              }
              else {
                SEGM = Led_two;
    }
            }
            ////////////////////////////////
            else{SEGM =fnd_data[icounter];}
       ++icounter;
       if(icounter ==8) icounter=0;
    } 

  • 러빙유 2008.01.10 14:15 글쓴이

    먼저 답변을 드려야죠.^^'  타이머들은 다 unsigned int로 했씁니다. 그리고, 위에 제가 첨부한 코드들로 했을 때
    fnd 6개는 다 잘들어옵니다. led들이 문제이죠.

    회로와 로직에 대해설 설명을 드리고, 코딩에 대해서 주석을 달아 드리겠습니다.

    먼저 회로를 여기에 다 올려서 설명하기 그렇고..
    일단 외부 io 제어 방식을 사용합니다. 그리고, 회로적으로 아래와 같은 주소에
    값을 쓰면, 입출력이 됩니다.

    #define SEGM (*(volatile unsigned char *)0x8000)//WR0
    #define DIGM (*(volatile unsigned char *)0x8200)//WR1
    #define KEYM (*(volatile unsigned char *)0x9000)//RD0
     
      여섯개의 FND와 8개의 LED 그룹1과 또다른 5개의 LED 그룹에 d0~d7로 버스방식으로 다 연결되어 잇습니다.
     따라서 fnd와 LED 출력인

    SEGM = 값을 쓰면  fnd나 led그룹들로 값이 나갑니다. 그 전에 몇번째 fnd와 몇번째 LED 그룹에다 값을 쓸 것인지를
    지정해줘야 되겠죠. 그것이 바로 DIGM 주소입니다. fnd와 led가 다 common anode로 연결 되어 있어 common을 잡아
    주는 IC의 맵핑 주소가 DIGM 입니다.

    따라서, 예를 들면 DIGM = 0X01; 첫번째 fnd선택 SEGM = 값; 하면 첫번째 fnd로만 시그널이 나갑니다.
    나머지는 빠르게 DIGM을 업카운트 시키면 되겠죠.

    여기서, 중요한 사실은

    DIGM = 0
    DIGM = 1
    DIGM = 2  FND 3개

    DIGM = 3 LED 첫번째 그룹(LED 8개)

    DIGM = 4
    DIGM = 5
    DIGM = 6 나머지 FND 3개

    DIGM = 7 LED 두번째 그룹(LED 5개)로 회로적으로 맵핑되어 있다는 것입니다.

    그리고, 스위치 입력은 그냥 KEYM (*(volatile unsigned char *)0x9000 이주소로

    key = KEYM 으로 받으면 됩니다.


    따라서 ,여기서 요구되는 것은 fnd와 led를 계속 업데이트 시켜 주면서 sw 스캔을 하여 특정 입력시
    특정 led그룹의 특정 led를 제어해야 한다는 사실입니다.

    -----------------------------------------------------------------------------------------------
    위에 근거한 제가 첨부한 코드 설명
    ----------------------------------------------------------------------------------------------
    void Disp_operation(void) {
     
      if(Disp_timer>0) return;
      Disp_timer =2;
     
        if(++icounter ==8) icounter=0;
          DIGM = 1<<icounter;                    //이부분이 바로 fnd와 led를 빠르게 순차적으로 선택해주는 것입니다. 값을 쓰기전에 선택하 
                                                                      는 것이죠. 0x01=1st fnd선택, 0x02=2nd fnd 선택...등.
            if(icounter == 3){ //위에서 언급했다 시피 DIGM = 0x08 이면 1st LED 그룹(8개)를 선택합니다.
              if(blink_flag ==0 && blink_flag < 9) return; //blink_flag 는 아래 LED 함수에서 설명 드리겠습니다.
              else {
                SEGM = Led_one; } // Led_one은 volatile unsigned char로 선언되어 있으며, 바로 첫번째 LED 그룹의 변수입니다.
                                                       여기서 출력을 내보냅니다.
            }
            ////////////////////////////// 
            else if(icounter == 7){  //바로 마지막 LED그룹을 선택하는 것입니다.
              if(blink_flag >8) return; //blink_flag를 왜 이렇게 비교하는지는 밑에 led 함수에서 설명..
              else {
                SEGM = Led_two; } //위와 마찬가지로 두번째 그룹의 led값을 출력합니다.
            }
          
            ////////////////////////////////
            else{SEGM =fnd_data[icounter];} //그리고 3 과 7이 아닌 나머지들은 바로 fnd들인 것입니다.
                                                                        여기서 fnd_data[ ]는 밑의 fnd 함수를 보시면 아 실 수 있으십니다.
    }   

    void Disp_suboperation(void) {
     
        if(LED_timer>0) return;
         LED_timer =2;
     
          
            ////////////////////////////
            if(icounter == 3){
            DIGM = 1<<icounter;  // 첫번째 led 그룹으로 출력을 내보내려고 선택했습니다.
              if(blink_flag >0 && blink_flag < 9){  //blink_flag 비교값이 왜 이런지, 뭔지는 led 함수에서....
                  
                  LED_timer = 800; //첫번째 LED 그룹, 8개의 LED들 중 특정 LED의 깜빡 주기. 250us * 800
                    if(LEDST[blink_flag-1]==1){ //LEDST는  volatile unsigned char  LEDST[13]; 이라고 선언되어 있습니다.
                                                                         LEDST[0] = 첫번재 led 그룹의 첫번재led 의 상태값, LEDST[12] = 두번재 LED 그룹의 LED
                                                                         마지막 LED의 상태값  여기서는 1 이면 OFF입니다.

                    Led_one = Led_one & ~(1<<(blink_flag-1));// 따라서 이렇게 하면 0으로 마스킹하여 ON 시킵니다.
                    SEGM = Led_one;} // 그리고 출력.
                    else if(LEDST[blink_flag-1]==0) { // 이제는 위와 반대겠죠.
                    Led_one = Led_one | (1<<(blink_flag-1));//OFF
                    SEGM = Led_one;}               
              }
              else return;
            }
         
            ////////////////////////////// 
            else if(icounter== 7){  //이제는 두번째 LED그룹(5개 LED)을 선택하는 것입니다.
             DIGM = 1<<icounter;
              if(blink_flag >8){ //왜 이값을 비교하는지는 밑의 LED 함수에서..
                  
                  LED_timer = 800;  //이제부터는 icounter==3 의 위와 유사합니다.
                    if(LEDST[blink_flag-1]==1){ //LED OFF 상태입니다.
                    Led_two = Led_two & ~(1<<(blink_flag-9));//ON  
                    SEGM = Led_two;}
                    else if(LEDST[blink_flag-1]==0) { //LED ON 상태입니다.
                    Led_two = Led_two | (1<<(blink_flag-9));//OFF
                    SEGM = Led_two;}                //마지막 LED 그룹으로 출력.
              }
              else  return;
            }
          
     ////////////////////////////////
    }          

    //FND WRITE 함수입니다.메인에서 호출하여 배열에 값을 넣어 두게 합니다.
    //numb 는 fnd 넘버입니다. 0,1,2,4,5,6. 입니다, 여기서 3,7은 led이므로 여기서 입력자체를 안합니다.
    //datafnd는 값입니다. 이미 상수 배열로 다 선언해놓았기 때문에, 여기는 걍 0~9만 쓰면 됩니다.
    //그리고 마지막으로 dotp 는 dot 유무입니다.
    void FndDisp(unsigned char numb,unsigned char datafnd, unsigned char dotp){
       if(dotp == 1) {fnd_data[numb]=(0x7f & fnd_pattern[datafnd]);} //dot 넣을 거면 masking~~! 그리고 값 넣습니다.
       else {fnd_data[numb] = fnd_pattern[datafnd];}  //아니면 그냥 값 넣습니다.
      }


    //바로 메인에서 호출하여 led_one, led_two에 값을 써 두는 함수입니다.
    //Lnum은 LED 넘버입니다. LED가 총 13개이므로 0~12로 정의하여 입력받습니다.
    //Ldata 는 일종의 모드입니다. 0이면 off, 1이면 on, 2이면 블링크입니다.
    void LedDisp(unsigned char Lnum, unsigned char Ldata){
        switch(Ldata) {
        case 0: //off
            LEDST[Lnum] =1;//LED[13] 이라고 선언된 배열에 상태를 입력
            if(Lnum <8) { //만약 LED가 첫번재 그룹이라면 0~7.
                Led_one = (Led_one | (1<<Lnum)); }// 바로 led_one에 값을 masking 하여 off 시킵니다.
            else {
                Led_two = (Led_two | (1<<(Lnum-8))); } //아니면 8을 빼주면 되겠쬬. 가령, Lnum=8 이면 두번째 그룹의 첫번째
                                                                                          LED입니다. 그럼, DIGM = 7 일때, SEGM = 0000 0001 의 '1' 이죠.
                                                                                        그렇기 때문에, (Lnum-8) == 0 이 되면 되는 것입니다. 그래서 8을 뺍니다.
                blink_flag =0;       //그리고 블링크 모드 플래그는 리셋시킵니다.
                break;
               
        case 1://on
           LEDST[Lnum] =0; // ON 입니다. 여기서는 ON 을 '0'으로 간주합니다.
            if(Lnum <8) {                                                                //마스킹만 틀리지 위와 똑같습니다.
                Led_one = (Led_one & ~(1<<Lnum)); }//set
            else {
                Led_two = (Led_two & ~(1<<(Lnum-8))); }
                 blink_flag =0;
                 break;
                
        case 2://blink                           //바로 여기입니다, blink 모드를 입력하면, blink_flag 에 LED 넘버(Lnum) +1 을 넣어
                                                             둡니다. 왜냐하면 led가 첫번째 led이면 Lnum =0이기 때문에 1을 더해 주어야 합니다.
                                                             blink_flag == 0 은 reset 에 사용하기 때문입니다.

                              따라서 위에서 본 if(blink_flag >0 && blink_flag < 9) 는 첫번째 LED 그룹의 8개의 LED들을
                              가리키는 것입니다.   그리고,  LEDST[blink_flag-1]==0 에서 1을 다시 빼는 이유도 다 여기
                              때문입니다.
                                         

            blink_flag = Lnum +1; 
                break;
        }         
      }

    main() {
    led_one = 0x00; //all 출력 on
    led_two = 0x00; //all 출력 on

    FndDisp(0,2,0);  //초기에 6개의 fnd와 13개 led에 값을 줍니다.
    FndDisp(1,2,0);
    FndDisp(2,3,0);
    FndDisp(4,4,0);
    FndDisp(5,5,0);
    FndDisp(6,7,0);
    LedDisp(0,1);
    LedDisp(1,1);
    LedDisp(2,1);
    LedDisp(3,2);
    LedDisp(4,1);
    LedDisp(5,1);
    LedDisp(6,1);
    LedDisp(7,1);
    LedDisp(8,1);
    LedDisp(9,1);
    LedDisp(10,1);
    LedDisp(11,1);
    LedDisp(12,2);

    while(1) {
    Disp_operation();
    Disp_suboperation();
    SW_operation();

    if(SwInput()==4)LedDisp(12,2); //스위치 입력값이 4이면, 12번째 led만 깜빡 깜빡해라.. fnd,
    스위치 입력값은 정상으로 들어오는데..--

     }
    }



    정말 힘들었습니다. 꼭 좋은  답변 부탁 드립니다.

  • WhiteAT 2008.01.10 15:18
    이제 어느정도 이해가 됩니다 ㅡㅡ;
    회사 업무하면서 잠깐잠깐 보니 정신이 하나도 없네요.

    1.
    (참고로 말씀드리면)
    void Disp_operation(void)   에서         if(icounter == 3)이 실행되었다고 해서
    void Disp_suboperation(void) 에서 if(icounter == 3) 이 꼭 실행된다고 보장할수 없습니다.
    Disp_operation(void) 에서 icount==3이 되었지만.. Disp_suboperation(void)  에서 LED_timer >0 때문에 실행이 안될수도 있습니다.  이럴 경우에는 아래처럼 각각의 함수와 변수를 만들어야 사용해야 합니다.


    함수1
    DIGM = 0
    DIGM = 1
    DIGM = 2  FND 3개


    함수2
    DIGM = 3 LED 첫번째 그룹(LED 8개)

    함수3
    DIGM = 4
    DIGM = 5
    DIGM = 6 나머지 FND 3개

    함수4
    DIGM = 7 LED 두번째 그룹(
    LED 5개)로 회로적으로 맵핑되어 있다는 것입니다


    2.
    (일단은) 12bit만 blink를 한다고 가정을 한다면.

    void LedDisp(unsigned char Lnum, unsigned char Ldata) 함수까지 만들었으면 다 된거 같은데요.
    BYTE g_byteLED12Blink;
    BYTE g_byteLEDNowStatus;

    void LED_oper(void) {   // main에서 이 함수 호출.
    // 여기서는 다른 함수에서 뭘 하던 말던. 이 두 변수로만 일을 하게 됩니다.
    // 
    g_byteLED12Blink = 1;  
    // 
    g_byteLEDNowStatus= 0;
     
        if(LED_timer>0) return;
         LED_timer =1000;

         if(1 == g_
    byteLED12Blink){
                   if(켜짐 ==
    g_byteLEDNowStatus){
                              
    LedDisp(12, 0); off해라
                              
    g_byteLEDNowStatus = 꺼짐;
                    }else {
                           LedDisp(12,1); ON해라
                          
    g_byteLEDNowStatus = 켜짐;
     

                      }    
         }else{
               // blink 가 아니라면.
              
    LedDisp(12, xxxxx);// ON이던 OFF 이던...

         }
    }

    main(){
            if(SwInput()==4)// LedDisp(12,2);
         { //  여기서는
    LED_oper()에서 사용할 변수와 플래그만 셋팅해 줍니다.
            // 다른 함수가 출력을 하던 말던 여기서는 상관을 하지 않는거죠....

               
    g_byteLED12Blink = 1;  
                
    g_byteLEDNowStatus= 0;
         }
    }
    // 원하는 결과가 나온다면 고정된 bit12말고 변수를 적절히 사용하여 모든비트에 적용하면 될겁니다.
     



    3. 만약 2번도 안된다면 다 주석처리하고 각각의 기능을 따로따로 해보고 합치는 방법이 있습니다.
        정말로 다른 방법이 없고 단지 이 방법뿐이 없습니다.




  1. VC++ RS232C통신 및 Log data 수집

    Date2009.04.04 Category :일반 Reply1
    Read More
  2. [MFC]키보드 입력 관련 질문입니다.

    Date2009.02.03 Category :일반 Reply1
    Read More
  3. 어제 테트리스에 댓글 달았던 학생입니다

    Date2008.12.13 Category :일반 Reply2
    Read More
  4. 테트리스 소스에 대한 질문이있습니다.

    Date2008.12.12 Category :일반 Reply1
    Read More
  5. 기술자료실에 127번 글에서 질문있습니다..

    Date2008.12.01 Category :일반 Reply1
    Read More
  6. 문제 답변 쫌 부탁드려요~ ^^

    Date2008.11.09 Category :일반
    Read More
  7. 조언 부탁드립니다. 필드에서 지적 받은건데요..

    Date2008.06.13 Category :일반
    Read More
  8. c++구조체와 함수를사용해서 성적표만들기2

    Date2008.05.29 Category :일반 Reply1
    Read More
  9. c++구조체와 함수를사용해서 성적표만들기

    Date2008.05.29 Category :일반 Reply1
    Read More
  10. mfc 테트리스 질문이요~

    Date2008.05.15 Category :일반 Reply1
    Read More
  11. RS485 통신 방법

    Date2008.01.22 Category :일반 Reply3
    Read More
  12. 함수인자를 구조체 변수나 구조체 주소로 받는 것.

    Date2008.01.14 Category :일반 Reply2
    Read More
  13. 인터럽트 루틴을 메인으로 빼고자 하는데 가능할 지요?

    Date2008.01.09 Category :일반 Reply12
    Read More
  14. LED 깜빡 거림.

    Date2008.01.08 Category :일반 Reply8
    Read More
  15. IAR 컴파일러 환경에서 AVR128 Timer1 인터럽터 구현이 안되요..

    Date2008.01.04 Category :일반 Reply2
    Read More
목록
Board Pagination Prev 1 2 3 4 Next
/ 4