Создание собственной системы стабилизации
херова ((
могу STM32F4DISCOVERY по себестоимости передать с кем (с налогами и доставкой чета около 23$), если кто будет ехать из знакомых… не пользованая по сути… себе по надобности новую закажу…
есть дырка, но к сожалению, уже в долги залез, так что накоплю - куплю себе проц нормальный…
ИМХО , если не использовать DMP , то закладывать в разработку MPU-6000 было несовсем правильное решение ибо недешево и вечные проблемы с доставабельностью … может есть смысл сделать еще один вариант верхней платы на чемнибуди более даставабельном ??? LSM330 или L3g4200 + bma180 ???
PS: интересно что быстрее станет доступно LSM333 или MPU-9250 …
PPS: посылку собрал …
чёт не догоняю я этот uart dma, uart1 dma1, а какой Stream ? тфу-ты из AutoQuad-а выдернуть же можно…
LSM330
чёта я лсм-ки наелся, хотяяя - жду безветрия попробую, должно уже нормально полететь…
блин уже башка трещит, stream а потом chanel ещё, куда чего писать?
www.digikey.com рулит… дистрибьюторы по всему миру… даж РБ вроде www.digikey.by ценник пожалуй самый низкий, а ассортимент товара огромный… есть если не все, то почти все… не знаю только что с доставкой в РБ… в канаду 7$…
Не не, доставка у них от 100$ в Беларусь. А по ценнику, посмотри и биплатно пришлют 😃
А по ценнику, посмотри и биплатно пришлют
только картинка зачётная не vgt а vet 😃 а в vet только вий и аероквад лезут, у остальных проектов флеха занята под 400кb и выше…
ну вот, переделанный uart Билла Несбита, под f4 ихний почему-то не нашел, так что переделывал старый, который спёр Таймкоп
#include "board.h"
/*
DMA UART routines idea lifted from AutoQuad
Copyright © 2011 Bill Nesbitt
*/
#define UART_BUFFER_SIZE 256
// Receive buffer, circular DMA
volatile uint8_t rxBuffer[UART_BUFFER_SIZE];
uint32_t rxDMAPos = 0;
volatile uint8_t txBuffer[UART_BUFFER_SIZE];
uint32_t txBufferTail = 0;
uint32_t txBufferHead = 0;
static void uartTxDMA(void)
{
DMA1_Stream4->M0AR = (uint32_t)&txBuffer[txBufferTail];
if (txBufferHead > txBufferTail) {
DMA1_Stream4->NDTR = txBufferHead - txBufferTail;
txBufferTail = txBufferHead;
} else {
DMA1_Stream4->NDTR = UART_BUFFER_SIZE - txBufferTail;
txBufferTail = 0;
}
DMA_Cmd(DMA1_Stream4, ENABLE);
}
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4);
DMA_Cmd(DMA1_Stream4, DISABLE);
if (txBufferHead != txBufferTail)
uartTxDMA();
}
void uartInit(uint32_t speed)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// USART1_TX PA9
// USART1_RX PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// Receive DMA into a circular buffer
DMA_DeInit(DMA1_Stream5);
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rxBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_BufferSize = UART_BUFFER_SIZE;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
DMA_Cmd(DMA1_Stream5, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
rxDMAPos = DMA_GetCurrDataCounter(DMA1_Stream5);
// Transmit DMA
DMA_DeInit(DMA1_Stream5);
DMA_InitStructure.DMA_Channel = DMA_Channel_5;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
DMA1_Stream5->NDTR = 0;
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_Cmd(USART1, ENABLE);
}
uint16_t uartAvailable(void)
{
return (DMA_GetCurrDataCounter(DMA1_Stream5) != rxDMAPos) ? true : false;
}
bool uartTransmitEmpty(void)
{
return (txBufferTail == txBufferHead);
}
uint8_t uartRead(void)
{
uint8_t ch;
ch = rxBuffer[UART_BUFFER_SIZE - rxDMAPos];
// go back around the buffer
if (--rxDMAPos == 0)
rxDMAPos = UART_BUFFER_SIZE;
return ch;
}
uint8_t uartReadPoll(void)
{
while (!uartAvailable()); // wait for some bytes
return uartRead();
}
void uartWrite(uint8_t ch)
{
txBuffer[txBufferHead] = ch;
txBufferHead = (txBufferHead + 1) % UART_BUFFER_SIZE;
// if DMA wasn't enabled, fire it up
if (!(DMA1_Stream4->CR & 1))
uartTxDMA();
}
void uartPrint(char *str)
{
while (*str)
uartWrite(*(str++));
}
/* -------------------------- UART2 ----------------------------- */
uartReceiveCallbackPtr uart2Callback = NULL;
#define UART2_BUFFER_SIZE 128
volatile uint8_t tx2Buffer[UART2_BUFFER_SIZE];
uint32_t tx2BufferTail = 0;
uint32_t tx2BufferHead = 0;
bool uart2RxOnly = false;
static void uart2Open(uint32_t speed)
{
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | (uart2RxOnly ? 0 : USART_Mode_Tx);
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
}
void uart2Init(uint32_t speed, uartReceiveCallbackPtr func, bool rxOnly)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
uart2RxOnly = rxOnly;
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// USART2_TX PD5
// USART2_RX PD6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
if (!rxOnly)
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
uart2Open(speed);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
if (!rxOnly)
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
uart2Callback = func;
}
void uart2ChangeBaud(uint32_t speed)
{
uart2Open(speed);
}
void uart2Write(uint8_t ch)
{
if (uart2RxOnly)
return;
tx2Buffer[tx2BufferHead] = ch;
tx2BufferHead = (tx2BufferHead + 1) % UART2_BUFFER_SIZE;
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
}
bool uart2TransmitEmpty(void)
{
return tx2BufferTail == tx2BufferHead;
}
void USART2_IRQHandler(void)
{
uint16_t SR = USART2->SR;
if (SR & USART_IT_RXNE) {
if (uart2Callback)
uart2Callback(USART_ReceiveData(USART2));
}
if (SR & USART_FLAG_TXE) {
if (tx2BufferTail != tx2BufferHead) {
USART2->DR = tx2Buffer[tx2BufferTail];
tx2BufferTail = (tx2BufferTail + 1) % UART2_BUFFER_SIZE;
} else {
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
}
}
}
/* -------------------------- UART3 ----------------------------- */
uartReceiveCallbackPtr uart3Callback = NULL;
#define UART3_BUFFER_SIZE 128
volatile uint8_t tx3Buffer[UART3_BUFFER_SIZE];
uint32_t tx3BufferTail = 0;
uint32_t tx3BufferHead = 0;
bool uart3RxOnly = false;
static void uart3Open(uint32_t speed)
{
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = speed;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | (uart3RxOnly ? 0 : USART_Mode_Tx);
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void uart3Init(uint32_t speed, uartReceiveCallbackPtr func, bool rxOnly)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
uart3RxOnly = rxOnly;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// USART2_TX PD8
// USART2_RX PD9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
if (!rxOnly)
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOD, &GPIO_InitStructure);
uart3Open(speed);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
if (!rxOnly)
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
uart3Callback = func;
}
void uart3ChangeBaud(uint32_t speed)
{
uart3Open(speed);
}
void uart3Write(uint8_t ch)
{
if (uart3RxOnly)
return;
tx3Buffer[tx3BufferHead] = ch;
tx3BufferHead = (tx3BufferHead + 1) % UART3_BUFFER_SIZE;
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
}
bool uart3TransmitEmpty(void)
{
return tx3BufferTail == tx3BufferHead;
}
void USART3_IRQHandler(void)
{
uint16_t SR = USART3->SR;
if (SR & USART_IT_RXNE) {
if (uart3Callback)
uart3Callback(USART_ReceiveData(USART3));
}
if (SR & USART_FLAG_TXE) {
if (tx3BufferTail != tx3BufferHead) {
USART3->DR = tx3Buffer[tx3BufferTail];
tx3BufferTail = (tx3BufferTail + 1) % UART3_BUFFER_SIZE;
} else {
USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
}
}
}
проект компилится, но далеко не факт что я что-то не намудрил 😃
только вот под телеметрию, тоже с DMA надо? если да то - ну его нафиг 😃
Вышел новый Кролик 😃
www.aliexpress.com/item/…/820519824.html
Параметры они не пишут но примерно наверно можно прикинуть что там
- 32 digits 72 MHZ CPU
- Gyroscope: ±2000dps,16 digits resolution ratio, responding time:1000HZ
- Accelerometer: -8G,14 digits resolution ratio, responding time:800Hz
- Digital Compass:± 1 deg
Мне что-то думается что туда с минимальными переделками зальется версия от timecop, или я ошибаюсь? 😃
Даже подумалось не купить ли одного кролика на опыты…
Параметры они не пишут но примерно наверно можно прикинуть что там - 32 digits 72 MHZ CPU - Gyroscope: ±2000dps,16 digits resolution ratio, responding time:1000HZ - Accelerometer: -8G,14 digits resolution ratio, responding time:800Hz - Digital Compass:± 1 deg
“Кролики это не только ценный мех…” Что там за проц? Какая шина к датчикам? В целом схематехнику не плохо бы было посмотреть… Если там СТМ то можно залить что угодно, вопрос только в количестве памяти и функционале ШИМ-входов\выходов.
только вот под телеметрию, тоже с DMA надо? если да то - ну его нафиг
ПДП по уарт не использовал, но в самом деле нет никого волшебства, должно работать. Главное правильно распределить каналы, чтоб не получилось что 2 разных устройства используют один канал.
Вот у меня так :
/*******************************************************************************
* Function Name : USART_Config_Default.
* Description : configure the USART1 with default values.
* Input : None.
* Return : None.
*******************************************************************************/
void USART1_Config(uint32_t rate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* подадим такт на порт */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
/* настройка выводов порта */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Соединим выводы портов с AF7 */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_7);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_7);
/* обнуляем указатели буферов */
USART1_TX_src_ptr = USART1_TX_dst_ptr = 0;
USART1_RX_src_ptr = USART1_RX_dst_ptr = 0;
/* настройка УПСИ */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_InitStructure.USART_BaudRate = rate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART Receive interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
NVIC_EnableIRQ(USART1_IRQn);
NVIC_SetPriority(USART1_IRQn, 15);
}
/*************** передача байта в УСПСИ *************************/
uint8_t USART1_TX_buff[256]; /* буфер для передачи УСПИСИ */
uint8_t USART1_TX_src_ptr; /* указатель на буфер для передачи УСПИСИ */
uint8_t USART1_TX_dst_ptr; /* указатель на буфер для передачи УСПИСИ */
void USART1_Transmite(uint8_t data)
{
USART1_TX_buff[USART1_TX_src_ptr++] = data;
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
/**************** приём байта из УСПСИ ****************************/
uint8_t USART1_RX_buff[256]; /* буфер для приема УСПИСИ */
uint8_t USART1_RX_src_ptr; /* указатель на буфер для приема УСПИСИ */
uint8_t USART1_RX_dst_ptr; /* указатель на буфер для приема УСПИСИ */
uint8_t USART1_Recieve()
{
if(USART1_RX_dst_ptr == USART1_RX_src_ptr)
return 0;
else
return USART1_RX_buff[USART1_RX_dst_ptr++];
}
/**************** получение кол-ва принятых байт УСПСИ ****************************/
uint8_t USART1_Available(void)
{
return (USART1_RX_dst_ptr != USART1_RX_src_ptr) ;
}
обработчик
/*******************************************************************************
* Function Name : EVAL_COM1_IRQHandler
* Description : This function handles EVAL_COM1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
/* ïðè¸ì */
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
{
USART1_RX_buff[USART1_RX_src_ptr++] = USART_ReceiveData(USART1);
}
/* ïåðåäà÷à */
if (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET)
{
if (USART1_TX_dst_ptr == USART1_TX_src_ptr)
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
else USART_SendData(USART1, USART1_TX_buff[USART1_TX_dst_ptr++]);
}
if (USART_GetFlagStatus(USART1, USART_FLAG_TC) == SET)
USART_ClearFlag(USART1, USART_FLAG_TC);
/* If overrun condition occurs, clear the ORE flag and recover communication */
if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
{
(void)USART_ReceiveData(USART1);
USART_ClearFlag(USART1, USART_FLAG_ORE);
}
}
обложки
extern void USART_Transmite(uint8_t data);
extern uint8_t USART_Recieve(void);
uint8_t USART_Available(void);
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE* f)
{
//ITM_SendChar(ch);
USB_PutChar(ch);
USART1_Transmite(ch);
return ch;
}
int fgetc(FILE *f)
{
// if (ITM_CheckChar()){
// return ITM_ReceiveChar();
// }
if (USB_Available()) {
return USB_GetChar();
}
if (USART1_Available()){
return USART1_Recieve();
}
return EOF;
}
то что про УСБ закомметируй
Вышел новый Кролик
переделывать нужно будет, но не критично…
вчера, сегодня и наверно и завтра сижу с детьми, пасха, жена в костёле пропадает, да и готовить на стол надо, так что не подходил не к чему…
а, вот, нормально, что загрузчик требует выбрать сколько флеши в проце, на 103-м сам определял?
Соединим выводы портов с AF7
так можно только цифирку писать - AF из таблицы? а я писал везде uartX, timerX…
блин, решил поморгать светодиодиками, а работают только 2 из четырёх - обидно…
А кто что думает по поводу DMP в MPU6000/MPU6050, он по идее сам фузинит данные акселя и гиры и выдает кватернионы. Стоит с ним возится?
А кто что думает по поводу DMP в MPU6000/MPU6050, он по идее сам фузинит данные акселя и гиры и выдает кватернионы. Стоит с ним возится?
У него есть проблема с “фузинированием” данных от компаса 😃
блин, решил поморгать светодиодиками, а работают только 2 из четырёх - обидно…
разобрался, ну по крайней мере проц рабочий, плата правильная, можно извращатся дальше 😃
У него есть проблема с “фузинированием” данных от компаса
Это да, врожденный недостаток сенсора =)))
так можно только цифирку писать - AF из таблицы? а я писал везде uartX, timerX…
Это если у тебя эти имена определены, я то стандартными библиотеками пользуюсь.
А кто что думает по поводу DMP в MPU6000/MPU6050,
Для меня более интересно было бы иметь транзит данных компаса с И2Ц на МПУшный SPI.
Для меня более интересно было бы иметь транзит данных компаса с И2Ц на МПУшный SPI.
В Multiwii посмотрите, они настраивают MPU на чтение компаса, а сами потом уже читают данные из внутренних регистров MPU.
там просто транзит, а вот по 6000 бог его знает, надо чтобы мпу мастером читала компас записывала в регистры, а потом их (данные) можно было забрать через spi…
зря я кнопочку reset не сделал и место под неё как раз есть, надо будет исправить…
там просто транзит, а вот по 6000 бог его знает, надо чтобы мпу мастером читала компас записывала в регистры, а потом их (данные) можно было забрать через spi…
Там как раз так и сделано, во всяком случае в 2.2:
Чтение компаса:
//The MAG acquisition function must be replaced because we now talk to the MPU device
#if defined(MPU6050_I2C_AUX_MASTER)
void Device_Mag_getADC() {
i2c_getSixRawADC(MPU6050_ADDRESS, 0x49); //0x49 is the first memory room for EXT_SENS_DATA
#if defined(HMC5843)
....
инициализация MPU:
#if defined(MPU6050_I2C_AUX_MASTER)
//at this stage, the MAG is configured via the original MAG init function in I2C bypass mode
//now we configure MPU as a I2C Master device to handle the MAG via the I2C AUX port (done here for HMC5883)
i2c_writeReg(MPU6050_ADDRESS, 0x6A, 0b00100000); //USER_CTRL -- DMP_EN=0 ; FIFO_EN=0 ; I2C_MST_EN=1 (I2C master mode) ; I2C_IF_DIS=0 ; FIFO_RESET=0 ; I2C_MST_RESET=0 ; SIG_COND_RESET=0
i2c_writeReg(MPU6050_ADDRESS, 0x37, 0x00); //INT_PIN_CFG -- INT_LEVEL=0 ; INT_OPEN=0 ; LATCH_INT_EN=0 ; INT_RD_CLEAR=0 ; FSYNC_INT_LEVEL=0 ; FSYNC_INT_EN=0 ; I2C_BYPASS_EN=0 ; CLKOUT_EN=0
i2c_writeReg(MPU6050_ADDRESS, 0x24, 0x0D); //I2C_MST_CTRL -- MULT_MST_EN=0 ; WAIT_FOR_ES=0 ; SLV_3_FIFO_EN=0 ; I2C_MST_P_NSR=0 ; I2C_MST_CLK=13 (I2C slave speed bus = 400kHz)
i2c_writeReg(MPU6050_ADDRESS, 0x25, 0x80|MAG_ADDRESS);//I2C_SLV0_ADDR -- I2C_SLV4_RW=1 (read operation) ; I2C_SLV4_ADDR=MAG_ADDRESS
i2c_writeReg(MPU6050_ADDRESS, 0x26, MAG_DATA_REGISTER);//I2C_SLV0_REG -- 6 data bytes of MAG are stored in 6 registers. First register address is MAG_DATA_REGISTER
i2c_writeReg(MPU6050_ADDRESS, 0x27, 0x86); //I2C_SLV0_CTRL -- I2C_SLV0_EN=1 ; I2C_SLV0_BYTE_SW=0 ; I2C_SLV0_REG_DIS=0 ; I2C_SLV0_GRP=0 ; I2C_SLV0_LEN=3 (3x2 bytes)
#endif