2014/11/21 17:41

12F675를 이용한 ADC를 가져오기.

 ATTiny2313이나 ATTiny4313은 ADC가 없다. 그래서 다른 방법으로 ADC를 읽어오는 방법을 고안했는데, 약간의 딜레이를 무시하고 사용할 수 있도록 고려했다.



 이러한 핀 중에서 7,6,5를 아날로그 입력으로 이용하고, 4번을 읽을 때 1번으로 하면 활성화되도록 했으며, 읽을 수 있는 상태가 되면 2번이 1이 된다. 3번으로 클럭을 입력하면 높은 비트에서 낮은 비트 순으로 10비트의 데이터를 전달한다.


1. GP3에 1을 할당.

2. GP5가 1이 될 때까지 대기.

3. GP4에 클럭을 입력. 0에서 1이 되면 비트가 GP5에 설정된다. 10번을 반복해서 ADC0, 10번을 반복해서 ADC1, 10번을 반복해서 ADC2를 얻는다. 높은 비트에서 낮은 비트 순으로로 출력된다.

4. 만약 GP3가 0이 되면 도중에 중단된다.


 대충 이러한 방법론으로 동작한다. 남는 핀이 없어서 4번째 채널까지는 불가능하다. 일단 프로토타입으로 구성한 것 뿐이고 실험이 필요할 것 같다.


더보기


저작자 표시 비영리 변경 금지

'하드웨어' 카테고리의 다른 글

12F675를 이용한 ADC를 가져오기.  (0) 2014/11/21
간단한 승압 회로.  (0) 2014/10/29
AVR Serial/HID의 간단한 설명.  (0) 2014/10/22
AVR Serial HID 구현.  (0) 2014/10/21
USB CDC는 막힌 듯?  (0) 2014/10/20
USBTiny 실험.  (0) 2014/10/17
Trackback 0 Comment 0
2014/10/29 14:41

간단한 승압 회로.

 직류-직류로 변환하는 간단한 회로로 문제는 전류량이 많이 줄어든다. 클럭을 발생시켜서 인턱터(코일)로 고전압을 발생시키는 방법으로 방법론은 비슷하다.




 다른 점은 약간의 부품의 변형. 인턱터는 100uH이고, 트랜지스터와 R2저항의 값도 다르다. R2는 출력의 전류량을 조절하는데 낮을수록 더 많은 전류량을 보장한다. 브레드보드에서는 무부하시 21V가 나왔는데, 실제로 기판에 옮기니 30V가량이 나왔다. 제너 다이오드를 없애면 부품을 태워버리기에 좋은 전압이다. =_=;


 다이오드 앞단에서는 입력한 전압 그래도가 나오고 다이오드를 거쳐야 비로소 제대로된 전압을 측정할 수 있다. 오실로스코프가 아니면 다이오드 앞단의 전압을 체크하기가 힘들거라본다.


 낮은 전류이기에 부하가 많이 걸리는 장치를 운용할 수는 없다. HV 프로그래밍 등에 응용될 수 있으리라 본다. 비슷한 패턴으로 스위칭 소자와 전원부를 따로 만들어서 400V이상의 고전압을 운용하는 사례도 많다.



저작자 표시 비영리 변경 금지

'하드웨어' 카테고리의 다른 글

12F675를 이용한 ADC를 가져오기.  (0) 2014/11/21
간단한 승압 회로.  (0) 2014/10/29
AVR Serial/HID의 간단한 설명.  (0) 2014/10/22
AVR Serial HID 구현.  (0) 2014/10/21
USB CDC는 막힌 듯?  (0) 2014/10/20
USBTiny 실험.  (0) 2014/10/17
Trackback 0 Comment 0
2014/10/22 11:31

AVR Serial/HID의 간단한 설명.

 HID장치를 간단하게 시리얼 통신처럼 이용할 수 있는 방법은 CDC ACM 방법이 운영체제가 막아서 생기는 문제는 해결할 수 있다. 이 방법이 꼭 장점이 강한 것은 아니지만, 간단한 테스트를 위한 하드웨어에서의 응용은 나쁘지 않을거라고 생각된다.


 기본적으로 HID의 사용되는 프로그래밍 방법은 같고 단지 주의할 점만 존재한다. 호스트 컴퓨터에서 장치로 USB통해 정보는 받는 부분에 control전송과 인터럽트 전송을 모두 거치는 usbFunctionWriteOut을 쓰는데, 이것은 별로 문제가 되지 않는다. 단지 가끔 NULL데이터를 보내므로 펌웨어에서 체크를 하면 된다. 그리고 데이터의 길이가 버퍼의 길이와 맞추는 작업도 필요하다. 이것은 각각의 구현에 따른 변경이 다르므로 다른 게시물에 업로드한 소스를 확인하면 대충 이해하기 쉽다.


 가장 크게 주의할 점은 바로 HID 레포트 정보의 선언으로 장치에서 호스트 컴퓨터로 보내는 크기는 8바이트가 되어야 한다. 그렇지 않으면 데이터가 전혀 전송이 되지 않는다. 호스트 컴퓨터에서 장치로 전송되는 크기는 크게 문제가 없지만 64이하로 만들어주는 것이 좋다.


PROGMEM const char usbHidReportDescriptor[] = {
  0x06, 0xa0, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
  0x09, 0x01,       // USAGE (Vendor Usage 1)
  0xa1, 0x01,       // COLLECTION (Application)

  // Input Report
  0x09, 0x02,       // Usage ID - vendor defined
  0x15, 0x00,       // Logical Minimum (0)
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bits)
  0x95, 0x08,       // Report Count (8 fields), must be 8
  0x81, 0x02,       // Input (Data, Variable, Absolute)

  // Output report
  0x09, 0x03,       // Usage ID - vendor defined
  0x15, 0x00,       // Logical Minimum (0)
  0x26, 0xFF, 0x00, // Logical Maximum (255)
  0x75, 0x08,       // Report Size (8 bits)
  0x95, 0x16,       // Report Count (16 fields)
  0x91, 0x02,       // Output (Data, Variable, Absolute)

  0xc0              // END_COLLECTION
};


 기본적인 레포트의 선언은 위와 같은데, 항상 명칭은 호스트 컴퓨터를 중심으로 표현된다. Input는 장치에서 컴퓨터로 보내는 것으로 Report Size와 Report Count는 반드시 8바이트가 되어야 한다. 하드웨어 지원이 된다면 이런 제한이 없다고 하는데 하드웨어 USB 지원이 안되는 AVR은 저속 장치로 인식되는 탓에 어쩔 수 없다.


 Output 레포트의 크기는 변화를 줘도 아무런 문제가 없다.


 레포트 선언은 이렇게 간단하고, v-usb의 선언에서 데이터 전송을 위한 부분을 처리하도록 작성하는데 몇개의 함수만 만들어주면 간단히 끝난다.


usbMsgLen_t usbFunctionSetup(uchar data[8])
{
    return 0;
}

uchar usbFunctionRead(uchar *data, uchar len)
{
    return 0;
}

void usbFunctionWriteOut(uchar *data, uchar len)
{
uchar i,c;
    if(len>0) {
        if( (*data==0x0d) || (*data==0x0a) )
            return;
        if(len>HIDSERIAL_INBUFFER_SIZE) len=HIDSERIAL_INBUFFER_SIZE;
        i=0;
        while(i<len) {
            c=data[i];
            inBuffer[i]=c;
            i++;
            if(c==0) break;
        }
        received=1;
        recv_len=i;
    }
}


 usbFunctionSetup은 컴퓨터에 장치의 정보들을 설정하고 주고 받거나 컨트롤 전송을 위해 쓰이는데, 이 구현에서는 따로 크게 코딩할 부분이 없다.


 usbFunctionRead는 장치로 데이터를 보내는 방법을 위한 것으로 마찬가지로 컨트롤 전송을 위한 것으로 인터럽트 전송을 하는 이 방법에서는 쓸모가 없다.


 usbFunctionWriteOut은 호스트 컴퓨터에서 장치로 보내는 데이터를 처리할 때 쓰이는데, 이곳에서 장치의 버퍼에 데이터를 저장하면 된다. 설명에는 컨트롤 전송도 이 함수를 통해 데이터를 받을 수 있다고 되어 있다. 데이터가 다 전송되었다는 것을 확인할 방법을 구현하는게 좋다.


int main(void)
{
    odDebugInit();
    hardwareInit();
    usbInit();

    sei();
    for(;;){    /* main event loop */
        wdt_reset();
        usbPoll();

        if( usbInterruptIsReady() && (received != 0) )
          Translate_buffer(inBuffer);

...

    if(iwptr>0) {
        rx_buf[iwptr]=0;
        usbSetInterrupt(rx_buf,8);
        if(iwptr>8) {
            while(!usbInterruptIsReady()) {
                wdt_reset();
                usbPoll();
            }
            usbSetInterrupt(rx_buf+8,8);
        }
        iwptr=0;
    }

    }
...

    return 0;
}


 이렇게 간단히 선언하고 위와 같이 usbPoll()과 usbInterruptIsReady() 함수로 계속 상태를 확인하고 데이터의 전송에는 usbSetInterrupt(data, 8)과 같이 사용하면 된다. 8로 고정된 이유는 이미 설명했다. 만약 데이터가 길다면 usbPoll()과 usbInterruptIsReady()로 상태를 체크한 후에 usbSetInterrupt(...,8)로 다시 보내주면 된다. 8바이트씩 보내는 것이라 계속 보내준다면 크게 길이의 제한은 없다고 생각된다.


그리고 usbconfig.h의 내용들은 대충 이렇다.

...

#define USB_CFG_HAVE_INTRIN_ENDPOINT    1

#define USB_CFG_HAVE_INTROUT_ENDPOINT   1 

#define USB_CFG_IMPLEMENT_FN_WRITEOUT   1

...

#define USB_CFG_INTERFACE_CLASS     3       /* HID class */
#define USB_CFG_INTERFACE_SUBCLASS  0     
#define USB_CFG_INTERFACE_PROTOCOL  0    

...

#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    34

...



 특별한 것은 없는 방법론이기 때문에 그냥 따라하면 끝이다. 탐구를 하고 싶다면 삽질을 해봐도 좋을 일이다. =_=;



cdcio.2009-07-15-serhid-4313.zip


추가적인 비트 쓰기/읽기 기능의 추가.

portb.7 portb.1 [  읽기 msb, 첫번째는 데이터, 두번째는 클럭.

portb.0 portb.3 ]  읽기 lsb,

ff portb.1 portb.0 > 쓰기 lsb

ff portb.2. portb1 / 쓰기 msb ( 터미널 오류로 다른 문자를 사용 )



cdcio.2009-07-15-serhid-addfuncs1.zip


저작자 표시 비영리 변경 금지

'하드웨어' 카테고리의 다른 글

12F675를 이용한 ADC를 가져오기.  (0) 2014/11/21
간단한 승압 회로.  (0) 2014/10/29
AVR Serial/HID의 간단한 설명.  (0) 2014/10/22
AVR Serial HID 구현.  (0) 2014/10/21
USB CDC는 막힌 듯?  (0) 2014/10/20
USBTiny 실험.  (0) 2014/10/17
Trackback 0 Comment 0


티스토리 툴바