비교사항

 

ADUC831은 ADUC812의 업그레이드 버전이라고 할 수 있습니다. 그래서 ADUC812와 ADUC831의 다른 부분 중 중요한 부분을 설명 드리고자 합니다.

 

내용

ADUC812 

ADUC831 

ADC 속도

최대 200ksps

최대 247ksps

Flash program memory

8k 

62k 

Flash/EE data memory 

640byte 

4kbyte 

Data ram 

256byte 

2304byte

기본 256byte

내부확장 2048 byte

Stack 이동

불가

가능

PWM 

없음

2개

DPTR 

1개

2개

 

위 표와 같이 메모리 관련하여 양이 많이 증가한 것을 볼 수 있습니다. 그래서 기존에 ADUC812를 사용하면서 메모리가 부족했던 점이 많이 줄어 들었습니다.

 

위 표에서는 설명 드리지 않았지만 ADC기능이 많이 추가 되었습니다. ADC 기능은 추후 다시 설명 드리겠습니다. 그리고 2 체널의 PWM이 추가되었으며 부분적으로 수정된 기능이 많이 있습니다. 예를 들어 Timer3와 같이 UART전용 타이머가 추가되었으며, RTC로 대신 사용 가능한 TIC가 있으며, DPTR이 2개가 되었으며, STACK 포인트도 이동이 가능한 것을 들 수 있습니다. 아래 그림 중 색칠이 되어 있는 블록 부분을 보시면 되겠습니다.

 

'공부 > 8051' 카테고리의 다른 글

[ADUC831] ADUC831 간단 매뉴얼 4  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 3  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 1  (0) 2012.11.12
[ADUC812] ADUC812 설명 8  (0) 2012.11.10
[ADUC812] ADUC812 설명 7  (0) 2012.11.10

 

시작 하기 전에

 

8051 core를 사용한 수많은 MCU 중에서 아날로그 디바이스에서 판매되는 ADUCxxx군은 아날로그 기능이 강화된 프로세서 군입니다. 이번에 소개하는 ADUC831은 ADUC812가 업그레이드 된 칩이라고 생각하면 됩니다.

그래서 ADUC812 Manual을 먼저 참고하시길 바랍니다. ADUC831을 사용하거나 공부할 때 좋은 참고 자료가 되었으면 좋겠습니다. 물론 부족하거나 잘못된 부분이 많지 않을까 합니다. 좀더 자세한 내용이 필요하신 분은 아날로그 디바이스사에서 제공하는 문서를 참고해 주시길 바랍니다. 감사합니다.

'공부 > 8051' 카테고리의 다른 글

[ADUC831] ADUC831 간단 매뉴얼 3  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 2  (0) 2012.11.12
[ADUC812] ADUC812 설명 8  (0) 2012.11.10
[ADUC812] ADUC812 설명 7  (0) 2012.11.10
[ADUC812] ADUC812 설명 6  (0) 2012.11.10

 

SOURCE 공개

 

1. I2C용 RTC S3530A 루틴

 

//-------- S3530A STATUS REG -----------

#define    S3530_REG_INT2FE_BIT    0x01        //INT2 level interrupt set

#define    S3530_REG_INT1FE_BIT    0x02        //INT1 level interrupt set

#define    S3530_REG_INT2ME_BIT    0x04        //INT2 edge interrupt

#define    S3530_REG_INT1ME_BIT    0x08        //INT2 edge interrupt

#define    S3530_REG_INT2AE_BIT    0x10 //INT2 interrupt output enable(1), disabled(0).

#define    S3530_REG_INT1AE_BIT    0x20 //INT1 interrupt output enable(1), disabled(0).

#define    S3530_REG_1224_BIT    0x40 //12(0), 24(1) time mode set

#define    S3530_REG_POWER_BIT    0x80 //Power Status, Normal(1), Fail(0)

 

typedef    struct{    

        _uchar    your;

        _uchar    mon;

        _uchar    day;

        _uchar    day_week;

        _uchar    time;

        _uchar    min;

        _uchar    sec;

        _uchar    reg;

        

}_rtc;

 

 

xdata _rtc rtc_temp;    //data를 읽은 원본,data를 저장할때 쓰는 버퍼

xdata _rtc rtc;

 

void rtc_time_read()

{

    i2c_start();

    i2c_write(0x65);      //access 1 mode

    rtc_temp.your = i2c_read(YES);

    rtc_temp.mon = i2c_read(YES);

    rtc_temp.day = i2c_read(YES);

    rtc_temp.day_week = i2c_read(YES);

    rtc_temp.time = i2c_read(YES);

    rtc_temp.min = i2c_read(YES);

    rtc_temp.sec = i2c_read(NO);

    i2c_stop();

 

    //data 가공

    rtc_temp.your = by_byte(rtc_temp.your);

    rtc_temp.mon = by_byte(rtc_temp.mon);

    rtc_temp.day = by_byte(rtc_temp.day);

    rtc_temp.day_week = by_byte(rtc_temp.day_week);

    rtc_temp.time = by_byte(rtc_temp.time);

    if(rtc_temp.time & 0x80) //상위 bit 1이면 12시간 제의 오후

    {

        rtc_temp.time = rtc_temp.time & 0x7F;

        //rtc_temp.time = rtc_temp.time + 11; //24시간 형태로 변경

        

    }

 

    rtc_temp.min = by_byte(rtc_temp.min); //Control register

    rtc_temp.sec = by_byte(rtc_temp.sec) & 0x7F; //Control register

 

    //data 버퍼에 복사

    rtc.your= rtc_temp.your;

    rtc.mon= rtc_temp.mon;

    rtc.day= rtc_temp.day;

    // //p_sts.rtc_time[3] = rtc.day_week = rtc_temp.day_week;

    rtc.time = rtc_temp.time;

    rtc.min = rtc_temp.min; //Control register

    rtc.sec = rtc_temp.sec; //Control register

 

 

}

 

/*

* 레지스터 내용

* bit 7 : 1(전원 들어옴) ,read only

* bit 6 : 0(12시간제) , 1(24시간제)

* bit 5 : /INT1 동작, 0(동작안함), 1(동작함)

* bit 4 : /INT2 동작, 0(동작안함), 1(동작함)

* bit 3 : 인터럽트 동작 설정 찾아서 해보길

* bit 2 :

* bit 1 :

* bit 0 :

*/

 

void rtc_reg_read()

{

    i2c_start();

    i2c_write(0x65);      //access 1 mode

     _nop_ ();

    rtc_temp.reg = i2c_read(NO);

    _nop_ ();

    i2c_stop();

    rtc.reg = by_byte(rtc_temp.reg); //Control register

 

}

 

//RTC 데이터 쓰기.....

void rtc_time_write()

{

 

    rtc_temp.your = by_byte(rtc_temp.your);

    rtc_temp.mon = by_byte(rtc_temp.mon);

    rtc_temp.day = by_byte(rtc_temp.day);

    //rtc_temp.day_week = by_byte(rtc_temp.day_week);

    rtc_temp.time = by_byte(rtc_temp.time);

    rtc_temp.min = by_byte(rtc_temp.min);

    rtc_temp.sec = by_byte(rtc_temp.sec);

 

 

    i2c_start();

    i2c_write(0x64);      //access 1 mode

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.your);

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.mon);

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.day);

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.day_week);     //주의 어떻게 될지 모름

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.time);

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.min);

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.sec);

     _nop_ ();

     _nop_ ();

    i2c_stop();

 

}

 

// RTC초기화 부분.. 상태register 에 쓰는부분....

void rtc_reg_write()

{

    rtc_temp.reg = by_byte(rtc_temp.reg);

 

    i2c_start();

    i2c_write(0x62);      //access 1 mode

     _nop_ ();

     _nop_ ();

    i2c_write(rtc_temp.reg);

     _nop_ ();

     _nop_ ();

    i2c_stop();

}

 

void rtc_init()

{

    rtc_temp.reg = S3530_REG_1224_BIT;    //rtc초기화

    rtc_reg_write();

}

 

//상위비트와 하위 비트를 바꾸어 준다.

unsigned char by_byte(unsigned char in_data)

{

    unsigned char i,temp_data, out_data = 0;

    bit k;

 

    for(i=0 ; i<8 ;i++)

    {

 

        k = ((in_data & 0x80) ? 1 : 0); //msb data

        in_data <<= 1;     // Shift the byte by one bit

        temp_data = 0;

        temp_data |= k;        //lsb data

        temp_data <<= i;

        out_data |= temp_data;

    }

 

    return out_data;

}

'공부 > 8051' 카테고리의 다른 글

[ADUC831] ADUC831 간단 매뉴얼 2  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 1  (0) 2012.11.12
[ADUC812] ADUC812 설명 7  (0) 2012.11.10
[ADUC812] ADUC812 설명 6  (0) 2012.11.10
[ADUC812] ADUC812 설명 5  (0) 2012.11.10

 

SOURCE 공개

1. 공개 I2C 처리루틴

 

#define HIGH                1

#define LOW                0

 

#define TRUE                1

#define FALSE                0

 

//------------------------------------------------------------------------------

// I2C Functions - Master

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

//     Routine:    i2c_init

//    Inputs:    none

//    Outputs:    none

//    Purpose:    Initialize I2C for the ADu812C

//------------------------------------------------------------------------------

void i2c_init (void)

{

                    // To initialize we need the output

                    // data high, the clock high, and

                    // the I2C system in Master mode

    I2CM = HIGH;            // Set master mode

    MDO = HIGH;            // Set the data bit to HIGH

    MDE = FALSE;            // We are not using the pin yet

    MCO = HIGH;            // Set the clock bit to HIGH

}

 

//------------------------------------------------------------------------------

//     Routine:    i2c_start

//    Inputs:        none

//    Outputs:    none

//    Purpose:    Sends I2C Start Trasfer - State "B"

//------------------------------------------------------------------------------

void i2c_start (void)

{

                // An I2C start sequence is defined as

                // a High to Low Transistino on the data

                // line as the CLK pin is high

    MDE = TRUE;        // Master Mode Data Output Enable: ON

    MDO = HIGH;

    MCO = HIGH;

    MDO = LOW;        // Master Mode Data Output: LOW

    MDO = LOW;        // Repeat for delay

    MCO = LOW;        // Master Mode Clock Output: LOW

}

 

//------------------------------------------------------------------------------

//     Routine:    i2c_stop

//    Inputs:        none

//    Outputs:    none

//    Purpose:    Sends I2C Stop Trasfer - State "C"

//------------------------------------------------------------------------------

void i2c_stop (void)

{

                // An I2C start sequence is defined as

                // a Low to High Transistino on the data

                // line as the CLK pin is high

    MDE = TRUE;        // Master Mode Data Output Enable: ON

    MDO = LOW;        // Master Mode Data Output: LOW

    MCO = HIGH;        // Master Mode Clock Output: HIGH

    MCO = HIGH;        // Repeat for delay

    MDO = HIGH;        // Master Mode Data Output: LOW

}

 

//------------------------------------------------------------------------------

//     Routine:    i2c_write

//    Inputs:        output byte

//    Outputs:    none

//    Purpose:    Writes data over the I2C bus MSB -> LSB write

//------------------------------------------------------------------------------

bit i2c_write (unsigned char output_data)

{

    unsigned char index;

                    // An I2C output byte is bits 7-0

                    // (MSB to LSB). Shift one bit at a time

                    // to the MDO output, and then clock the

                    // data to the I2C Slave

 

    MDE = TRUE;            // Master Mode Data Output Enable: ON

    for(index = 0; index < 8; index++)     // Send 8 bits out the port

    {

    // Output the data bit to the EEPROM

        MDO = ((output_data & 0x80) ? 1 : 0);

        output_data <<= 1;     // Shift the byte by one bit

        MCO = HIGH;         // Clock the data into the EEPROM

        MCO = HIGH;         // Repeat for delay

        MCO = LOW;                    

    }

 

    MDE = FALSE;            // Put data pin into read mode

    MCO = HIGH;            // Get ACK bit

    if (!MDI)

    {

        MCO = LOW;        // Clock Low

        return TRUE;        // ACK from slave

    }

    else

    {

        MCO = LOW;        // Clock Low

        return FALSE;        // No ACK

    }

}

 

//------------------------------------------------------------------------------

//     Routine:    i2c_read

//    Inputs:        send_ack (if TRUE send the ACK signal)

//    Outputs:    input byte

//    Purpose:    Reads data from the I2C bus MSB -> LSB read

//------------------------------------------------------------------------------

unsigned char i2c_read (bit send_ack)

{

    unsigned char index, input_data;

 

    input_data = 0x00;

 

    MDE = FALSE;                // Put data pin into read mode

    MCO = LOW;                // Set clock LOW

 

    for(index = 0; index < 8; index++)     // Get 8 bits from the device

    {

    input_data <<= 1;            // Shift the data right 1 bit

        MCO = HIGH;            // Clock the data into the register

        MCO = HIGH;            // Repeat for delay

        MCO = LOW;                            

        input_data |= MDI;        // Read the data bit

    }

    

    MDE = TRUE;                // Put data pin into write mode

    if (send_ack) MDO = LOW;        // Set data pin LOW to Ack the read

    else MDO = HIGH;            // Set data pin HIGH to Not Ack the read

 

    MCO = HIGH;                // Set the clock pin HIGH

    MCO = HIGH;                // Repeat for delay

    MCO = LOW;                // Set the clock pin LOW

    MDO = LOW;                // Set the data pin LOW

    MDO = LOW;                // Repeat for delay

    MDE = LOW;                // Put data pin into read mode

 

    return input_data;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'공부 > 8051' 카테고리의 다른 글

[ADUC831] ADUC831 간단 매뉴얼 1  (0) 2012.11.12
[ADUC812] ADUC812 설명 8  (0) 2012.11.10
[ADUC812] ADUC812 설명 6  (0) 2012.11.10
[ADUC812] ADUC812 설명 5  (0) 2012.11.10
[ADUC812] ADUC812 설명 4  (0) 2012.11.10

 

SOURCE 공개

매뉴얼을 보시는 분에게 약간의 SOURCE를 공개 하겠습니다. 사용 하실 분은 하세요.

keil 컴파일러를 기준으로 작성 되어 있습니다.

1. ADC , DAC 초기화

 

#define OSC         14745600.0

#define NOR_OSC_DIVIDE        12

#define HIGH_BYTE(n) ((char)(n >> 8))

#define LOW_BYTE(n) ((char)(n & 0xff))

 

 

void OpenADC(int ms, char dac_onoff) /* LAUNCH ADC CONVERSIONS */ // --> adc

{

xdata unsigned int TM;

EADC = 0; // disable adc

ADCCON1 = 0x62;    // 0,1, 1,0, 0,0, 1,0

            // normal mode,adc_ clk=x_clk/4,획득시간, timer2 interrupt enable

            //adc_clk 는 osc클럭을 몇분주 해서 처리할껀지를 본다

            //획득시간은 한개의 data를 읽어 들이기 위한 민감도조절로

            //입력 포트의 누설 전류를 감안해야 하며 누설전류가 1m 에서 610옴

            //10m에서 61옴이다. 입력측 임피던스가 적으면 1개의 주기로도 상관이

            //없지만 임피던스가 커지면 내부 콘덴서 누설을 감안해 설정을 늘려야 한다.

ADCCON2 = 0x00 ; // sellect chan#8 = temp chanal (초기 체널값)

 

TM = 0x10000 - (_uint)((ms * 1000.0) / (NOR_OSC_DIVIDE/(OSC/1000000.0)));

TH0 = HIGH_BYTE(TM);

TL0 = LOW_BYTE(TM);

                            

RCAP2L = TL0 ; // timer2 인터럽트 걸린후 자동 타이머 셋팅값 (rcap2l, rcap2H)

RCAP2H = TH0 ;

 

TL2 = TL0 ;

TH2 = TH0 ;

 

if(dac_onoff == 1) DACCON=0x1F;     

    //DAC mode : 12bit,DAC1(0-Vref),DAC0(0-Vref),DAC1 output normal,DAC0 output normal

    //,DACxL upload => output change, DAC1 power on , DAC0 power off

 

EADC = 1;            //enable ADC interrupt

TR2 = 1;            //T2CON = 0x04 ; // run Timer2

}

 

 

1. ADC 처리루틴

 

#define ADC_MAX_CH 5 //입력되는 체널

 

xdata int ADC_BUF_VLT[ADC_MAX_CH]; //중간값 저장

xdata int ADC_CNV_VLT[ADC_MAX_CH]; //전압값 저장

xdata char adc_end = 0; //외부에 인터럽트 처리 완료

 

void adc_int() interrupt 6 { // int6*8+3 = 51dec = 33hex = ADCI

 

    unsigned char ch_chk;

    

    int add_DA_M;        //

    int add_DA_R;

 

    if( (ADCCON3 & 0x80) == 0x80 ) return; //adconverting..

    if(ch_chk<4) add_DA_M = (((ADCDATAH & 0x0F) <<8 ) | ADCDATAL);

//add AD converter value

    else add_DA_M = (((ADCDATAH & 0x0F) <<8 ) | ADCDATAL);

//add AD converter value

    

    if(add_DA_M < 0) add_DA_M=0;

    add_DA_R = (int)((250.0/4096.0*(add_DA_M))*2.0);

// Calculation = (reference/step) * converting values

    ch_chk = (ADCDATAH >> 4) & 0x0F;

    ADC_BUF_VLT[ch_chk] = (ADC_BUF_VLT[ch_chk] + add_DA_R)/2 ;

    ch_chk++;

 

    if(ch_chk >= ADC_MAX_CH)

    {

    ch_chk = 0 ;

    adc_end ++;    //adc 한번 변환이 끝났다고 알려줌

    }

 

    ADCCON2 = ch_chk;

}

 

 

 

 

 

 

 

'공부 > 8051' 카테고리의 다른 글

[ADUC812] ADUC812 설명 8  (0) 2012.11.10
[ADUC812] ADUC812 설명 7  (0) 2012.11.10
[ADUC812] ADUC812 설명 5  (0) 2012.11.10
[ADUC812] ADUC812 설명 4  (0) 2012.11.10
[ADUC812] ADUC812 설명 3  (0) 2012.11.10

 

4) 내부 Flash/EE DATA Memory 사용

 

내부 Flash/EE DATA Memory는 ADUC812만의 특이한 점이 있습니다. 총 640byte의 메모리를 가지고 있고 4개의 바이트는 하나의 페이지로 관리됩니다. 다시 말해 1byte를 읽거나 쓰기 위해서 4개의 바이트를 처리해야 된다는 말일수도 있지요.

 

레지스터중에 EADRL 이라는 것이 있습니다. 여기에 들어갈 수 있는 값은 0H에서 9FH까지입니다. 눈치 빠르신 분은 이 레지스터가 내부 Flash/EE DATA Memory 의 주소를 나타낸다는 것을 바로 아셨을 겁니다. 한 개의 주소를 선택함으로서 4byte에 대한 처리가 가능하게 됩니다. 4개의 바이트는 각각 EDATA1,EDATA2,EDATA3,EDATA4에 의해 관리가 됩니다.

각각의 (읽거나 쓰는)작업을 위해서는 ECON이라는 레지스터에 명령어를 주어 처리를 합니다. ECON을 살펴보죠

 

명령

내역

01H

READ COMMAND

02H

WRITE COMMAND

03H

RESERVED

04H

VERIFY COMMAND

05H

ERASE COMMAND

06H

ERASE ALL COMMAND

ECON

실제 사용하는 명령어를 살펴보죠 (어셈불러입니다.)

MOV    EADRL, #03H    ;페이지를 설정합니다.

MOV    ECON,#01H    ;DATA를 읽어 들입니다.

MOV    EDATA1, #01H    ;EDATA1에 01h값을 넣습니다.

MOV    EDATA2, #02H    ;EDATA2에 02h값을 넣습니다.

MOV    EDATA3, #03H    ;EDATA3에 03h값을 넣습니다.

MOV    EDATA4, #04H    ;EDATA4에 04h값을 넣습니다.

MOV    ECON,    #02H    ;설정된 주소의 페이지를 지움니다.

MOV    ECON,    #05H    ;DATA 저장하기

 

제 부족한 매뉴얼을 읽어주셔서 감사합니다. 아직 모든 기능을 사용해 보지 못한 관계로 부족한 부분이 많이 있습니다. 더욱 자세한 내용은 8051 책자 또는 www.analog.com을 참고하시기 바랍니다.

'공부 > 8051' 카테고리의 다른 글

[ADUC812] ADUC812 설명 7  (0) 2012.11.10
[ADUC812] ADUC812 설명 6  (0) 2012.11.10
[ADUC812] ADUC812 설명 4  (0) 2012.11.10
[ADUC812] ADUC812 설명 3  (0) 2012.11.10
[ADUC812] ADUC812 설명 2  (0) 2012.11.10

 

4) DAC

 

ADUC812칩에는 2개의 DAC가 있습니다. 어떻게 이것을 사용할수 있을까요

DAC는 1개의 Control 레지스터와 1개의 DAC포트당 2개의 출력값 설정용 레지스터 2개씩 있습니다. 그럼 간단하게 이 레지스터를 살펴보겠습니다.

 

DACCON SFR

SFR Address : FDH , SFR Power On Default Value : 04H

bit Addressable : NO

 

BIT7

MODE

1: 8bit mode (DACxL만 사용)

0: 12bit mode

BIT6

REG1

1: DAC1 출력범위 0-VDD

0: DAC1 출력범위 0-Vref

BIT5

REG0

1: DAC0 출력범위 0-VDD

0: DAC0 출력범위 0-Vref

BIT4

CLR1

0: DAC1 출력을 0V로 만든다.

1: Normal

BIT3

CLR0

0: DAC0 출력을 0V로 만든다.

1: Normal

BIT2

SYNC

1: DACxL 에 값을 입력하면 바로 레지스터의 값이 출력된다.

0: DACxL 또는 DACxH 중 하나라도 변경되면 출력

BIT1

PD1

1: DAC1 Power on

0: DAC1 Power off

BIT0

PD0

1: DAC0 Power on

0: DAC0 Power off

 

사용방법을 예를 들자면 프로그램 시작부분에서 기본값을 00011111을 SETTING 한후

DAC0에 출력하기 위해서 DAC0H에 값을 넣고 DAC0L에 값을 넣으면 설정한 값이 바로 출력된다.

DACCON=0x1F;     //DAC mode : 12bit,DAC1(0-Vref),DAC0(0-Vref),DAC1

//output normal,DAC0 output normal

         //,DACxL upload => output change, DAC1 power on ,

// DAC0 power on

     DAC0H = 0x0F;

     DAC0L = 0xFF;

     DAC1H = 0x0F;

     DAC1L = 0xFF;

'공부 > 8051' 카테고리의 다른 글

[ADUC812] ADUC812 설명 6  (0) 2012.11.10
[ADUC812] ADUC812 설명 5  (0) 2012.11.10
[ADUC812] ADUC812 설명 3  (0) 2012.11.10
[ADUC812] ADUC812 설명 2  (0) 2012.11.10
[ADUC812] ADUC812 설명 1  (0) 2012.11.10

 

3) ADC

ADUC812 의 가장 큰 특징중에 하나는 ADC와 DAC를 내부적으로 가지고 있다는 거지요

이번에는 이 ADC와 DAC를 사용하는 방법을 소개할까 합니다.

 

ADUC812내부에는 12bit 8체널의 ADC를 가지고 있습니다. 12bit ADC를 사용하기 위해서는 기준 되는 전압을 정의해야 합니다. 그렇지 않으면 ADUC812가 전압을 어떻게 사용할지 모르니까요.

 

매뉴얼을 살펴보면 알겠지만 ADUC812 내부에는 2.5V의 레퍼런스가 들어 있습니다. 내부 레퍼런스를 사용할 경우 아날로그 input 가능범위는 0V-Vref 까지 즉 0V-2.5V까지죠 물론 외부 레펀런스도 사용 가능합니다. 외부 레퍼런스입력범위는 2.3V - AVDD까지입니다. AVDD를 3V로 쓰면 외부 레퍼런스전압은 2.3V-3V까지 가능하겠죠 만약 AVDD를 5V로 사용하신다면 외부 레퍼런스전압은 2.3V-5V까지 조정이 가능합니다.

 

그럼 ADC 시작은 언제부터 가능한 걸까요 이것은 CONVST핀(25번핀)을 사용하는 것에 따라 틀려집니다. 만약 CONVST핀을 사용한다면 이 핀에 'L'가 인가되면 동작을 하게 되어 있지요. 이 핀을 사용 안하면 어떻게 동작을 시킬까요 "1) 간단한 ADUC812칩의 특징"을 잘 살펴 보신분은 금방 이해가 될 겁니다. 키 포인트는 바로 타이머 2인터럽트죠. 타이머2 인터럽트의 시간을 설정하고 이 타이머 2인터럽트가 발생하면 ADC를 시작하고 컴버트가 끝나면 ADC인터럽트가 발생을 하게 됩니다. 그 다음에 인터럽트에 대한 처리를 하면 되겠죠.

 

ADC변환값에 대한 DMA처리가 가능하니까 DMA를 지원하는 외부 MCU나 CPU를 사용하신다면 이 기능을 활용해 보는 것도 좋을듯하군요

 

여기서 한가지를 집고 넘어가야겠군요 ADUC812의 9번째 아날로그신호는 온도센서입니다. 이 온도센서는 600mA일 때 25도이며 1도 상승시 마다 -3mA가 줄어듭니다. 만약 온도가 하강하면 +3mA가 증가하겠죠.

그럼 ADC에 관련된 레지스터를 살펴봅시다. 레지스터를 모르고 프로그램을 할 방법은 없겠죠.

 

ADDCCON1 (ADC Control SFR #1)

이 레지스터는 ADC의 기능을 설정하는 놈입니다.

어드레스 : EFH , 파워 온 시 기본값 : 20H , BIT단위 제어 불가능

BIT7

MD1

MODE BIT

MD1 MD0

0 0 : ADC 파워 다운

0 1 : ADC 표준모드

1 0 : Conversion cycle 사용하지 않으면 ADC 파워다운

1 1 : Conversion cycle 사용하지 않으면 ADC 대기상태

BIT6

MD0

BIT5

CK1

ADC 계산 분주율을 설정합니다.

CK1 CK0 MCLK DIVIDER

0 0 : 1

0 1 : 2

1 0 : 4

1 1 : 8

BIT4

CK0

BIT3

AQ1

얻어지는 신호(이전신호와 지금신호)를 고르게 얻기위한 값으로 사용된다.(몇번 ADC를 하고 받을것인지 설정)

AQ1 AQ0 #ADC Clks

0 0 1

0 1 2

1 0 3

1 1 4

 

입력된 source 저항이 8k 이하면 00으로 선택하고 그이상이면 다른 값으로 선택한다.

BIT2

AQ0

BIT1

T2C

타이머 2를 사용할건지를 선택한다.

BIT0

EXC

CONVST를 사용할것인지 석택한다.

선택시 CONVST 신호가 low active일때 동작한다.

CONVST는 100ns보다 pulsewidth를 사용해야 한다.

 

ADCCON2(ADC Control SFR #2)

SFR Address : D8H , SFR Power On Default Value

Bit 제어 : YES

BIT7

ADCI

ADC 변환후 SET되며 인터럽트 루틴으로 점프한다.

인터럽트 처리가끝나면 자동으로 지워진다.

BIT6

DMA

DMA를 사용가능하도록 해준다

BIT5

CCONV

계속해서 ADC를 하도록 SET한다.

BIT4

SCONV

한번의 변화만 하기위해 SET하며 변화가 끝나면 0로 된다.

BIT3

CS3

변환해야될 체널을 선택한다.

CS3 CS2 CS1 CS0 선택된체널

0 0 0 0 0

0 0 0 1 1

0 0 1 0 2

0 0 1 1 3

0 1 0 0 4

0 1 0 1 5

0 1 1 0 6

0 1 1 1 7

1 0 0 0 Temp Sensor

1 X X X Other Combinations

1 1 1 1 DMA STOP

BIT2

CS2

BIT1

CS1

BIT0

CS0

 

ADCCON3(ADC Control SFR #3)

SFR Address : F5H , SFR Power On Default Value : 00H

Bit 제어 : NO

 

BIT7

BUSY

ADC 처리중일 BUSY 가 1로되 처리가 안끝났다고 알려준다.

BIT6

 

RESERVED

BIT5

 

BIT4

 

BIT3

 

BIT2

 

BIT1

 

BIT0

 

 

위에 제어 비트들을 살펴보았다면 Reference 인터페이스 부분을 다시 한번 살펴보아야 하겠죠. 만약 내부 레퍼런스를 사용한다면 Vref 와 Cref핀에 100nF의 Capacitor를 달아주어야 합니다.

외부 레퍼러스의 경우 전에 말씀드렸듯이 사용가능 범위는 2.3V-AVDD까지며 이때는 Cref에 100nF의 Capacitor를 달아주어야 하며, 내부 레퍼런스의 오차범위는 ±50mV입니다.

 

변환된 값은 어디에 저장되는지 알아야 실제 그 값을 가지고 다른 처리가 가능하겠죠. 처리된 값은 ADCDATAH 와 ADCDATAL에 저장됩니다.

ADCDATAH의 상위 4bit(bit7-bit4)에는 처리된 채널 번호가 들어가고 하위 4bit(bit3-bit0)에는 12bit 처리된 값중에 상위 4bit가 들어갑니다. ADCDATAL는 나머지 하위 8bit가 저장 됩니다.

 

ADCDATAH

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

CH ID(현재 읽어들인 체널값)

상위 4bit

 

ADCDATAL

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

하위 8bit

 

그러면 읽어들인 값을 가지고 어떻게 계산을 해야 할까요

Keil C 컴파일러에서 처리한 C소스 예제입니다. 레인지가 0V에서 2.5V (물론 내부 레퍼런스를 사용했을 때입니다) 이고, ADC 가 12bit이니까 총 STEP은 4096 이 됩니다. 계산을 하기위해 0V를 0으로 2.5V를 2500으로 처리하면

 

int DA_ADD;        

int DA_C;

 

DA_ADD = ((ADCDATAH & 0x0F) <<8 ) | ADCDATAL; //add AD converter value

DA_C =(int)((2500.0/4096.0)*add_DA_M); // Calculation = (reference/step) * converting value

ADCDATAH 의 하위 바이트만 읽어 들인 후 8Bit를 상위 바이트로 밀고 이 값에 하위 바이트 값을 OR시켜 하나의 DATA형태로 만듭니다.(int 형은 2 byte 라는 것을 잊으면 안됩니다.)

DA_C와 같이 계산을 하면 1.5V의 값이 들어오면 DA_C에 들어간 값은 약 1500이 될 겁니다. 이 값을 1000으로 나누면 원래의 DATA를 얻을 수 있겠죠.

 

이로서 ADC 부분을 마쳤습니다. 이중 DMA부분은 빠졌는데 필요한 분은 매뉴얼을 참고하여 프로그램 하시면 될 겁니다.

 

'공부 > 8051' 카테고리의 다른 글

[ADUC812] ADUC812 설명 6  (0) 2012.11.10
[ADUC812] ADUC812 설명 5  (0) 2012.11.10
[ADUC812] ADUC812 설명 4  (0) 2012.11.10
[ADUC812] ADUC812 설명 2  (0) 2012.11.10
[ADUC812] ADUC812 설명 1  (0) 2012.11.10

+ Recent posts