Не получается правильно передать данные
- Войдите на сайт для отправки комментариев
Ср, 14/05/2014 - 09:40
Проблема в том, что пытаюсь выполнить задачу не по силам :)
Задача: данные с BMP085 отправить через CDC на компьютер
Код на данный момент такой:
/* Name: main.c * Project: AVR USB driver for CDC interface on Low-Speed USB * - Simple peripheral controller * Author: Osamu Tamura * Creation Date: 2007-05-12 * Tabsize: 4 * Copyright: (c) 2007 by Recursion Co., Ltd. * License: Proprietary, free under certain conditions. See Documentation. * */ #include <string.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <avr/wdt.h> #include <util/delay.h> #include "usbdrv.h" #include "oddebug.h" //BMP #include <stdlib.h> #include <stdio.h> #include "types.h" #include "defs.h" #include "i2c.h" #define BMP085_R 0xEF #define BMP085_W 0xEE #define OSS 0 // Oversampling Setting (note: code is not set up to use other OSS values) #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask)) #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask)) ///============Function Prototypes=========///////////////// void BMP085_Calibration(void); ///============I2C Prototypes=============////////////////// short bmp085ReadShort(unsigned char address); long bmp085ReadTemp(void); long bmp085ReadPressure(void); void bmp085Convert(long * temperature, long * pressure); ///============Initialize Prototypes=====////////////////// void ioinit(void); void delay_ms(uint16_t x); /////=========Global Variables======//////////////////// short ac1; short ac2; short ac3; unsigned short ac4; unsigned short ac5; unsigned short ac6; short b1; short b2; short mb; short mc; short md; //BMP #define INTERRUPT_REPORT 1 #define CMD_WHO "cdc-io" enum { SEND_ENCAPSULATED_COMMAND = 0, GET_ENCAPSULATED_RESPONSE, SET_COMM_FEATURE, GET_COMM_FEATURE, CLEAR_COMM_FEATURE, SET_LINE_CODING = 0x20, GET_LINE_CODING, SET_CONTROL_LINE_STATE, SEND_BREAK }; static PROGMEM char configDescrCDC[] = { /* USB configuration descriptor */ 9, /* sizeof(usbDescrConfig): length of descriptor in bytes */ USBDESCR_CONFIG, /* descriptor type */ 67, 0, /* total length of data returned (including inlined descriptors) */ 2, /* number of interfaces in this configuration */ 1, /* index of this configuration */ 0, /* configuration name string index */ #if USB_CFG_IS_SELF_POWERED USBATTR_SELFPOWER, /* attributes */ #else USBATTR_BUSPOWER, /* attributes */ #endif USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */ /* interface descriptor follows inline: */ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ USBDESCR_INTERFACE, /* descriptor type */ 0, /* index of this interface */ 0, /* alternate setting for this interface */ USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */ USB_CFG_INTERFACE_CLASS, USB_CFG_INTERFACE_SUBCLASS, USB_CFG_INTERFACE_PROTOCOL, 0, /* string index for interface */ /* CDC Class-Specific descriptor */ 5, /* sizeof(usbDescrCDC_HeaderFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 0, /* header functional descriptor */ 0x10, 0x01, 4, /* sizeof(usbDescrCDC_AcmFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 2, /* abstract control management functional descriptor */ 0x02, /* SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE */ 5, /* sizeof(usbDescrCDC_UnionFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 6, /* union functional descriptor */ 0, /* CDC_COMM_INTF_ID */ 1, /* CDC_DATA_INTF_ID */ 5, /* sizeof(usbDescrCDC_CallMgtFn): length of descriptor in bytes */ 0x24, /* descriptor type */ 1, /* call management functional descriptor */ 3, /* allow management on data interface, handles call management by itself */ 1, /* CDC_DATA_INTF_ID */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x80|USB_CFG_EP3_NUMBER, /* IN endpoint number */ 0x03, /* attrib: Interrupt endpoint */ 8, 0, /* maximum packet size */ USB_CFG_INTR_POLL_INTERVAL, /* in ms */ /* Interface Descriptor */ 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ USBDESCR_INTERFACE, /* descriptor type */ 1, /* index of this interface */ 0, /* alternate setting for this interface */ 2, /* endpoints excl 0: number of endpoint descriptors to follow */ 0x0A, /* Data Interface Class Codes */ 0, 0, /* Data Interface Class Protocol Codes */ 0, /* string index for interface */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x01, /* OUT endpoint number 1 */ 0x02, /* attrib: Bulk endpoint */ 8, 0, /* maximum packet size */ 0, /* in ms */ /* Endpoint Descriptor */ 7, /* sizeof(usbDescrEndpoint) */ USBDESCR_ENDPOINT, /* descriptor type = endpoint */ 0x81, /* IN endpoint number 1 */ 0x02, /* attrib: Bulk endpoint */ 8, 0, /* maximum packet size */ 0, /* in ms */ }; uchar usbFunctionDescriptor(usbRequest_t *rq) { if(rq->wValue.bytes[1] == USBDESCR_DEVICE){ usbMsgPtr = (uchar *)usbDescriptorDevice; return usbDescriptorDevice[0]; }else{ /* must be config descriptor */ usbMsgPtr = (uchar *)configDescrCDC; return sizeof(configDescrCDC); } } static uchar modeBuffer[7]; static uchar sendEmptyFrame; static uchar intr3Status; /* used to control interrupt endpoint transmissions */ /* ------------------------------------------------------------------------- */ /* ----------------------------- USB interface ----------------------------- */ /* ------------------------------------------------------------------------- */ uchar usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ if( rq->bRequest==GET_LINE_CODING || rq->bRequest==SET_LINE_CODING ){ return 0xff; /* GET_LINE_CODING -> usbFunctionRead() */ /* SET_LINE_CODING -> usbFunctionWrite() */ } #if USB_CFG_HAVE_INTRIN_ENDPOINT3 if(rq->bRequest == SET_CONTROL_LINE_STATE){ /* Report serial state (carrier detect). On several Unix platforms, * tty devices can only be opened when carrier detect is set. */ if( intr3Status==0 ) intr3Status = 2; } #endif #if 1 /* Prepare bulk-in endpoint to respond to early termination */ if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_HOST_TO_DEVICE) sendEmptyFrame = 1; #endif } return 0; } /*---------------------------------------------------------------------------*/ /* usbFunctionRead */ /*---------------------------------------------------------------------------*/ uchar usbFunctionRead( uchar *data, uchar len ) { memcpy( data, modeBuffer, 7 ); return 7; } /*---------------------------------------------------------------------------*/ /* usbFunctionWrite */ /*---------------------------------------------------------------------------*/ uchar usbFunctionWrite( uchar *data, uchar len ) { memcpy( modeBuffer, data, 7 ); return 1; } #define TBUF_SZ 256 #define TBUF_MSK (TBUF_SZ-1) //static uchar tos, val, val2; static uchar rcnt, twcnt, trcnt; static char tbuf[TBUF_SZ]; //static char rbuf[8], tbuf[TBUF_SZ]; static uchar u2h( uchar u ) { if( u>9 ) u += 7; return u+'0'; } /*static uchar h2u( uchar h ) { h -= '0'; if( h>9 ) h -= 7; return h; }*/ static void out_char( uchar c ) { tbuf[twcnt++] = c; #if TBUF_SZ<256 twcnt &= TBUF_MSK; #endif } //////////-----------------/////////////// #if INTERRUPT_REPORT static uchar intr_flag[4]; #define INTR_REG(x) { intr_flag[x>>3] |= 1<<(x&7); } #if _AVR_IOM8_H_ || _AVR_IOM16_H_ #define INTR_MIN 4 ISR( TIMER2_COMP_vect ) INTR_REG(4) ISR( TIMER2_OVF_vect ) INTR_REG(5) ISR( TIMER1_CAPT_vect ) INTR_REG(6) ISR( TIMER1_COMPA_vect ) INTR_REG(7) ISR( TIMER1_COMPB_vect ) INTR_REG(8) ISR( TIMER1_OVF_vect ) INTR_REG(9) ISR( TIMER0_OVF_vect ) INTR_REG(10) ISR( SPI_STC_vect ) INTR_REG(11) ISR( USART_RXC_vect ) INTR_REG(12) ISR( USART_UDRE_vect ) INTR_REG(13) ISR( USART_TXC_vect ) INTR_REG(14) ISR( ADC_vect ) INTR_REG(15) ISR( EE_RDY_vect ) INTR_REG(16) ISR( ANA_COMP_vect ) INTR_REG(17) ISR( TWI_vect ) INTR_REG(18) #if _AVR_IOM8_H_ #define INTR_MAX 19 ISR( SPM_RDY_vect ) INTR_REG(19) #else #define INTR_MAX 21 ISR( INT2_vect ) INTR_REG(19) ISR( TIMER0_COMP_vect ) INTR_REG(20) ISR( SPM_RDY_vect ) INTR_REG(21) #endif #endif #if _AVR_IOMX8_H_ || _AVR_IOM328P_H_ #define INTR_MIN 4 #define INTR_MAX 26 ISR( PCINT0_vect ) INTR_REG(4) ISR( PCINT1_vect ) INTR_REG(5) ISR( PCINT2_vect ) INTR_REG(6) ISR( WDT_vect ) INTR_REG(7) ISR( TIMER2_COMPA_vect ) INTR_REG(8) ISR( TIMER2_COMPB_vect ) INTR_REG(9) ISR( TIMER2_OVF_vect ) INTR_REG(10) ISR( TIMER1_CAPT_vect ) INTR_REG(11) ISR( TIMER1_COMPA_vect ) INTR_REG(12) ISR( TIMER1_COMPB_vect ) INTR_REG(13) ISR( TIMER1_OVF_vect ) INTR_REG(14) ISR( TIMER0_COMPA_vect ) INTR_REG(15) ISR( TIMER0_COMPB_vect ) INTR_REG(16) ISR( TIMER0_OVF_vect ) INTR_REG(17) ISR( SPI_STC_vect ) INTR_REG(18) ISR( USART_RX_vect ) INTR_REG(19) ISR( USART_UDRE_vect ) INTR_REG(20) ISR( USART_TX_vect ) INTR_REG(21) ISR( ADC_vect ) INTR_REG(22) ISR( EE_READY_vect ) INTR_REG(23) ISR( ANALOG_COMP_vect ) INTR_REG(24) ISR( TWI_vect ) INTR_REG(25) ISR( SPM_READY_vect ) INTR_REG(26) #endif static void report_interrupt(void) { uchar i, j; for( i=INTR_MIN; i<=INTR_MAX; i++ ) { j = i >> 3; if( intr_flag[j]==0 ) { i = ( ++j << 3 ) - 1; continue; } if( intr_flag[j] & 1<<(i&7) ) { intr_flag[j] &= ~(1<<(i&7)); out_char( '\\' ); out_char( u2h(i>>4) ); out_char( u2h(i&0x0f) ); out_char( '\r' ); out_char( '\n' ); break; } } } #endif static void hardwareInit(void) { uchar i; /* activate pull-ups except on USB lines */ USB_CFG_IOPORT = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT)); /* all pins input except USB (-> USB reset) */ #ifdef USB_CFG_PULLUP_IOPORT /* use usbDeviceConnect()/usbDeviceDisconnect() if available */ USBDDR = 0; /* we do RESET by deactivating pullup */ usbDeviceDisconnect(); #else USBDDR = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT); #endif for(i=0;i<20;i++){ /* 300 ms disconnect */ wdt_reset(); _delay_ms(15); } #ifdef USB_CFG_PULLUP_IOPORT usbDeviceConnect(); #else USBDDR = 0; /* remove USB reset condition */ #endif } char buffer[33]; char buffer2[33]; int main(void) { // BMP long temperature = 0; long pressure = 0; ioinit(); i2cInit(); delay_ms(100); BMP085_Calibration(); // BMP wdt_enable(WDTO_1S); odDebugInit(); hardwareInit(); usbInit(); intr3Status = 0; sendEmptyFrame = 0; rcnt = 0; twcnt = 0; trcnt = 0; sei(); for(;;){ /* main event loop */ wdt_reset(); usbPoll(); /* device -> host */ if( usbInterruptIsReady() ) { if( twcnt!=trcnt || sendEmptyFrame ) { ////////////////////////////////////////////////////////////////////// bmp085Convert(&temperature, &pressure); out_char( temperature ); out_char( '|' ); out_char( pressure ); out_char( '|' ); itoa (temperature,buffer,33); out_char( *buffer ); out_char( '|' ); itoa (pressure,buffer2,33); out_char( *buffer2 ); out_char( '\n' ); ////////////////////////////////////////////////////////////////////// uchar tlen; tlen = twcnt>=trcnt? (twcnt-trcnt):(TBUF_SZ-trcnt); if( tlen>8 ) tlen = 8; usbSetInterrupt((uchar *)tbuf+trcnt, tlen); trcnt += tlen; trcnt &= TBUF_MSK; /* send an empty block after last data block to indicate transfer end */ sendEmptyFrame = (tlen==8 && twcnt==trcnt)? 1:0; } } #if INTERRUPT_REPORT report_interrupt(); #endif #if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* We need to report rx and tx carrier after open attempt */ if(intr3Status != 0 && usbInterruptIsReady3()){ static uchar serialStateNotification[10] = {0xa1, 0x20, 0, 0, 0, 0, 2, 0, 3, 0}; if(intr3Status == 2){ usbSetInterrupt3(serialStateNotification, 8); }else{ usbSetInterrupt3(serialStateNotification+8, 2); } intr3Status--; } #endif } return 0; } // BMP void BMP085_Calibration(void) { ac1 = bmp085ReadShort(0xAA); ac2 = bmp085ReadShort(0xAC); ac3 = bmp085ReadShort(0xAE); ac4 = bmp085ReadShort(0xB0); ac5 = bmp085ReadShort(0xB2); ac6 = bmp085ReadShort(0xB4); b1 = bmp085ReadShort(0xB6); b2 = bmp085ReadShort(0xB8); mb = bmp085ReadShort(0xBA); mc = bmp085ReadShort(0xBC); md = bmp085ReadShort(0xBE); } short bmp085ReadShort(unsigned char address) { char msb, lsb; short data; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(BMP085_W); // write 0xEE i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(BMP085_R); // write 0xEF i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); msb = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); lsb = i2cGetReceivedByte(); // Get LSB result i2cWaitForComplete(); i2cSendStop(); data = msb << 8; data |= lsb; return data; } long bmp085ReadTemp(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(BMP085_W); // write 0xEE i2cWaitForComplete(); i2cSendByte(0xF4); // write register address i2cWaitForComplete(); i2cSendByte(0x2E); // write register data for temp i2cWaitForComplete(); i2cSendStop(); delay_ms(1000); // max time is 4.5ms return (long) bmp085ReadShort(0xF6); } long bmp085ReadPressure(void) { long pressure = 0; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(BMP085_W); // write 0xEE i2cWaitForComplete(); i2cSendByte(0xF4); // write register address i2cWaitForComplete(); i2cSendByte(0x34); // write register data for temp i2cWaitForComplete(); i2cSendStop(); delay_ms(1000); // max time is 4.5ms pressure = bmp085ReadShort(0xF6); pressure &= 0x0000FFFF; return pressure; //return (long) bmp085ReadShort(0xF6); } void bmp085Convert(long* temperature, long* pressure) { long ut; long up; long x1, x2, b5, b6, x3, b3, p; unsigned long b4, b7; ut = bmp085ReadTemp(); ut = bmp085ReadTemp(); // some bug here, have to read twice to get good data up = bmp085ReadPressure(); up = bmp085ReadPressure(); x1 = ((long)ut - ac6) * ac5 >> 15; x2 = ((long) mc << 11) / (x1 + md); b5 = x1 + x2; *temperature = ((b5 + 8) >> 4)/10.0; b6 = b5 - 4000; x1 = (b2 * (b6 * b6 >> 12)) >> 11; x2 = ac2 * b6 >> 11; x3 = x1 + x2; b3 = (((int32_t) ac1 * 4 + x3) + 2)/4; x1 = ac3 * b6 >> 13; x2 = (b1 * (b6 * b6 >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (ac4 * (unsigned long) (x3 + 32768)) >> 15; b7 = ((unsigned long) up - b3) * (50000 >> OSS); p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2; x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; *pressure = (p + ((x1 + x2 + 3791) >> 4))/133.32; } void ioinit (void) { //1 = output, 0 = input DDRC = 0b00010000; //PORTC4 (SDA), PORTC5 (SCL), PORTC all others are inputs PORTC = 0b00110000; //pullups on the I2C bus } // BMP void usbFunctionWriteOut( uchar *data, uchar len ) { // postpone receiving next data usbDisableAllRequests(); // host -> device: request char c; // delimiter? c = *data++; if( rcnt>=1 || rcnt == 0 ) { const char *ptr; ptr = PSTR( CMD_WHO ); //ptr = (PSTR("%d"), temperature); while( (c=pgm_read_byte(ptr++))!=0 ) { out_char(c); } out_char( '\n' ); } usbEnableAllRequests(); }
В строках с 413 по 430 собственно пытаюсь отправить данные. temperature и pressure содержат данные типа long. На компьютере принимаю нечитаемые символы, которые, тем не менее, изменяются при нагреве\охлаждении датчика.
Подскажите, пожалуйста, в чем теперь проблема.