공부/8051 2012. 11. 12. 20:43

 

SPI의 사용

 

1    SPI의 기본사항

DATA를 시리얼 형태로 통신하는 방법은 많이 있다. 그 중 주변소자와 통신하는데 사용하는 대표적인 방식으로는 I2C,SPI 등을 말할 수 있으며 이번 장은 그 중 ADUC831에서 SPI MASTER 기능은 어떻게 사용하는지 설명 하려 한다.

 

2    SPI의 관련 레지스터

 

ADUC831 SPICON define

BIT7 

ISPI

1:SPI 인터럽트 동작조건 SPIDAT 전송이 완료되면 발생된다. 사용자의 프로그램에 의해 지워야 한다.

BIT6 

WCOL

1:SPI 전송을 위해 SPIDAT 잘못되면 발생된다.

사용자의 프로그램에 의해 지워야 한다.

BIT5 

SPE

1: SPI 사용 enable 설정

BIT4 

SPIM

SPI master/slave 모드 설정

1: master mode , 0:slave mode 

BIT3 

CPOL

Clock 이 발생하지 않을 때 핀의 상태를 나타낸다.

1: high 상태로 유지 , 0: low 상태로 유지

BIT2 

CPHA

DATA가 어떤 클럭에 동기 되는지 설정한다.

1: SCLOCK leading edge에 동기

2: SCLOCK trailing edge에 동기

BIT1 

SPR1

SPI bit 유지 시간을 설정 한다.(SPR1 SPR0 Selected Bit Rate)

00: fCORE/2,     01: fCORE/4,    10: fCORE/8,     11: fCORE/16

BIT0 

SPR0

 

 

3    SPI의 사용을 위한 CHIP 선정

 

SPI Master 활용예를 설명 들이겠습니다. 이를 위해 선정한 CHIP AD5232 2개의 저항을 가지고 있는 Digital Potentiometer 입니다. 내부에 EEPROM(EEMEM) 가지고 있으며 이와 연결된 가변저항 조정 레지스터(RDAC) 있으며 , 기타 콘트롤 부분이 있습니다. 자세한 사항은 관련 매뉴얼을 참고해주시면 감사하겠습니다.

 

EEMEM 비활성 메모리이기 때문에 이곳에 값을 저장해 두면 파워온 자동으로 RDAC 조정하여 저항을 조절하게 됩니다. 그러므로 초기값 설정을 원한다면 EEMEM 사용하면 됩니다. RDAC 값의 조정에 따라 아래의 그래프와 같이 저항성분이 변하게 되어 있습니다.

 

 

SPI 통신 파형은 가지 방식을 지원 합니다. 그러므로 좀더 사용이 편리합니다.

 

기본회로는 아래와 같습니다. 정확한 회로 해석은 ADUC831 AD5232 매뉴얼을 참고해 주시기 바랍니다.

 

회로는 A-GND , B-GND 가지 저항값을 조절하는 회로이다. P1.0 Chip select 용이며 SCLOCK MOSI ADUC831 원래 기능을 활용합니다.

 

4    AD5232 제어 명령

 

AD5232 COMMAND define

상위 8BIT

하위 8BIT

(DATA)

내용

상위 4BIT

(COMMAND) 

하위 4BIT

(ADDRESS) 

0000

xxxx

xxxxxxxx

NOP

0001

000'A0'

xxxxxxxx

EEMEM(A0)의값->RDAC(A0), 실행 후 nop 실행, power up후 실행     

0010

000'A0'

xxxxxxxx

RDAC(A0)의값->EEMEM(A0)

0011

<<ADDR>>

D7 - D0

DATA의값->EEMEM(ADDR)

0100

000'A0'

xxxxxxxx

RDAC(A0)의값을6db감소,ZERO에서 멈춤

0101

xxxx

xxxxxxxx

모든RDAC의값을6db감소,ZERO에서 멈춤

0110

000'A0'

xxxxxxxx

RDAC(A0)의값을'1'감소,ZERO에서 멈춤

1000

0000

xxxxxxxx

기존의 EEMEM값을 RDAC에 다시 넣기(RESET)

1001

<<ADDR>>

xxxxxxxx

EEMEM<<ADDR> 의 값을 0으로 설정

1010

000'A0'

xxxxxxxx

RDAC(A0)의값을0으로 설정

1011

000'A0'

D7 - D0

DATA의 값->RDAC(A0)

1100

000'A0'

xxxxxxxx

RDAC(A0)의 값을6db추가

1101

xxxx

xxxxxxxx

모든RDAC의 값을6db추가

1110

000'A0'

xxxxxxxx

RDAC(A0)의 값을'1'추가

1111

xxxx

xxxxxxxx

모든RDAC의 값을'1'추가

참고사항

<<ADDR>> 는 아래와 같다.

0000:RDAC1의EEMEM,0001:RDAC2의EEMEM,0010:USER1의EEMEM.....

1111:USER14의EEMEM

 

ZERO값은 50옴 저항 값을 가진다.

 

개인적으로 실험해본 결과 위의 명령 중 가장 적절하게 사용하는 방법은 DATA의 값->RDAC(A0) 을 하는 것이며, 만약 EEMEM에 저장하고자 한다면, DATA의 값->RDAC(A0) 을 한후에 RDAC(A0)의값->EEMEM(A0) 을 하는 것을 추천합니다.

다음 부분에서 실제로 사용한 예를 보여 드리겠습니다.

 

 

5    SPI를 사용한 AD5232 제어 SOURCE

 

Source SPI를 초기화 한다.

void openSPI()
{
    SPICON = 0x33;
}

 

Source AD5232의 RDAC조절하여 저항값을 조정한다.

void ad5232_ch_rdac_set(unsigned char sele, unsigned char ch, unsigned char dat)    
{                                            
    unsigned char ddllyy =0;
    unsigned char chip_sel =0;
    unsigned char chip_data =0;
    unsigned int sel =0;

    sel = ad5232_table[sele];
    chip_sel = HIGH_BYTE(sel);
    chip_data = LOW_BYTE(sel);

    ad5232_cs[chip_sel] = chip_data;

//ext_dvr_update1( (0xB0|ch) , dat );

    //txDat = (0xB0|ch);
    ISPI = 0;                     // Clear ISPI bit
    SPIDAT = (0xB0|ch);
    while(!ISPI);                 // Wait until tx complete

    //txDat = dat;
    ISPI = 0;                     // Clear ISPI bit
    SPIDAT = dat;
    while(!ISPI);                 // Wait until tx complete


    //ad5232_cs[chip_sel] = 0;
    //for(ddllyy =0; ddllyy <=1; ddllyy++);
    //ad5232_cs[chip_sel] = chip_data;
    //for(ddllyy =0; ddllyy <=1; ddllyy++);
    //ad5232_cs[chip_sel] = 0;

    ad5232_cs[chip_sel] = 0;
    //ad5232_cs[chip_sel] = chip_data;
    //ad5232_cs[chip_sel] = chip_data;
    ad5232_cs[chip_sel] = chip_data;
    ad5232_cs[chip_sel] = 0;

}

 

Source AD5232의 RDAC의 값을 EEMEM에 저장한다.

void ad5232_rdac_eemem_mov(unsigned char sele, unsigned char ch)    
{                                            
    unsigned char chip_sel =0;
    unsigned char chip_data =0;
    unsigned int sel =0;

    sel = ad5232_table[sele];
    chip_sel = HIGH_BYTE(sel);
    chip_data = LOW_BYTE(sel);

    ad5232_cs[chip_sel] = chip_data;

    ISPI = 0;                     // Clear ISPI bit
    SPIDAT = (0x20|ch);
    while(!ISPI);                 // Wait until tx complete

    ISPI = 0;                     // Clear ISPI bit
    //SPIDAT = dat;
    SPIDAT = 0;
    while(!ISPI);                 // Wait until tx complete


    ad5232_cs[chip_sel] = 0;
    ad5232_cs[chip_sel] = chip_data;
    ad5232_cs[chip_sel] = chip_data;
    ad5232_cs[chip_sel] = chip_data;
    ad5232_cs[chip_sel] = 0;

}

 

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

ABOV MC9x Code Generator  (0) 2014.06.19
8051 레지스터 자료  (0) 2012.11.15
[ADUC831] ADUC831 간단 매뉴얼 6  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 5  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 4  (0) 2012.11.12
[ADUC831] ADUC831 간단 매뉴얼 3  (0) 2012.11.12
posted by 큰파도

댓글을 달아 주세요