BH2227FV는 Rohm사의 DAC 칩으로 MCU의 DAC 채널이 모자른 경우 사용할 수 있다.
- 8bit 해상도를 가지고 R-2R-type D/A Convert를 4채널 가진다. R-2R-type DAC에 대해선 밑에서 설명하겠다.
- 2개의 독립적인 파워소스를 사용할 수 있으며 최적화된 파워소스는 3V/5V인데 2.7V에서 5.5V까지는 허용된다.
- built-in 리셋 기능이 있어서 power up 동안 모든 채널이 LOW 출력하는게 보장된다.
- 3선식 serial interface를 사용한다.
R-2R-type D/A Convert란?
Binary Weighted DAC라고도 하는데 모든 디지털 비트에 대해 R과 그 2배인 2R 이렇게 두 개의 저항으로 구성되며, 비트 입력이 많을 수록 즉, 분해능이 높을수록 이 R-2R조합을 사다리 모양으로 나열해 구성한다. 비트 입력 지점에는 스위치가 있어서 디지털 입력이 1인 경우 Vref에 연결되고 0인 경우 GND에 연결되어 Binary 입력 가중치에 따라 출력이 조절되는 식이다.
핀 구성과 블락 다이어그램은 다음과 같다. AO1-AO4 총 4개의 아날로그 출력 터미널이 있고 AO1, AO2는 VFS 파워소스를 사용하고 AO3, AO4는 VDD 파워소스를 사용한다.
시리얼 인터페이스에는 CSB, CLK, DI 핀이 사용된다. 일반적인 SPI Interface에서 MISO만 연결 안하는 구조이다.
다음 전기적 특성을 살펴보자.
VDD, VFS 공급 범위는 위에서 언급한 것처럼 2.7~5.5V이고 (Note 2)에 Vdd >= Vfs 이어야 한다고 나와있다. 즉, 둘을 동일한 Voltage로 공급해도 되긴하지만 만약 풀스케일 출력이 3V인거 두 채널, 5V인거 두 채널을 쓰고 싶으면 VFS를 3V, VDD를 5V 공급해야 된다는 의미이다.
Data Transfer Frequency는 최대 10MHz이다.
로직 인터페이스의 Vil, Vih는 0.6, 2.4로 3.3V MCU의 시리얼 라인으로 인터페이스가 가능하다.
타이밍 차트를 보자.
대부분 Min값이 50ns 내외로 SPI 모듈을 쓴다면 10MHz 이하로 설정해 쓰면 크게 신경쓸게 없을 것 같다.
특징적으로 볼만한 건 D/A Output Setting Time이 100us이다. 즉, 시리얼 인터페이스로 아날로그 출력값 설명 명령을 전송하고 CS핀이 HIGH로 올라간 순간부터 100us가 지나야 설정한 출력값이 실제로 나간다는 것이다.
또 눈여겨 볼 것은 클럭의 라이징 엣지에 데이터를 가져가고 있다.
다음 실제로 작동 방식을 살펴보자.
시리얼 인터페이스에 CSB, CLK, DI 세 라인이 사용된다. 모든 커맨드는 DI라인을 통해 전송되는 12bit 데이터로 구성되는데 MSB first 방식으로 전송되며, CSB가 LOW동안 CLK의 rising edge에 DI 데이터가 읽히고 CSB가 다시 HIGH로 올라가는 순간 12bit 데이터가 래치된다.
근데 아래 그림을 보면 CSB가 LOW로 떨어진 후에 첫번째 CLK의 상승엣지는 무시되는 것 처럼 그려져있는데 이부분은 실제 확인해보니 그냥 그림 오류인 것같다. 또 다른 데이터시트를 보면 이렇게 안그려져 있다.
D8-D11은 출력채널 선택에 쓰이고 D0-D7의 8bit는 아날로그 출력값 설정에 쓰인다. D11을 먼저 전송하고 D0까지 순차 전송하는 식이다.
D0-D7의 데이터는 8bit 해상도 DAC니까 0-255 사이에 값을 선택하면 된다. 표에도 나와있지만 세팅 값이 0이면 GND 출력, 255면 Full scale이 출력이고, 세팅값이 127인데 파워소스가 5V이면 (5-0)/256*127인 약 2.48V가 출력될 것다.
아무튼 한번에 한 채널의 출력만 세팅할 수 있기 때문에 만약에 AO1-AO4 총 4개의 채널을 한꺼번에 설정하고 싶으면 커맨드를 4번에 걸쳐 보내야된다.
그리고 여기서 약간 특이한 점이 있는데 D7-D0까지는 Least significant bit가 마지막으로 전송한다. 예를들어 세팅값을 1을 쓰려면 '0b00000001' 이 전송한다. 근데 D11-D8까지는 Least significant bit가 먼저 전송한다. 예를들어 AO1채널을 선택한다면 '0b1000'을 전송하는 것이다. 코드 짤 때 이점을 주의해야 한다.
초기화 코드 및 제어 코드
#define BH2227FV_DI_PIN (int)1
#define BH2227FV_CLK_PIN (int)2
#define BH2227FV_CS_PIN (int)3
#define BH2227FV_FULL_SCALE (float)5.0
// BH2227FV IC 초기화 함수
void InitBh2227fv(void) {
// 핀먹스 설정
GPIO_setPinConfig(GPIO_1_GPIO1);
GPIO_setPinConfig(GPIO_2_GPIO2);
GPIO_setPinConfig(GPIO_3_GPIO3);
// DI 핀 설정
GPIO_setDirectionMode(BH2227FV_DI_PIN, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(BH2227FV_DI_PIN, GPIO_PIN_TYPE_STD);
GPIO_setQualificationMode(BH2227FV_DI_PIN, GPIO_QUAL_ASYNC);
// CLK 핀 설정
GPIO_setDirectionMode(BH2227FV_CLK_PIN, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(BH2227FV_CLK_PIN, GPIO_PIN_TYPE_STD);
GPIO_setQualificationMode(BH2227FV_CLK_PIN, GPIO_QUAL_ASYNC);
// CS핀 GPIO 설정
GPIO_setDirectionMode(BH2227FV_CS_PIN, GPIO_DIR_MODE_OUT);
GPIO_setPadConfig(BH2227FV_CS_PIN, GPIO_PIN_TYPE_STD);
GPIO_setQualificationMode(BH2227FV_CS_PIN, GPIO_QUAL_ASYNC);
GPIO_writePin(BH2227FV_CS_PIN, 1);
ControlBh2227fv(1, 0);
ControlBh2227fv(2, 0);
}
// BH2227FV IC 클럭 펄스 발생 함수
void Bh2227fvClkPulse(void) {
GPIO_writePin(BH2227FV_CLK_PIN, 0);
DEVICE_DELAY_US(1);
GPIO_writePin(BH2227FV_CLK_PIN, 1);
DEVICE_DELAY_US(1);
}
// BH2227FV IC 제어 명령 함수
void ControlBh2227fv(uint16_t ch, uint16_t data) {
// ch : 1-2 범위의 설정할 채널 값
// val : 0-255 사이의 설정할 데이터 값
int16_t i;
GPIO_writePin(BH2227FV_CS_PIN, 0);
DEVICE_DELAY_US(1); // CS setup time
Bh2227fvClkPulse();
for(i = 0; i < 4; i++) {
if((ch & (0x1U << i))) GPIO_writePin(BH2227FV_DI_PIN, 1);
else GPIO_writePin(BH2227FV_DI_PIN, 0);
Bh2227fvClkPulse();
}
for(i = 0; i < 8; i++) {
if((0x80U >> i) & data) GPIO_writePin(BH2227FV_DI_PIN, 1);
else GPIO_writePin(BH2227FV_DI_PIN, 0);
Bh2227fvClkPulse();
}
GPIO_writePin(BH2227FV_CLK_PIN, 0);
GPIO_writePin(BH2227FV_CS_PIN, 1);
}
GPIO를 직접 제어해서 시리얼 통신을 구현해 봤다.
데이터 세팅값과 voltage 간의 변환은 다음과 같이 할 수 있다.
data = (uint16_t)(voltage * 256 / BH2227FV_FULL_SCALE);
voltage = data * BH2227FV_FULL_SCALE / 256;
'임베디드 개발 > 펌웨어' 카테고리의 다른 글
오실로스코프 1M Ohm, 50 Ohm 설정에 관해 (0) | 2024.05.09 |
---|---|
AD5292BRUZ-100, Digital Potentiometer 데이터시트 분석 (0) | 2024.05.07 |
ADG201A, Analog Switch IC 데이터시트 분석 (0) | 2024.05.03 |
인텔 hex 포맷 이해하기 (+ Intel hex to Bin 변환) (0) | 2024.04.23 |
2의 거듭제곱에 대한 나머지 연산 최적화 및 bit mask 생성 (0) | 2024.04.08 |