첫 Raspberry Pi Pico ㉜ Circuitpython에서 MCP3304

마이크로칩 MCP3304은 13비트 A-D 컨버터입니다. 최상위는 부호 비트이므로 -4096~+4095까지의 분해능이 있는 12비트 ADC입니다. 인터페이스는 SPI 버스이며 전송 속도는 최대 2.1MHz(5V)입니다. 동작 전압은 5V가 권장되지만 3.3V에서도 움직였다.

MCP3304의 주요 사양


  • 비트 수 13
  • 채널 수 8(싱글 엔드), 4(차동)
  • 기준 전압 내장 없음, 단자 있음
  • 변환 속도 100ksps(5V시)
  • 인터페이스 SPI(모드 0,0 및 1,1), 클럭 최대 2.1MHz(5V 시)
  • 동작 전압 4.5(2.7)~5.5V
  • 핀 수 16 핀 DIP

  • 연결




    MCP3304 단자
    Pico 터미널 (GPIO)
    이름


    1ch0
    -
    -

    2 ch1
    -
    -

    3 ch2
    -
    -

    4 ch3
    -
    -

    5 ch4
    -
    -

    6 ch5
    -
    -

    7 ch6
    -
    -

    8 ch7
    -
    -

    9 DGND
    GND
    GND

    10/CS
    GP8
    GP8

    11 Din
    GP3
    MOSI SPI0 TX

    12 도트
    GP4
    MISO SPI0 RX

    13 CLK
    GP2
    SPI0 SCK

    14 AGND
    GND
    GND

    15 Vref
    3V3
    3.3V

    16 Vdd
    3V3
    3.3V


     ch0-ch1 차동 입력에는, 전지 구동의 간이 전원 TL431의 출력을 연결하고 있습니다. 약 2.5V입니다.

    프로그램



    명령을 보내는 형식은 다음과 같습니다.
       Startbit チャネル指定4バイト예를 들면, 차동 ch0-ch1이면,
       0000입니다. 마지막 채널 지정 비트 D0가 MCP3304에 보내지는 타이밍에서, 약 1비트 놓고, NULL비트에 이어,
       Sign D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0A-D 변환 결과 데이터가 MCP3304에서 Pico로 전송됩니다.
    SPI는 기본 8비트 단위이므로 LSB의 D0부터 앞으로 거슬러 올라가 8비트 단위로 보낼 데이터를 정리합니다. 차동 ch0-ch1의 경우입니다.
     x x x x 1 0 0 0 0 x x x x x x x x x x x x x x xSPI는 클럭을 계속 보내지 않으면 데이터는 오지 않습니다. 위의 x는 더미이므로 0이든 1이든 상관 없습니다. 그러나 처음 4 비트 중 하나를 '1'로 설정하면 Startbit로 해석 될 수 있으므로 '0'으로 설정합니다. '0'에서도 클럭이 발생합니다. 따라서 여기서 ch0-ch1 차동 데이터는 다음과 같이 했다.
     0x08 0x00 0xff
    본 프로그램은 차동 입력만을 대상으로 하고 있습니다.


    채널 지정
    첫 번째 바이트
    두 번째 바이트
    세 번째 바이트


    ch0 = IN+ ch1 = IN-
    0b00001000
    0b00000000
    0xff

    ch2 = IN + ch3 = IN-
    0b00001001
    0b00000000
    0xff

    ch4 = IN+ ch5 = IN-
    0b00001010
    0b00000000
    0xff

    ch6 = IN + ch7 = IN-
    0b00001011
    0b00000000
    0xff


    3바이트 보냈으므로, 읽은 데이터는 3바이트입니다. 1바이트째는 쓰레기이므로 버립니다. 2바이트째는 상위 자리수Sign D11 D10 D9 D8가 오른쪽 채우기로 들어가 있습니다. 세 번째 바이트는 D7 D6 D5 D4 D3 D2 D1 D0입니다.
      Sign 비트를 보고 부호를 붙입니다.
    12비트의 데이터이므로 Vref의 3.3V를 곱하여 4096으로 나누어 전압을 구합니다. Vref는 가능한 한 정확하게 테스터로 측정한 값을 기입해 둡니다.
    from board import *
    import busio
    import time
    import digitalio
    
    print('\n  start\n')
    
    spi = busio.SPI(GP2, GP3, GP4)  # SPI0BUS clock MOSI MISO
    while not spi.try_lock():
        pass
    spi.configure(baudrate=1_000_000, phase=0, polarity=0)
    
    cs = digitalio.DigitalInOut(GP8)
    cs.direction = digitalio.Direction.OUTPUT
    cs.value = 1
    
    def readADC():
        result = bytearray(3)
        cs.value = 0
        spi.write_readinto(bytearray([0x08,0x00,0xff]), result)  # cho-ch1
        cs.value = 1
        temp = (result[1] & 0b00011111) << 8 | result[2]
        Volts = -(temp & 0b1000000000000) | (temp & 0b0111111111111)
        #print(result[0], result[1], result[2])
        #print(bin(Volts))
        return(Volts)
    
    while 1:
        print(str(readADC()*3.3/4096) + 'V')
        time.sleep(3.14)
    

     ch0-ch1을 읽고 있는 곳입니다.

    좋은 웹페이지 즐겨찾기