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

 
 
> 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

Сообщений в этой теме
- undef1ned   STM32 <-spi-> внешний ADC   May 27 2013, 15:51
- - artkam   А где у Вас в коде управление ногой CHIP SELECT (C...   May 27 2013, 20:49
|- - undef1ned   Цитата(artkam @ May 28 2013, 00:49) А где...   May 27 2013, 21:38
- - artkam   Поверьте, CS обязательно требуется притягивать к з...   May 27 2013, 22:10
- - undef1ned   Да, у меня CS (4 пин) подключен к GND на stm32f3-d...   May 27 2013, 22:41
- - artkam   Приведите пожалуйста схему подключения АЦП к МК...   May 28 2013, 12:44
- - undef1ned   Ну собственно, от AD7738 к мк идут только SCLK, RD...   May 28 2013, 13:13
- - artkam   Отсоедините CS от земли и подключите его к свободн...   May 28 2013, 13:29
- - undef1ned   Да, я так попробую сделать сейчас. спасибо за подс...   May 29 2013, 08:12
- - undef1ned   Вобщем подключил SS и дергаю его когда передаю-пол...   May 29 2013, 14:05
|- - AHTOXA   Цитата(undef1ned @ May 29 2013, 20:05) По...   May 29 2013, 16:47
- - undef1ned   Я думал, что то что я записываю 0х42 это и есть ну...   May 29 2013, 16:56
|- - AHTOXA   Как, по-вашему, АЦП по первому биту команды 0x42 д...   May 29 2013, 17:14
|- - undef1ned   Цитата(AHTOXA @ May 29 2013, 21:14) Как, ...   May 29 2013, 18:11
|- - AHTOXA   Хм, похоже у вас SPI в 16-битном режиме. Где-то з...   May 29 2013, 18:19
- - undef1ned   Я когда этот макрос применяю, у меня вообще зависа...   May 29 2013, 19:03
- - undef1ned   Если я пишу в CR2 датасайз, соответствующий 7 бит ...   May 29 2013, 22:56
- - AHTOXA   Да уж. У меня до F3 пока руки не доходят. Но думаю...   May 30 2013, 17:48


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

 


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


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