Перейти к содержанию

Работа С Hal_Spi


ukr823f

Рекомендуемые сообщения

Доброго времени суток. Изучаб STM32. В наличии STM32F4Discovery с STM32F407VG на борту. Пытаюсь работать с акселерометром на плате LIS3DSH. Пытаюсь разобраться с применением CubeMX и HAL библиотеки, но уже если честно надоело. Не работает и всё проект написанный с помощью HAL. А самое интересное с применением STdPeriph - всё олично. передал настройки, считываю регистры. Получаю нцжные мне данные. Натсройки SPI в обеих случаях одинаковые.

Вот привожу рабочий код написанный в Coocox

#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_spi.h"
#include "lis302dl.h"
#include "stdio.h"
short x, y, z;
short x_l, y_l, z_l;
short x_h, y_h, z_h;

uint8_t writeData(uint8_t data) {
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
;
SPI_I2S_SendData(SPI1, data);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
 ;
return SPI_I2S_ReceiveData(SPI1);
}
void setReg(uint8_t address, uint8_t value) {
GPIO_ResetBits(GPIOE,GPIO_Pin_3);
writeData(address);
writeData(value);
GPIO_SetBits(GPIOE,GPIO_Pin_3);
}
uint8_t getReg(uint8_t address) {
int data=0;
address|=(1<<7);
GPIO_ResetBits(GPIOE,GPIO_Pin_3);
writeData(address);
data = writeData(0x00);
GPIO_SetBits(GPIOE,GPIO_Pin_3);
return data;
}
void delay() {
volatile uint32_t i;
for(i=0;i<=13000;i++)
;
}
int main(void)
{
void spi_init() {
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
// Тактирование модуля SPI1 и порта А
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOD, ENABLE);
// Настраиваем ноги SPI1 для работы в режиме альтернативной функции
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |GPIO_Pin_15 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//Заполняем структуру с параметрами SPI модуля
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //полный дуплекс
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // передаем по 8 бит
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // Полярность и
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // фаза тактового сигнала
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // Управлять состоянием сигнала NSS программно
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // Предделитель SCK
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Первым отправляется старший бит
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Режим - мастер
SPI_Init(SPI1, &SPI_InitStructure); //Настраиваем SPI1
SPI_Cmd(SPI1, ENABLE); // Включаем модуль SPI1....
// Поскольку сигнал NSS контролируется программно, установим его в единицу
// Если сбросить его в ноль, то наш SPI модуль подумает, что
// у нас мультимастерная топология и его лишили полномочий мастера.
SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);
}
spi_init(); //Инициализация SPI
// Включить акселерометр. Это минимальная инициализация.
// setReg(LIS302DL_CTRL_REG1, (1<<PD_CTRL_REG1) );
setReg(0x20, 0x5F);
setReg(0x24, 0x40);
while(1)
{
 delay();
	 x = (getReg(0x29)*256)+getReg(0x28);
	 delay();
	 y = (getReg(0x2B)*256)+getReg(0x2A);
	 delay();
	 z = (getReg(0x2D)*256)+getReg(0x2C);
	 delay();
 if(x<8000)
 {
 GPIO_SetBits(GPIOD,GPIO_Pin_13);
 }
 else
 {
 GPIO_ResetBits(GPIOD,GPIO_Pin_13);
 }

}
}

А вот так выглядит неработающий код написанный с помощью HAL. Где ошибка, почему не работает, ведь всё одинаково...

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t address = 0;
uint8_t data = 0;
uint8_t data_return[2] = {0};
uint8_t x_l, x_h;

/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
address = 0x20;
HAL_SPI_Transmit(&hspi1, &address, 1, 0x1000);
address = 0x5F;
HAL_SPI_Transmit(&hspi1, &address, 1, 0x1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
address = 0x24;
HAL_SPI_Transmit(&hspi1, &address, 1, 0x1000);
address = 0x40;
HAL_SPI_Transmit(&hspi1, &address, 1, 0x1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(100);
   HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
   address = 0xA8;
   HAL_SPI_TransmitReceive(&hspi1, &address, &data, sizeof(data), 0x1000);
   address = 0x00; //00000000
   HAL_SPI_TransmitReceive(&hspi1, &address, &SPI_data, sizeof(data), 0x1000);
   HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);   

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
/* SPI1 init function */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi1.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi1);
}
/** Configure pins as
 * Analog
 * Input
 * Output
 * EVENT_OUT
 * EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOE_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
/*Configure GPIO pin : PE3 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pins : PD12 PD13 PD14 PD15 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)
{

}

А что самое интересное - адрес считывает вот такой конструкцией

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
address = 0x8F; //10001111 - WHO_AM_I - READ
HAL_SPI_TransmitReceive(&hspi1, &address, &data, sizeof(data), 0x1000);
address = 0x00; //00000000
HAL_SPI_TransmitReceive(&hspi1, &address, &SPI_data, sizeof(data), 0x1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

А вот если такой же конструкцией читать регистр ускорения допустим 0x29 (естественно устанавливаем первый бит в 1, чтобы мы дали понять что мы считываем а не записываем - получается 0xA8) - старший байт ускорения по оси Х, то что то один раз считывается и на этом останавливается. То есть в программе STMStudio я наблюдаю что один раз что то походу считалось и всё. Сколько не дёргай плату - никаких данных...

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Сам задаю вопросы - сам отвечаю. Вроде заработало. проблема была в том, что предделитель для SPI неправильно расчитал для частоты 16мГц. Сделал предделитель = 2, и вроде пошло.

Ссылка на комментарий
Поделиться на другие сайты

  • 5 месяцев спустя...

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...