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;
}
|