Господа, помогите разобраться.
У меня есть 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