реклама на сайте
подробности

 
 
> STM32 <-spi-> внешний ADC
undef1ned
сообщение May 27 2013, 15:51
Сообщение #1





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Господа, помогите разобраться.

У меня есть STM32F3-Discovery, я хочу подключить к нему через SPI ацп AD7738 (pdf). Решил использовать SPI2, в даташите STM32F3 прочитал, что в SPI2 задействованы ноги PB13, PB14, PB15. Настроил GPIO для этих пинов, настроил GPIO для RDY пина, на который пишется нолик, когда АЦП завершает преобразование (выбрал PD10), создал SPI2 с некими параметрами.

Для конфигурации я сделал ряд функций, которыми можно изменять параметры регистров, чтобы каждый раз не писать 0b00... (см. дефайны и ADC_ функции в коде)

Суть в том, что я использовал сначала пример с прерываниями и он работал, но через ж... не совсем как я хочу. Там я отправляю байтики функцией SPI_I2S_SendData16 и они приходят в функцию прерывания. Проблема в том, что я не могу понять, что я читаю, но по данным догадался, что приходит стандартное значение регистра данных (8000h), на датчик не реагирует АЦП.

Поэтому я погуглил еще и просто сделал функции для чтения-записи 8бит данных вместо прерываний.

Далее пишу 0x42 (перед mode-регистром, до начала преобразования), чтобы достать версию чипа, должно прийти "33" (dec), но приходит 0. С прерываниями работало и приходило 33 (и это подходило под описание регистра ревизии). Также не приходит стандартное значение регистра данных, вместо этого приходит тупо 0.

В чем ошибка моего варианта? Я подозреваю, что само соединение как-то не правильно настроено.
Код прилагаю

Код
#include "main.h"
#include <stdbool.h>
#include <math.h>
#include "usb_CDC.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_spi.h"

/*******************************************************************************/
__IO uint32_t TimingDelay = 0;
__IO uint32_t UserButtonPressed = 0;
__IO uint8_t DataReady = 0;
__IO uint8_t PrevXferComplete = 1;
__IO uint32_t USBConnectTimeOut = 100;
volatile int rx, rx_data;

union Pack16bitk{
    char b[sizeof(short)];
    short sval;
} Package16;

/*
* AIN0: 000
* AIN1: 001
* AIN2: 010
* AIN3: 011
* AIN4: 100
* AIN5: 101
* AIN6: 110
* AIN7: 111
*/

#define SELECH                    0b00000111

#define IOPR_P0_OUTPUT_0        0b00000000
#define IOPR_P0_OUTPUT_1        0b10000000
#define IOPR_P0_DIR_AIN            0b01000000
#define IOPR_P0_DIR_AOUT        0b00000000
#define IOPR_P1_DIR_DIN            0b00100000
#define IOPR_P1_DIR_DOUT        0b00000000
#define IOPR_RDYFN_ANY            0b00000000
#define IOPR_RDYFN_ALL            0b00001000
#define IOPR_SYNC_ON            0b00000001
#define IOPR_SYNC_OFF            0b00000000

#define CHSETR_BUF_ENABLE        0b00000000
#define CHSETR_BUF_DISABLE        0b10000000
#define CHSETR_AINCONF_0        0b00000000
#define CHSETR_AINCONF_1        0b01100000
#define CHSETR_STATOPT_P1        0b00010000
#define CHSETR_STATOPT_RDY        0b00000000
#define CHSETR_ENABLE_ENABLE    0b00001000
#define CHSETR_ENABLE_DISABLE    0b00000000
#define CHSETR_RANGE_0            0b00000100    // +-2.5V
#define CHSETR_RANGE_1            0b00000101    // 0V to +2.5V
#define CHSETR_RANGE_2            0b00000000    // +-1.25V
#define CHSETR_RANGE_3            0b00000001    // 0V to +1.25V
#define CHSETR_RANGE_4            0b00000010    // +-0.625V
#define CHSETR_RANGE_5            0b00000011    // 0V to +0.625V

#define CHCONVTIMER_CHOP_ON    0b10000000
#define CHCONVTIMER_CHOP_OFF    0b00000000
#define CHCONVTIMER_FILTER_0    0b01111111    //FW=127, Conv.Time = 2686 us, Out data rate = 372Hz [With chopping enabled]
#define CHCONVTIMER_FILTER_1    0b00101110    //FW=46, Conv.Time = 999 us, Out data rate = 1001 Hz
#define CHCONVTIMER_FILTER_2    0b00010001    //FW=17, Conv.Time = 395 us, Out data rate = 2534 Hz
#define CHCONVTIMER_FILTER_3    0b00001000    //FW=8, Conv.Time = 207 us, Out data rate = 4826 Hz
#define CHCONVTIMER_FILTER_4    0b00000100    //FW=4, Conv.Time = 124 us, Out data rate = 8074 Hz
#define CHCONVTIMER_FILTER_5    0b00000010    //FW=2, Conv.Time = 82 us, Out data rate = 12166 Hz

#define MODER_MODE_CONTINUOUS    0b00100000
#define MODER_MODE_SINGLE        0b01000000
#define MODER_CLKDIS_ON        0b00010000
#define MODER_CLKDIS_OFF        0b00000000
#define MODER_DUMP_ON            0b00001000
#define MODER_DUMP_OFF            0b00000000
#define MODER_CONTRD_ON        0b00000100
#define MODER_CONTRD_OFF        0b00000000
#define MODER_BITS_24            0b00000010
#define MODER_BITS_16            0b00000000
#define MODER_CLAMP_ON        0b00000001
#define MODER_CLAMP_OFF        0b00000000

/*******************************************************************************/
void USB_Config(void){
  Set_System();
  Set_USBClock();
  USB_Interrupts_Config();
  
  USB_Init();

  while ((bDeviceState != CONFIGURED)&&(USBConnectTimeOut != 0))
  {}
}

/*******************************************************************************/
void SPI_Config(void){
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5);

    GPIO_InitTypeDef port;

    port.GPIO_Mode = GPIO_Mode_AF;
    port.GPIO_OType = GPIO_OType_PP;
    port.GPIO_PuPd  = GPIO_PuPd_DOWN;
    port.GPIO_Speed = GPIO_Speed_50MHz;

    //SCK -> PB13 | MISO -> PB14 | MOSI -> PB15
    port.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_Init(GPIOB, &port);

    SPI_InitTypeDef  spi;
    spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi.SPI_Mode = SPI_Mode_Master;
    spi.SPI_DataSize = SPI_DataSize_8b;
    spi.SPI_CPOL = SPI_CPOL_High;
    spi.SPI_CPHA = SPI_CPHA_2Edge;
    spi.SPI_NSS = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
    spi.SPI_FirstBit = SPI_FirstBit_MSB;
    spi.SPI_CRCPolynomial = 7;

    SPI_Init(SPI2, &spi);
    SPI_Cmd(SPI2, ENABLE); //Включение SPI
}

uint8_t SPI_SendRead8(uint8_t ToSend8){
    while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
    SPI2->DR = ToSend8;
    while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
    return (SPI2->DR);
}

void SPI_Send8(uint8_t ToSend8){
    while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
    SPI2->DR = ToSend8;
    while ((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
    uint8_t dummy = (SPI2->DR);
}

void ADC_Reset(){
    SPI_Send8(0x00);
    SPI_Send8(0xff);
    SPI_Send8(0xff);
    SPI_Send8(0xff);
    SPI_Send8(0xff);
}

void ADC_IOpr(uint8_t P0, uint8_t P1, uint8_t P0_DIR, uint8_t P1_DIR, uint8_t RDYFN, uint8_t SYNC){
    SPI_Send8(0b00000001); //IO Port Register
    SPI_Send8(P0+P1+P0_DIR+P1_DIR+RDYFN+SYNC);
}

void ADC_ChSetr(uint8_t BUFOFF, uint8_t AINCONF, uint8_t STATOPT, uint8_t ENABLE, uint8_t RANGE){
    SPI_Send8(0b00101000+SELECH); //Channel setup register
    SPI_Send8(BUFOFF+AINCONF+STATOPT+ENABLE+RANGE);
}

void ADC_ChConvTimr(uint8_t CHOP, uint8_t FILTERWORD){
    SPI_Send8(0b00110000+SELECH); //Channel conversion time register
    SPI_Send8(CHOP+FILTERWORD);
}

void ADC_Moder(uint8_t MODER_MODE, uint8_t CLKDIS, uint8_t DUMP, uint8_t CONTRD, uint8_t MODER_BITS, uint8_t CLAMP){
    SPI_Send8(0b00111000+SELECH); //Mode register
    SPI_Send8(MODER_MODE+CLKDIS+DUMP+CONTRD+MODER_BITS+CLAMP);
}


/*******************************************************************************/
int main(void){
  SystemInit();
  RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
  GPIO_InitTypeDef portd;
  portd.GPIO_Mode = GPIO_Mode_IN;
  portd.GPIO_PuPd = GPIO_PuPd_DOWN;
  portd.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOD, &portd);

  USB_Config();
  SPI_Config();

  ADC_Reset();
  ADC_IOpr(IOPR_P0_OUTPUT_1,
          IOPR_P0_OUTPUT_1,
          IOPR_P0_DIR_AIN,
          IOPR_P1_DIR_DOUT,
          IOPR_RDYFN_ANY,
          IOPR_SYNC_OFF);
  ADC_ChSetr(CHSETR_BUF_ENABLE,
          CHSETR_AINCONF_1,
          CHSETR_STATOPT_P1,
          CHSETR_ENABLE_ENABLE,
          CHSETR_RANGE_1);
  ADC_ChConvTimr(CHCONVTIMER_CHOP_ON,
          CHCONVTIMER_FILTER_2);

  uint8_t ADC_Revision = SPI_SendRead8(0x42); //Должно быть 0x21

  ADC_Moder(MODER_MODE_CONTINUOUS,
          MODER_CLKDIS_ON,
          MODER_DUMP_OFF,
          MODER_CONTRD_OFF,
          MODER_BITS_16,
          MODER_CLAMP_OFF);

  while (1){
      if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_10) == 0){ //1=high 0=low
          SPI_Send8(0b1001000+SELECH);//1001000-1001111
          Package16.b[0] = SPI_SendRead8(0x00);
          Package16.b[1] = SPI_SendRead8(0x00);
          USB_Send_Short(Package16.sval);
      }
      Delay(50);
  }
}

/*******************************************************************************/
void Delay(__IO uint32_t nTime){
  TimingDelay = nTime;
  while(TimingDelay != 0);
}

/*******************************************************************************/
void TimingDelay_Decrement(void){
  if (TimingDelay != 0x00)  {
    TimingDelay--;
  }
}


Сообщение отредактировал undef1ned - May 27 2013, 15:53
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 17)
artkam
сообщение May 27 2013, 20:49
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 14-09-10
Из: Уфа
Пользователь №: 59 479



А где у Вас в коде управление ногой CHIP SELECT (CS) описано??? Что-то я найти не могу...
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 27 2013, 21:38
Сообщение #3





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Цитата(artkam @ May 28 2013, 00:49) *
А где у Вас в коде управление ногой CHIP SELECT (CS) описано??? Что-то я найти не могу...

Цитата
With this input hardwired low, the AD7738 can operate in its 3-wire interface mode using SCLK, DIN, and DOUT. CS can be used to select the device in systems with more than one device on the serial bus.

У меня как раз вот так сделано ну и только одно устройство на шине.

Сообщение отредактировал undef1ned - May 27 2013, 21:38
Go to the top of the page
 
+Quote Post
artkam
сообщение May 27 2013, 22:10
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 14-09-10
Из: Уфа
Пользователь №: 59 479



Поверьте, CS обязательно требуется притягивать к земле даже при наличии одного единственного устройства. Посмотрите внимательнее на приведенные диаграммы в даташите Figure 1 и Figure 2.
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 27 2013, 22:41
Сообщение #5





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Да, у меня CS (4 пин) подключен к GND на stm32f3-discovery, я проверил

Еще приведу свой код с прерываниями, где поочередно приходят значения 0x8000, 0x80, 0x00, а кстати если отключить питание датчиков то приходит 0xE080, 0xE0, 0x8000
Собственно, та же программа, но есть ф-я

Код
void SPI2_IRQHandler(){
    if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET){
        uint16_t spi_data16 = 0x00;
        spi_data16 = SPI_I2S_ReceiveData16(SPI2);
        USB_Send_Short(spi_data16);
    }
}

В ней я ставлю бряк на USB_Send_Short() и смотрю spi_data16.

Конф-я SPI, вроде такая же, ну помимо 16 бит размера, но с 8 бит то же самое:
Код
/*******************************************************************************/
void SPI_Config(void){
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5);

    port.GPIO_Mode = GPIO_Mode_AF;
    port.GPIO_OType = GPIO_OType_PP;
    port.GPIO_PuPd  = GPIO_PuPd_DOWN;
    port.GPIO_Speed = GPIO_Speed_50MHz;

    //SCK -> PB13, MOSI -> PB15
    port.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOB, &port);

    port.GPIO_Pin = GPIO_Pin_13;
    GPIO_Init(GPIOB, &port);

    //MISO -> PB14
    port.GPIO_Pin = GPIO_Pin_14;
    GPIO_Init(GPIOB, &port);

    //SPI_StructInit(&spi);
    spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi.SPI_Mode = SPI_Mode_Master;
    spi.SPI_DataSize = SPI_DataSize_16b;//16
    spi.SPI_CPOL = SPI_CPOL_High;
    spi.SPI_CPHA = SPI_CPHA_2Edge;
    spi.SPI_NSS = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    spi.SPI_FirstBit = SPI_FirstBit_MSB;
    spi.SPI_CRCPolynomial = 7;
    SPI_Init(SPI2, &spi);
}


Вместо ADC_ функций тупо шлю заранее записанные байты:
Код
void ADC_Config(void){
    //00h + FFh + FFh + FFh + FFh (RESET)
    SPI_SendData8(SPI2, 0x00);
    SPI_SendData8(SPI2, 0xff);
    SPI_SendData8(SPI2, 0xff);
    SPI_SendData8(SPI2, 0xff);
    SPI_SendData8(SPI2, 0xff);

    //Configure
    SPI_SendData8(SPI2, 0b00000001); //IO Port Registe
    SPI_SendData8(SPI2, 0b11110000); //

    SPI_SendData8(SPI2, 0b00101000+SELECH); //Channel setup register
    SPI_SendData8(SPI2, 0b00011100); //+-2.5V, Single-ended ENABLE

    SPI_SendData8(SPI2, 0b00110000+SELECH); //ch. conv. time, 110000-110111
    SPI_SendData8(SPI2, 0b10010001); //
}

void ADC_SetMODER(void){
    SPI_SendData8(SPI2, 0b00111000+SELECH); //Mode register, 00111111-00111000
    SPI_SendData8(SPI2, 0x00100000);
}


Ну и здесь вот с настрйокой прерываний:
Код
int main(void){
  __enable_irq();
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
  GPIO_InitTypeDef portd;
  portd.GPIO_Mode = GPIO_Mode_IN;
  portd.GPIO_PuPd = GPIO_PuPd_DOWN;
  portd.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOD, &portd);

  SystemInit();
  RCC_GetClocksFreq(&RCC_Clocks);
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
  USB_Config();

  SPI_Config();
  NVIC_EnableIRQ(SPI2_IRQn);
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
  SPI_Cmd(SPI2, ENABLE);
  SPI_NSSInternalSoftwareConfig(SPI2, SPI_NSSInternalSoft_Set);

  ADC_Config();
  ADC_SetMODER();

  while (1){
      //Poll RDY pin
      if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_10) == 0){ //1=high 0=low
          SPI_SendData8(SPI2, 0b1001000+SELECH);//0x4F
      }
      Delay(50);
  }
}


Такие дела. Конечно неправильно отправлять просто 0x4F, там в дш после него еще 2 раза по 0х00 идет. Если поставить SPI_SendData8(0x00) 2 раза, то в ответ на это просто приходят нули (по крайней мере в этом все отличие).

Сообщение отредактировал undef1ned - May 27 2013, 22:42
Go to the top of the page
 
+Quote Post
artkam
сообщение May 28 2013, 12:44
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 14-09-10
Из: Уфа
Пользователь №: 59 479



Приведите пожалуйста схему подключения АЦП к МК...
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 28 2013, 13:13
Сообщение #7





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Ну собственно, от AD7738 к мк идут только SCLK, RDY, DIN, DOUT, RESET (dvdd), CS (dgnd), вроде ничего не забыл
MUXOUT и ADCIN соединены (пины 13 и 16, 14 и 15)
SCLK -> SCK (PB13)
DIN ->MOSI (PB15)
DOUT ->MISO (PB14)
RDY -> PD10
MCLKIN, MCLKOUT к резонатору
CS -> DGND
RESET ->DVdd +3v
DVdd (пин 27) -> DVdd
AIN7 соединен с датчиком как показано на схеме в дш

Не надо ведь управлять сигналом SCLK вручную?
Go to the top of the page
 
+Quote Post
artkam
сообщение May 28 2013, 13:29
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 14-09-10
Из: Уфа
Пользователь №: 59 479



Отсоедините CS от земли и подключите его к свободному пину, который должен быть сконфигурирован как выход в состоянии лог. 1 по умолчанию. Вы должны его устанавлдивать в лог. 0 и возвращать в лог. 1 как показано на Figure 7 даташита, например.
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 08:12
Сообщение #9





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Да, я так попробую сделать сейчас. спасибо за подсказку
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 14:05
Сообщение #10





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Вобщем подключил SS и дергаю его когда передаю-получаю данные. Для проверки посылаю 0x42, чтобы он мне вернул версию чипа. Судя по даташиту, должно прислать число, которое кончается на 0001, я его как-то раз совершенно случайно получил, это было 0х21, но вместо нее приходит 0x40.
Логический анализатор мне показывает вот такую картину:

как видно, SS работает исправно, sclk тоже работает, MOSI отправляет данные и MISO принимает
Я отправляю 0x42 в цикле с задержкой. Этот ответ чередуется с точно таким же только без 0x00 в MOSI и без 0x21 в MISO. Почему у меня 16 бит отправляется, я же выставил в настройках 8 битный режим? Почему на 0x42 приходит 0x40, а правильный ответ 0x21 только после него?

Посылаю так:
Код
while(1){
uint8_t ADC_Revision = SPI_SendRead8(0x42);
Delay(1);
}


Код
uint8_t SPI_SendRead8(uint8_t ToSend8){
    GPIO_WriteBit(GPIOD, GPIO_Pin_8, Bit_RESET); //<--SS=0
    while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
    SPI2->DR = ToSend8;
    while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
    GPIO_WriteBit(GPIOD, GPIO_Pin_8, Bit_SET); //<--SS=1
    return (SPI2->DR);
}
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 29 2013, 16:47
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(undef1ned @ May 29 2013, 20:05) *
Посылаю так:
Код
while(1){
uint8_t ADC_Revision = SPI_SendRead8(0x42);
Delay(1);
}


А надо так:
Код
while(1){
  uint8_t ADC_Revision;
  SPI_SendRead8(0x42);
  ADC_Revision = SPI_SendRead8(0);
Delay(1);
}

Чтобы прочитать ответ от ведомого SPI-устройства, надо что-нибудь отправить в него.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 16:56
Сообщение #12





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Я думал, что то что я записываю 0х42 это и есть нужная запись. Попробую теперь с двойной записью.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 29 2013, 17:14
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Как, по-вашему, АЦП по первому биту команды 0x42 догадается, что это 0x42, чтобы сразу начать отправлять ответ? sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 18:11
Сообщение #14





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Цитата(AHTOXA @ May 29 2013, 21:14) *
Как, по-вашему, АЦП по первому биту команды 0x42 догадается, что это 0x42, чтобы сразу начать отправлять ответ? sm.gif

offtop

Однако, вот что происходит, когда я посылаю сначала 0х42, а потом 0х00:
http://imgur.com/BAytYmI
Такое впечатление, что он по 16 бит кидает сразу... хотя у меня настроено на 8 бит:
Код
spi.SPI_DataSize = SPI_DataSize_8b;


edit:
Код
return (uint8_t)SPI2->DR >> 8;

Вот так вытаскивает 0x21, оказывается 0x4021 приходит сразу в регистр когда я шлю 0x42, так должно быть?

Сообщение отредактировал undef1ned - May 29 2013, 18:11
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 29 2013, 18:19
Сообщение #15


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Хм, похоже у вас SPI в 16-битном режиме. Где-то здесь пробегало описание такого косяка...
Вот, нашёл: тынц. Там, правда, F0, а не F3, но может быть оно.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 19:03
Сообщение #16





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Я когда этот макрос применяю, у меня вообще зависает на
Код
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);

Хотя вроде у F0 и у F3 одинаково:
Код
__IO uint16_t DR;       /*!< SPI data register,                                   Address offset: 0x0C */
Go to the top of the page
 
+Quote Post
undef1ned
сообщение May 29 2013, 22:56
Сообщение #17





Группа: Участник
Сообщений: 10
Регистрация: 27-05-13
Пользователь №: 76 996



Если я пишу в CR2 датасайз, соответствующий 7 бит и меньше - отправляется ровно столько бит от моего числа, а если сайз 8 бит то сразу отправляется 16 бит

Я кажется придумал как сделать. Тот хак работает, но из-за него нужно ставить таймер на NSS. Ну по крайней мере, отправляется ровно 1 байтик biggrin.gif

Код
    GPIO_WriteBit(GPIOD, GPIO_Pin_8, Bit_RESET);
    int i;
    while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
    uint32_t spixbase = 0x00;
    spixbase = (uint32_t)SPI2;
    spixbase += 0x0C;
    *(__IO uint8_t *) spixbase = ToSend8;
    //while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET); <--Вот это висит когда не SPI2->DR=smth
    for(i = 0; i < 350; i++);
    GPIO_WriteBit(GPIOD, GPIO_Pin_8, Bit_SET);
    return SPI2->DR;


Сообщение отредактировал undef1ned - May 30 2013, 00:42
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 30 2013, 17:48
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да уж. У меня до F3 пока руки не доходят. Но думаю, что такой косяк был бы на слуху. Можете привести свою инициализацию SPI?
(Если вы используете StdPeriphLib, то попробуйте обновить её, возможно, там это уже поправили).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 09:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.01545 секунд с 7
ELECTRONIX ©2004-2016