2015년 10월 28일 수요일

써미스터 온도계

NTC Thermometer를 이용한 디지털 온도계 제작

온도를 측정하기 위한 센서에는 반도체를 이용하는 것과 두 금속의 접합부에서 발생하는 열기전력을 이용하는 것 등 여러 가지가 있다, 그 중에서도 써미스터(Themistor)는 가격이 낮고 높은 신뢰성을 지닌다.

NTC Themistor
NTC(Negative Temperature Coefficient of Resistance) 써미스터는 대부분 사용 온도가 300℃ 미만으로 Co, Mn, Ni, Cu, Fe 등의 금속산화물을 두 종류 또는 그 이상 혼합한다. 소결성 향상을 위해 CuO를, 저항값 감소를 위해 F₂O₃나 Li₂O를, 저항값 증가를 위해 Cr₂O를 첨가한다. 또한 1200∼1400℃의 고온에서 소성한 소결체로, 안정된 Spinel 구조나 Rock Salt 구조를 갖게 함으로써 저항이 (-)의 온도계수를 갖는 Thermally Sensitive Resistor이다.

그림 1. 써미스터 종류별 특성
그림 2. 디스크형
그림 3. 터미널형
그림 4. 막대형

써미스터의 한 선을 +5V에 연결하고 직렬로 저항을 연결시킨 후 저항의 한 쪽은 0V로 향하게 한다. 써미스터와 직렬로 연결된 저항 사이에서 선로를 인출해 마이크로프로세서의 ADC PORT로 연결하면, 온도 변화에 따른 써미스터의 저항 변화에 대한 전압이 마이크로프로세서를 통해 디지털로 변화된다(그림 5 참조).

그림 5. 마이크로프로세서와 온도 센서 연결 도면

NTC 온도 측정을 위해 사용된 마이크로프로세서는 8bit로 많은 사용자를 가지고 있는 ATMEL의 ‘ATMega128’이며, 소스 코드를 다른 마이크로프로세서에 이식해 적용하는 것은 쉬울 것으로 판단된다. 핵심 코드는 Temp_Cal() 이며, 온도에 따른 써미스터의 저항 변화를 AD를 통해 전압으로 읽어 들이고, 이러한 전압을 특별한 공식을 이용해 온도 값으로 연산하고 표시한다.
Steinhart–Hart 방정식이 일 때 특정 온도의 저항값 a, b, c 모두 필요하다. 그러나 B parameter 방정식을 사용하면 식 1과 식 2로 정리된다.
조건이 식 1과 식 2를 사용할 수 있다.




 그림 6. 온도 계산 함수

그림 6에서 Temp_Cal() 함수의 마지막에 25℃를 기준으로 온도 보상이 이루어진다. 25℃와 50℃의 온도에서 데이터 로거와 제작한 온도계의 온도 차는 약 2℃로, 보상을 위한 조건문을 삽입했다.
그림 5에서 위치번호 J6으로 표현된 곳에 써미스터가 연결된다. ATMega128에 내장된 10bit ADC를 이용한 써미스터의 변화된 저항값을 전압으로 디지털 변환해 읽어 온다.


그림 7. 온도 표시부

그림 7은 측정된 온도를 표시하기 위해 FND를 사용하여 측정된 써미스터의 저항을 전압으로 입력받아 연산한 결과를 표시하기 위한 것이다. FND는 위치정보 U3 과 U4로 나누어 표시됐지만 온도가 표시될 때에는 연결해 읽어보면 된다.

그림 8. 전원부와 키보드 입력부



결론
감도오차(Sensitivity Error)를 보상해 주고 온도계용 데이터 로거를 사용해 비교 측정을 했으며, 연결된 센서는 써모커플 K type이다. 온도로거의 온도는 53.1℃이지만 PCB로 제작된 온도계는 52.9639℃였다. 측정 결과, 써미스터를 사용한 온도계가 -0.1361℃ 정도로 미소하게 작아 만족할 만한 결과를 얻을 수 있었다.
초기 개발에서는 감도 오차가 없다고 생각했지만 그림 12에 보이는 분홍색의 장치를 사용해 센서에 온도를 올려 측정해 본 결과, 감도오차(Sensitivity Error)가 있어 보상을 해 줬다. 하지만 –온도는 검증되지 않았다. 분홍색의 장치는 찜질용 안대를 데우는 본체로, 온찜질과 냉찜질을 모두 할 수 있는 제품이다. 이 제품 역시 NTC 써미스터를 이용한 온도센서로 온도를 제어한다.

NTC 소자를 이용한 써미스터 온도센서는 저렴한 가격과 견고성, 신뢰성이 특징이다. 하지만 열이 센서로 전달 되는 데 일정 시간이 걸린다는 단점이 있다. 여기에 사용한 센서는 약 7.5초의 시간 지연이 일어난다. 물론 작은 NTC를 사용하면 지연 시간이 줄어든다. NTC가 SMD로 제작된 부품도 시중에 많이 유통된다. 개발에 사용된 컴파일러는 WinAVR이며 통합 환경은 AVR STUDIO에서 진행했다.

http://www.hellot.net/new_hellot/magazine/magazine_read.html?code=205&sub=002&idx=21448&public_date=2014-11&sort=registDate&page_num=15&list_type=List&page=1

http://www.hellot.net/new_hellot/magazine/magazine_read.html?code=105&sub=002&idx=21449

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AVR Studio V4.19
// WinAVR 20050214
#include "main.h"
#include "localmath.h"
#ifdef ADC_BubbleSort_Enable
 #define SWAP(a, b)  { dword t;  t=a;  a=b;  b=t; }
 word BubbleSort(word *p, byte num){
  byte i, j;
  long k=0;

  for(i=0; i<_AVERGE_NUMBER_-1; i++) {
   for(j=1; j<_AVERGE_NUMBER_-i; j++) {
    if(p[j-1] > p[j])  SWAP(p[j-1],p[j]);
   }
  }
  for(i=_AVERGE_NUMBER_/3; i < (_AVERGE_NUMBER_/3)*2; i++) k += p[i];
 
  return k/(_AVERGE_NUMBER_/3);
 }
#endif
void Is_Rx(void){
while(g_RxTopCount != g_RxButtomCount){
if(g_RxEnd == 0){
   if(g_RxRingBuffer[g_RxButtomCount] == _STX_)      str  = g_WorkBuf;
   else  if(g_RxRingBuffer[g_RxButtomCount] == _ETX_)   g_RxEnd++;
   *str++   = g_RxRingBuffer[g_RxButtomCount++];
    *str     = 0;
    g_RxButtomCount  %= _BufferLength_;
   }
   else{
    if(g_RxEnd < 3){
     g_RxEnd++;
     *str++         =  g_RxRingBuffer[g_RxButtomCount++];
     *str          =  0;
     g_RxButtomCount %=   _BufferLength_;
    }
   }
  }
 }
}
void Delay_xMs(word i){
 CLEARBIT(TIMSK, TOIE0);       // 타이머0 인터럽트 금지
 g_DelayValue  = i;
  SETBIT(TIMSK, TOIE0);        // 타이머0 인터럽트 허용
 
  if((SREG & 0x80) == 0) sei();    // 인터럽터 활성화가 되어 있지 않다면 강제로 전체 인터럽터 활성화

 while(g_DelayValue)
  wdt_reset();
}
void SPI_WriteByte(unsigned char CMD){
 SPDR = CMD;
 while(!(SPSR & (1<}
void Init_SPI_Clock_Devide(byte Devide){
 if(      Devide == 2)  SPSR |= (1< else if(Devide == 4)   SPSR |= (0< else if(Devide == 8)   SPSR |= (1< else if(Devide == 16)  SPSR |= (1< else if(Devide == 32)  SPSR |= (1< else if(Devide == 64)  SPSR |= (1< else if(Devide == 128)  SPSR |= (1< else         SPSR |= (1<}
void Init_SPI(void){
 Init_SPI_Clock_Devide(2);
                                                            
 SPDR  = 0;            // 초기화
                                                           
 SETBIT(SPCR, MSTR);         // SPI 마스타로 동작
 SETBIT(SPCR, SPE);          // SPI 활성화
 CLEARBIT(SPCR, CPOL);        // SPI 모드 0으로 동작, 클럭 발생 상승 부터
 CLEARBIT(SPCR, CPHA);        // SPI ?
 CLEARBIT(SPCR, DORD);        // MSB를 먼저 출력
                                                            
 #ifdef _Is_Is_SPI_Interrupt__Proc_                         
  SETBIT(SPCR, SPIE);        // SPI 인터럽터 활성화
 #endif
}

byte Write_SPI_One_byte(byte i){
 while(g_Flag_SPI_TxStatus) wdt_disable();
 SPDR  = i;
 return SPDR;
}
void Write_SPI_Several_byte(byte length, byte* pSend){
 while(length--)  Write_SPI_One_byte(*pSend++);
}
void Init_ADC(void){
// ADCSRA = 0;        // 2분주
// ADCSRA = 1;        // 2분주
// ADCSRA = 2;        // 4분주
// ADCSRA = 3;        // 8분주
// ADCSRA = 4;        // 16분주
// ADCSRA = 5;        // 32분주
// ADCSRA = 6;        // 64분주
 ADCSRA = 7;        // 128분주
  SETBIT(ADCSRA, ADEN);                  // AD 활성화          
 ADMUX   = 0x02;                    // 입력 AIN2
 #ifdef ADC_ISR_Load
   CLEARBIT(ADMUX, REFS1);   SETBIT(ADMUX, REFS0);    // 기준 전압은 AVcc로 사용
 // SETBIT(ADMUX, REFS1);    SETBIT(ADMUX, REFS0);    // 기준 전압은 내부 2.5V로 사용
 // SETBIT(ADMUX, REFS1);    SETBIT(ADMUX, REFS0);
   SETBIT(ADCSRA, ADIE);                 // AD 변환 인터럽터 작동
   SETBIT(ADCSRA, ADSC);                 // AD 변환 시작       
 #else
   SETBIT(ADCSR, ADFR);                 // AD 자유 변환 시작       
 #endif

 SETBIT(MCUCR, SM0);                   // AD Noise Reducation
}
word Read_ADC(void){
 ADCSRA   |= (1 << ADSC);
 while(!(ADCSRA  & (1 << ADIF)));
 return ADC;
}
void Init_USART(unsigned long BaudRate){        
  UBRR0H  = 0;
  UBRR0L  = (byte)((_FCPU_/(16 * BaudRate))-1);
// Enable receiver and transmitter, receiver Interrupt Enable
 UCSR0B  = (1<
// Set frame format: 8data, 1stop bit
 UCSR0C  = (3<}
void Init_Ext_Int(void){
 SETBIT(EICRB, ISC41);  CLEARBIT(EICRB, ISC40);
 SETBIT(EICRB, ISC51);  CLEARBIT(EICRB, ISC50);
 SETBIT(EICRB, ISC61);  CLEARBIT(EICRB, ISC60);
 SETBIT(EIMSK, INT4);
 SETBIT(EIMSK, INT5);
 SETBIT(EIMSK, INT6);
}
void Init_timer0(void){
 #ifdef _FCPU_16MHz_
  TCNT0    = _Timer0_16M_64Dived_1mSec_;   // 16MHz 클럭 8분주 일때 1mSec 발생
 #else
  TCNT0    = _Timer0_8M_64Dived_1mSec_;   // 8MHz 클럭 8분주 1mSec 발생
 #endif
 SETBIT(TCCR0, CS02);             // 64분주
  SETBIT(TIMSK, TOIE0);              // 타이머0 인터럽트 허용
}                                             
                                              
void Init_timer1(void){              // 카운터로 사용한다
 TCCR1A   = 0;              // 자유증가 카운터 모드
 SETBIT(TCCR1B, CS11);            // 8 분주
 TCNT1    = _TDELAY_;
  SETBIT(TIMSK, TOIE1);              // 타이머1 인터럽트 허용
}
void Init_timer2(void){
 SETBIT(TCCR2, CS20);
 TCNT2  = 0;
  SETBIT(TIMSK, TOIE2);              // 타이머2 인터럽트 허용
}                                             
                                              
void Init_timer3(void){                       
 TCCR3A = 0;                // 자유증가 카운터 모드
 SETBIT(TCCR3B, CS31);            // 8 분주
 TCNT3  = 0xff-50;                        
  SETBIT(ETIMSK, TOIE3);             // 타이머3 인터럽트 허용
}
byte Sum_Char_Return(byte i){
 if(i > 9)  return (i-10) + 'A';
 else    return  i     + '0';
}
byte BCC_Hi_Byte(byte i){
 I  >>= 4;

 return Sum_Char_Return(i);
}
byte BCC_Low_Byte(byte i){
 I  &= 0x0f;

 return Sum_Char_Return(i);
}
byte SUM_Check(void){
 byte i = 0;

 str  = g_WorkBuf;
 while(*str != _ETX_)   i += *str++;
 i   += *str++;
 if(BCC_Hi_Byte(i)  != *str++)  return 1;
 if(BCC_Low_Byte(i) != *str++)  return 2;
 
 return 0;




SIGNAL(SIG_ADC){
 CLEARBIT(ADCSRA, ADIF);            // 인터럽터 플레그 클리어
 #ifdef ADC_Convert_Enable

  #ifdef ADC_BubbleSort_Enable
   _g_AdcTempBuffer[_g_AdcTempBufCount++]   =  ADC;
   _g_AdcTempBufCount            %= _AVERGE_NUMBER_;
  #endif
 #endif

  SETBIT(ADCSR, ADSC);             // AD 변환 시작
}
SIGNAL(SIG_OVERFLOW0){
 #ifdef _FCPU_16MHz_
  TCNT0    = _Timer0_16M_64Dived_1mSec_;    // 16MHz 클럭 64분주 일때 1mSec 발생
 #else
  TCNT0    = _Timer0_8M_64Dived_1mSec_;    // 8MHz 클럭 64분주 1mSec 발생
 #endif
 if(g_DelayValue > 0)    g_DelayValue--;

 if(g_DelayRun > 0)  g_DelayRun--;
 else{
  g_DelayRun = 500;
  g_Run_Flag = ~g_Run_Flag;
 
  if(g_Run_Flag)  SETBIT(PORTD,  _RUN_);
  else      CLEARBIT(PORTD, _RUN_);
 }

#ifdef _Is_KeyPressDisp_test_Proc
 if(TESTBIT(g_KeyStatus, 0)){
  if(TESTBIT(PINE, 6))  CLEARBIT(g_KeyStatus, 0);
 }
 if(TESTBIT(g_KeyStatus, 1)){
  if(TESTBIT(PINE, 5))  CLEARBIT(g_KeyStatus, 1);
 }
 if(TESTBIT(g_KeyStatus, 2)){
  if(TESTBIT(PINE, 4))  CLEARBIT(g_KeyStatus, 2);
 }
#endif
}
SIGNAL(SIG_OVERFLOW1){
  CLEARBIT(TIMSK, TOIE1);                // 타이머1 인터럽트 금지
 _g_CommanSelect++;
 _g_CommanSelect   %= _FndCommMaxLength_;
 #ifdef _Is_KeyPressDisp_test_Proc
  PORTA   = _ga_DispBUF[  _g_CommanSelect];
  PORTC   = _ga_FndComConst[_g_CommanSelect];    // FND Com 제어, 1개의 자리만 점등
 #endif

 TCNT1    = _TDELAY_;
  SETBIT(TIMSK, TOIE1);                  // 타이머1 인터럽트 허용
}
SIGNAL(SIG_OVERFLOW3){
 TCNT3   = 0xff-100;                // 8MHz / 8 /100 = 20KHz
}
SIGNAL(SIG_USART0_RECV){
 byte  i = UDR0;

 g_RxRingBuffer[g_RxTopCount++] = i;            // 수신 링 버퍼
 g_RxTopCount           %= _BufferLength_;
}
SIGNAL(SIG_INTERRUPT4){
 SETBIT(g_KeyStatus, 2);
}
SIGNAL(SIG_INTERRUPT5){
 SETBIT(g_KeyStatus, 1);
}
SIGNAL(SIG_INTERRUPT6){
 SETBIT(g_KeyStatus, 0);
}
void Init_Port(void){
// 1 일때 출력, 0 일때 입력으로 설정 된다
 DDRA  = 0xff;            // 모두 출력, FND 데이터 출력
 PORTA  = 0xff;            // 소등 데이터 출력
 DDRB    = (1<<_SS_)+(1<<_SCK_)+(1<<_MOSI_)+(1<<_PWM_A_)+(1<<_PWM_B_);
 PORTB  = (1<<_SS_)+(1<<_SCK_)+(1<<_MOSI_)+(1<<_PWM_A_)+(1<<_PWM_B_);
 DDRC    = 0xff;            // 전체출력
 PORTC  = 0xff;            // 세그먼트 공통 단자 끄기
 DDRD = (1<<_Tx1_)+(1<<_START_)+(1<<_CHOICE_)+(1<<_RUN_)+(1<<_BUZZER_)+(1<<_BUZZER_)+(1<<_PowerEnable_);
 PORTD = (1<<_Rx1_)+(1<<_Tx1_)+(1<<_START_)+ (1<<_RUN_)+(1<<_BUZZER_)+(1<<_BUZZER_)+(1<<_PowerEnable_);
 DDRE     =  (1<<_Tx0_)+(1<<_Set_)+(1<<_Up_)+(1<<_Down_)+(1<<_RTS_);
 PORTE  = (1<<_Rx0_)+(1<<_Tx0_)+(1<<_Set_)+(1<<_Up_)+(1<<_Down_)+(1<<_RTS_);
 DDRF    = 0x00;            // 전체입력
 PORTF  = 0x00;
}
void SystemInit(void){
 Init_Port();  
            
 SETBIT(SFIOR, TSM);          // 타이머 클럭 동기화 동작
                                      
  Init_timer0();              // mSec Delay 함수사용
  Init_timer1();              // FND 표시용
 Init_ADC();  
 Init_SPI();
 Init_USART(19200);

 Init_Ext_Int();
 CLEARBIT(MCUCSR, WDRF);
 wdt_enable(WDTR_1S);

  sei();
}
// 써미스터 부품 번호 : NTCALUGE2C90169
void Temp_Cal(void){
 word   Vo;      // 써미스터와 직렬로 연결 된 분압저항 중간에서 읽은 전압
 double R29 = 9729    // 써미스터와 직렬로 연결 되는 분압저항 값
 double Rt;
 double T, C;
 double Ro = 10000;    // 25도에서 NTC 저항 값
 double To = 298.15;   // 섭씨 25도 = 절대온도 298.15eh = 273.15 + C
 double B  = 3813;    // 물질 상수, 오차율 +- 0.5% 이하
#ifdef ADC_ISR_Load
 Vo = BubbleSort(_g_AdcTempBuffer, _AVERGE_NUMBER_);   // 온도센서 저항 값
#else
 Vo = Read_ADC();
#endif
 Rt      = R29 * ((1023.0/(double)Vo)-1.0);      // 온도센서 저항 측정, 1023 이 5V
 T       = 1.0/((1.0/To)+(1/B)*log((Rt/Ro)));      // B parameter를 이용한 온도 계산 방정식
 C       = T - 273.15;
 g_temp_float  = C;
 g_temp_float  = g_temp_float;
}
void Float_Str2FND(byte *ps){
 byte i=0, *pd;

 pd  = _ga_DispBUF;

 while(i < 6){
  if(*ps >= '0' && *ps <= '9')  *pd = _ga_FndFontConst[*ps - '0'];
  else{
   if(*ps == '.'){
    if(i){
     *pd--;
     *pd &= _DIGITE_Dot_;        // 소수점 생성
     i--;
    }
   }
   else{
    if(*ps == '-') *pd = _DIGITE_Minus_;   // - 생성
    else    *pd = 0;
   }
  }
  i++;
  *pd++;
  *ps++;
 }
 *pd++ = 0;
}
void Temp_Display(void){
 dtostrf(g_temp_float, 3 ,5, string);
 Float_Str2FND(string);
}
void Task_Temp(void){
 Temp_Cal();
 Temp_Display();
}
void main(void){
 SystemInit();
 Task_Temp();
 while(1){
  Task_Temp();
  Delay_xMs(250);
  wdt_reset();
 }
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#define _FCPU_8MHz_          8000000UL
//#define _FCPU_16MHz_        16000000UL
 #ifdef _FCPU_16MHz_
  #define _FCPU_          _FCPU_16MHz_
 #else  
  #define _FCPU_          _FCPU_8MHz_
 #endif 
#define WDTR_15MS  0
#define WDTR_30MS  1
#define WDTR_60MS  2
#define WDTR_120MS 3
#define WDTR_250MS 4
#define WDTR_500MS 5
#define WDTR_1S   6
#define WDTR_2S   7
#define _Timer0_16M_64Dived_1mSec_  0xff-((_FCPU_/64)/1000)       // 255-((16000000/64)/1000) = 5
#define _Timer0_8M_64Dived_1mSec_    0xff-((_FCPU_/64)/1000)       // 255-((8000000 /64)/1000) = 130
#define ADC_BubbleSort_Enable
#define ADC_Convert_Enable
#define ADC_ISR_Load
                                
#define byte          unsigned char  
#define word            unsigned int
#define dword int         unsigned long
#define SETBIT(  ADDRESS, BIT) (ADDRESS |=  (1<#define CLEARBIT(ADDRESS, BIT)  (ADDRESS &= ~(1<#define TESTBIT( ADDRESS, BIT)  (ADDRESS &   (1<
typedef union{
  byte      b_Value[2];
  unsigned long W_Value;
}W2b;
W2b ConvWB;
typedef union{
  byte      b_Value[4];
  unsigned long L_Value;
}L4b;
L4b ConvLB;
L4b integ;
typedef union{
  byte      b_Value[8];
  unsigned long L_Value[2];
  double     d_Value;
}D8b;
D8b Double_64bit;
#define _Is_KeyPressDisp_test_Proc
#define _SegA_        0x01
#define _SegB_        0x02
#define _SegC_        0x04
#define _SegD_        0x08
#define _SegE_        0x10
#define _SegF_        0x20
#define _SegG_        0x40
#define _SegDp_        0x80
#define _DIGITE_0_      ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegE_ + _SegF_)
#define _DIGITE_1_      ~(_SegB_ + _SegC_)
#define _DIGITE_2_      ~(_SegA_ + _SegB_ + _SegD_ + _SegE_ + _SegG_)
#define _DIGITE_3_      ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegG_)
#define _DIGITE_4_      ~(_SegB_ + _SegC_ + _SegF_ + _SegG_)
#define _DIGITE_5_      ~(_SegA_ + _SegC_ + _SegD_ + _SegF_ + _SegG_)
#define _DIGITE_6_      ~(_SegA_ + _SegC_ + _SegD_ + _SegE_ + _SegF_ + _SegG_)
#define _DIGITE_7_      ~(_SegA_ + _SegB_ + _SegC_ + _SegF_)
#define _DIGITE_8_      ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegE_ + _SegF_ + _SegG_)
#define _DIGITE_9_      ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegF_ + _SegG_)
#define _SPACE_        ~0
#define _b_          ~(_SegC_ + _SegD_ + _SegE_ + _SegF_ + _SegG_)
#define _a_          ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegE_ + _SegG_)
#define _A_          ~(_SegA_ + _SegB_ + _SegC_ + _SegE_ + _SegF_ + _SegG_)
#define _t_          ~(_SegD_ + _SegE_ + _SegF_ + _SegG_)
#define _E_          ~(_SegA_ + _SegD_ + _SegE_ + _SegF_ + _SegG_)
#define _R_          ~(_SegA_ + _SegB_ + _SegC_ + _SegE_ + _SegF_ + _SegG_)
#define _r_          ~(_SegE_ + _SegG_)
#define _S_          ~(_SegA_ + _SegC_ + _SegD_ + _SegF_ + _SegG_)
#define _y_          ~(_SegB_ + _SegC_ + _SegF_ + _SegG_)
#define _C_          ~(_SegA_ + _SegD_ + _SegE_ + _SegF_)
#define _h_          ~(_SegC_ + _SegE_ + _SegF_ + _SegG_)
#define _g_          ~(_SegA_ + _SegB_ + _SegC_ + _SegD_ + _SegF_ + _SegG_)
#define _DIGITE_Dot_     ~_SegDp_
#define _DIGITE_Minus_    ~_SegG_
#define _TDELAY_        65535-4000
#define _FndCommMaxLength_   6
static  byte _g_CommanSelect   = 0;
   byte _ga_DispBUF[_FndCommMaxLength_ + 1]= {0, };
const  byte _ga_FndFontConst[] = {_DIGITE_0_, _DIGITE_1_, _DIGITE_2_, _DIGITE_3_, _DIGITE_4_,
                                    _DIGITE_5_, _DIGITE_6_, _DIGITE_7_, _DIGITE_8_, _DIGITE_9_, 0 };
const  byte _ga_FndComConst[]  = {~0x08, ~0x10, ~0x20, ~0x01, ~0x02, ~0x04, 0xff, 0};
// PORTA
 #define _Sag_A_       0
 #define _Sag_B_       1
 #define _Sag_C_       2
 #define _Sag_D_       3
 #define _Sag_E_       4
 #define _Sag_F_       5
 #define _Sag_G_       6
 #define _Sag_P_       7

// PORTB
 #define _SS_         0
 #define _SCK_         1
 #define _MOSI_       2
 #define _MISO_       3
 #define _PWM_A_       4
 #define _PWM_B_       5
 #define _DSR_         6
 #define _DCD_         7

// PORTC
 #define _COM0_       0
 #define _COM1_       1
 #define _COM2_       2
 #define _COM3_       3
 #define _COM4_       4
 #define _COM5_       5
 #define _COM6_       6
 #define _COM7_       7

// PORTD
 #define _START_         0
 #define _CHOICE_        1
 #define _Rx1_          2
 #define _Tx1_          3
 #define _RUN_          4
 #define _BUZZER_        5
 #define _PowerEnable_         6
 #define _CTS_          7

// PORTE
 #define _Rx0_         0
 #define _Tx0_         1
 #define _Ain0_         2
 #define _Ain1_         3
 #define _Set_         4
 #define _Up_         5
 #define _Down_       6
 #define _RTS_         7

// PORTF
 #define _Adc0_       0
 #define _Adc1_       1
 #define _Adc2_       2
 #define _Adc3_       3
 #define _TCK_         4
 #define _TMS_         5
 #define _TDO_        6
 #define _TDI_         7
#define _AVERGE_NUMBER_   6
#ifdef ADC_BubbleSort_Enable
 word  _g_AdcTempBuffer[_AVERGE_NUMBER_+1]   = {0, };
 byte _g_AdcTempBufCount = 0;
#endif
byte g_Run_Flag     = 0;
word g_DelayRun     = 0;
word g_DelayValue        = 0;
word gw_Delay_10uSec     = 0;
                                
//=========== 232 통신 관련 ===========================================================
#define _NUL_             0x00
#define _BufferLength_   100
#define _STX_              0x02
#define _ETX_      0x03
#define _ACK_      0x06
#define _NAK_      0x15
//=========== SPI 통신 관련 ===========================================================
byte g_Flag_SPI_TxStatus = 0;
byte g_RxRingBuffer[_BufferLength_+1] = {0, };
byte g_WorkBuf[20]   = {0, };
byte g_TxBuf[20]    = {0, };
byte g_RxEnd     = 0;
byte g_RxTopCount   = 0;
byte g_RxButtomCount  = 0;
//=========== 공용  ===========================================================
#define _Err_OpenTempSenser_    1
byte *str;
byte g_KeyStatus    = 0;
byte string[20]    = {0, };
double g_temp_float  = 0;

댓글 없음:

댓글 쓰기