Создание собственной системы стабилизации

rual
DVE:

Параметры они не пишут но примерно наверно можно прикинуть что там - 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

“Кролики это не только ценный мех…” Что там за проц? Какая шина к датчикам? В целом схематехнику не плохо бы было посмотреть… Если там СТМ то можно залить что угодно, вопрос только в количестве памяти и функционале ШИМ-входов\выходов.

SergDoc:

только вот под телеметрию, тоже с 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;
}

то что про УСБ закомметируй

oleg70

Вот что у меня осталось от DiscoveryF3 после небольшой работы с ЛУТом:

SergDoc
DVE:

Вышел новый Кролик

переделывать нужно будет, но не критично…

вчера, сегодня и наверно и завтра сижу с детьми, пасха, жена в костёле пропадает, да и готовить на стол надо, так что не подходил не к чему…
а, вот, нормально, что загрузчик требует выбрать сколько флеши в проце, на 103-м сам определял?

SergDoc
rual:

Соединим выводы портов с AF7

так можно только цифирку писать - AF из таблицы? а я писал везде uartX, timerX…

SergDoc

блин, решил поморгать светодиодиками, а работают только 2 из четырёх - обидно…

Razek

А кто что думает по поводу DMP в MPU6000/MPU6050, он по идее сам фузинит данные акселя и гиры и выдает кватернионы. Стоит с ним возится?

Sir_Alex
Razek:

А кто что думает по поводу DMP в MPU6000/MPU6050, он по идее сам фузинит данные акселя и гиры и выдает кватернионы. Стоит с ним возится?

У него есть проблема с “фузинированием” данных от компаса 😃

SergDoc
SergDoc:

блин, решил поморгать светодиодиками, а работают только 2 из четырёх - обидно…

разобрался, ну по крайней мере проц рабочий, плата правильная, можно извращатся дальше 😃

Razek
Sir_Alex:

У него есть проблема с “фузинированием” данных от компаса

Это да, врожденный недостаток сенсора =)))

rual
SergDoc:

так можно только цифирку писать - AF из таблицы? а я писал везде uartX, timerX…

Это если у тебя эти имена определены, я то стандартными библиотеками пользуюсь.

Razek:

А кто что думает по поводу DMP в MPU6000/MPU6050,

Для меня более интересно было бы иметь транзит данных компаса с И2Ц на МПУшный SPI.

Sir_Alex
rual:

Для меня более интересно было бы иметь транзит данных компаса с И2Ц на МПУшный SPI.

В Multiwii посмотрите, они настраивают MPU на чтение компаса, а сами потом уже читают данные из внутренних регистров MPU.

SergDoc

там просто транзит, а вот по 6000 бог его знает, надо чтобы мпу мастером читала компас записывала в регистры, а потом их (данные) можно было забрать через spi…

зря я кнопочку reset не сделал и место под неё как раз есть, надо будет исправить…

Sir_Alex
SergDoc:

там просто транзит, а вот по 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
mahowik

но для выполнения этого фокуса, т.е. подключения компаса как slave устр-во к mpu, надо что бы компас физически сидел на доп. i2c шине mpu…

rual
mahowik:

надо что бы компас физически сидел на доп. i2c шине mpu…

Александр, но эт понятно, жаль Сергей в своей плате это не предусмотрел.

SergDoc

Я как-то не вижу в этом особого смысла, можно будет, если всё нормально, в доработанной версии предусмотреть перемычки как в AIO
проект скомпилировал, но он, к сожалению, не запустился 😦
сижу разбираюсь…

rual
SergDoc:

проект скомпилировал, но он, к сожалению, не запустился

ну дык ты его отладчиком проутюжь, хотя бы инициализацию внутренних устройств, проблема скорей всего там.

SergDoc:

Я как-то не вижу в этом особого смысла,

Смысл есть в части упрощения процедур чтения датчиков, можно в пдп через SPI всё читать одним потоком в память, а там разбирай как хочешь. Тут смысл не в скорости, а в надёжности. Единственнный вопрос как МПУшка как мастер и2ц выводит шину из зависания.

SergDoc

не могу разобраться с памятью:

*** error 65: access violation at 0x40023800 : no 'read' permission

это в кеил, что дебаггер не знает такого камня?

SergDoc

Думаю надо начинать всё сначала, сделать периферию, а потом уже wii встраивать, ибо я уже запутался где что…

rual
SergDoc:

это в кеил, что дебаггер не знает такого камня?

Это ты эмулятором отлаживаешь? Если да, то не стоит, подключи JTAG.

SergDoc:

Думаю надо начинать всё сначала, сделать периферию, а потом уже wii встраивать, ибо я уже запутался где что…

Это правильное решение, разберись где алгоритм обращается к датчикам и устройствам и от этих точек рисуй функции вниз к перефирии.

SergDoc

залил в GIT, то что сейчас имеется github.com/SergDoc/…/Tests_NO_flight , ибо не имею представления где сейчас копать. проект под кеил и эклипс (не хочет нормально hex собирать в эклипсе, кеил собирает)…

rual:

подключи JTAG.

на данный момент, я это - сапожник без сапог 😃