Игорь 2
Трансиверы, передатчики, РПУ => Доработка и узлы => Тема начата: vikr от Август 19, 2020, 05:51:43 pm
-
Сергей, на прошлом форуме вы вели тему -программирование для синтеза Игоря, не могли бы повторить исходники примеров работы с PCA9555 с объяснением основных моментов.
-
#define TUNER_PCA9555_ADR_READ 0b01000011 //чтение
#define TUNER_PCA9555_ADR_WRITE 0b01000010 //save
#define BPF_PCA9555_ADR_WRITE 0b01000000 //save
...
...ini
делать обязательно!
//tuner
uint8_t buferT[3] = {0b00000110, 0x0,0x0};//6-регистр инициализации портов если 0 то это выход, 0-все порты на выход
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9555_ADR_WRITE, (uint8_t *) &buferT, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(100, y, (uint8_t *) "ini-TX-5", LEFT_MODE);
};
uint8_t buferWT[3] = {0b00000010, 0x0, 0x0}; //обнуляем все порты в 0 (ничего не выбрано)
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9555_ADR_WRITE, (uint8_t *) &buferWT, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(150, y, (uint8_t *) "ini-TX-5-0", LEFT_MODE);
tx.iniTunerOK = NO;
};
.........
//запись
uint8_t buferWT[3] = {0b00000010, l, c_in};//три байта которые полетят в микруху (команда, порт0, порт1)
while (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9555_ADR_WRITE, (uint8_t *) &buferWT, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(0, 150, (uint8_t *) "tuWr-err", LEFT_MODE);
};
-
адреса
-
пример ini тюнера
void iniTunerPca(void) {//тюнер и дпф
HAL_GPIO_WritePin(i2c_switcher_GPIO_Port, i2c_switcher_Pin, GPIO_PIN_RESET);//переключатель РСА9515 1=внутр 0=наружу
tx.iniTunerOK = YES;
tx.yn = NO;
tx.needToDrawYN = YES;
tx.micYN = YES;// питание на мик
BSP_LCD_SetFont(&Font8);
uint16_t y = 10;
//lpf
uint8_t bufer[2] = {0b00000011, 0x0};//3-регистр инициализации портов если 0 то это выход, 0-все порты на выход
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9554_ADR_WRITE, (uint8_t *) &bufer, (uint16_t) 2,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(3, y, (uint8_t *) "ini-TX 4", LEFT_MODE);
tx.iniTunerOK = NO;
};
uint8_t buferW[2] = {0b00000001, 0x0}; //обнуляем все порты в 0 , RX
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9554_ADR_WRITE, (uint8_t *) &buferW, (uint16_t) 2,
(uint32_t) 500) !=
HAL_OK) {
BSP_LCD_DisplayHStringAt(50, y, (uint8_t *) "ini-TX4-0", LEFT_MODE);
tx.iniTunerOK = NO;
};
//tuner
uint8_t buferT[3] = {0b00000110, 0x0,
0x0};//6-регистр инициализации портов если 0 то это выход, 0-все порты на выход
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9555_ADR_WRITE, (uint8_t *) &buferT, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(100, y, (uint8_t *) "ini-TX-5", LEFT_MODE);
tx.iniTunerOK = NO;
};
uint8_t buferWT[3] = {0b00000010, 0x0, 0x0}; //обнуляем все порты в 0 (ничего не выбрано)
if (HAL_I2C_Master_Transmit(&hi2c3, TUNER_PCA9555_ADR_WRITE, (uint8_t *) &buferWT, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(150, y, (uint8_t *) "ini-TX-5-0", LEFT_MODE);
tx.iniTunerOK = NO;
};
//дпф
band.iniBpfOK = YES;
uint8_t buferD[3] = {0b00000110, 0x0,
0x0};//6-регистр инициализации портов если 0 то это выход, 0-все порты на выход
if (HAL_I2C_Master_Transmit(&hi2c3, BPF_PCA9555_ADR_WRITE, (uint8_t *) &buferD, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(100, y, (uint8_t *) "--BPF-INI-ERR-", LEFT_MODE);
band.iniBpfOK = NO;
};
uint8_t buferWD[3] = {0b00000010, 0x0, 0x0}; //обнуляем все порты в 0 (ничего не выбрано)
if (HAL_I2C_Master_Transmit(&hi2c3, BPF_PCA9555_ADR_WRITE, (uint8_t *) &buferWD, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(150, y + 40, (uint8_t *) "--BPF-INI-ERR-", LEFT_MODE);
band.iniBpfOK = NO;
};
//TX PCA9555
uint8_t buferv[3] = {0b00000110, 0b11111110, //кроме пина cw тон, все на входы
0b11000111};//6-регистр инициализации портов если 0 то это выход, 0-все порты на выход
if (HAL_I2C_Master_Transmit(&hi2c3, TX_PCA9555_ADR_WRITE, (uint8_t *) &buferv, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(100, y, (uint8_t *) "--tx-INI-ERR-", LEFT_MODE);
};
uint8_t buferWv[3] = {0b00000010, 0b00000001, 0b10001000}; // порты в 0 кроме пина cw тон
if (HAL_I2C_Master_Transmit(&hi2c3, TX_PCA9555_ADR_WRITE, (uint8_t *) &buferWv, (uint16_t) 3,
(uint32_t) 500) != HAL_OK) {
BSP_LCD_DisplayHStringAt(150, y + 40, (uint8_t *) "--tx-INI-ERR-", LEFT_MODE);
};
// buferWv[2]=0b0000000;// 1/6 reset adau 1=нормальная работа
// //1/5 en adau
// //1/4 tx on
// //1/3 mic power
// if (HAL_I2C_Master_Transmit(&hi2c3, TX_PCA9555_ADR_WRITE, (uint8_t *) &buferWv, (uint16_t) 3,
// (uint32_t) 500) != HAL_OK) {
// BSP_LCD_DisplayHStringAt(150, y+40, (uint8_t *) "--tx-INI-ERR-", LEFT_MODE);
// };
// 18900
//15000
}
-
Спасибо, буду разбираться и адаптировать к своим хотелкам.
-
Ну вот, теперь у меня есть 16-ти кнопочная клавиатура. В отличии приведённых примеров, мне нужно считывать порты, получилось.Немного протупил на том, что после инициализации нужно сбрасывать порты, в даташите об этом как кто вскользь упомянуто.
-
Сергей, теперь вопрос по ADC. как правильно его настроить для измерения напряжения АРУ? На дисплее у меня полоска бегает, но тормозит систему заметно.
-
А дайте полное описание что вы сейчас имеете и что хотите давить и от куда ару будите брать и чем ?
-
Клава то как сделана ? Прерывание?
-
Нет, опрос в цикле вывода ИНТ, как вы и предлагали. Эксперименты с ацп погибли при переходе на другую иде.Ару планирую брать с 8307
-
Я понял, нельзя в цикле сильно долгая процедура опроса, да и не желательно чтобы и2с работала во время приема. Я завтра вам вырезку сделаю по ару. Она сделано по таймеру и прерыванию и дма.
-
Настройка АРУ на STM
Сперва настроим таймер который будет дергать прерывания в котором будут перезапускаться АЦП (2шт сразу)
-
Теперь прерывания, которые собственно и будут подключены к ад8307
Внимание! у меня на этих выводах был гироскоп. Необходимо освободить эти пины иначе там будет всегда 0. Я просто выпаял микросхему гироскопа.
АЦП1
-
АЦП2
-
//main.c
//буфера куда будут писаться значения ацп (2 шт.)
/* USER CODE BEGIN PD */
__IO uint16_t IN_Buffer_sila[FRAME_SIZE];
__IO uint16_t IN_Buffer_slabo[FRAME_SIZE];
//int main(void) {
.
.
//запускаем таймер и ацп
if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK) Error_Handler();
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &IN_Buffer_sila[0], FRAME_SIZE) != HAL_OK) Error_Handler();
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *) &IN_Buffer_slabo[0], FRAME_SIZE) != HAL_OK) Error_Handler();
.
.
.....
// main.h
// здесь играемся с длиной буфера
/* USER CODE BEGIN Includes */
// NOTE: In this algorithm N and LogN can be only:
// N = 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384;
// LogN = 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14;
#define FRAME_SIZE 64 //*0.125мс = 20мс (сэмплирование 8кГц)
....
//stm32f4xx_it.c
//обработка прерывания при заполнении половины буфера или полного заполнения
/**
* @brief This function handles DMA2 stream2 global interrupt.
*/
void DMA2_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
if (DMA2->LISR & DMA_FLAG_HTIF2_6) {
// cou++;
agcDacSelectLevel(1);
}
if (DMA2->LISR & DMA_FLAG_TCIF2_6) {
agcDacSelectLevel(2);
// cou++;
}
/* USER CODE END DMA2_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc2);
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
/* USER CODE END DMA2_Stream2_IRQn 1 */
}
//какой-то ваш файл
//основная процедура АРУ
void agcDacSelectLevel(uint8_t bank) {
if (tx.yn || skip) {//|| skip
skip = 0;
return;
}
if(agc.txToRxForAgcYN){//только пришли с тх надо выставить старые значения
agc.txToRxForAgcYN=NO;
agcDacWrite( agc.beforeTxSila, 1);
agcDacWrite(agc.beforeTxSlabo , 0);
skip=YES;
agcCountSlabo=agcCountSila=0;
}
adcSlaboSumValue = 0;
adcSilaSumValue = 0;
uint16_t s = 0;
uint16_t po = (uint8_t) (FRAME_SIZE2 - 1);
uint8_t stepUp = 0;
if (agcCountSila) agcCountSila--;
if (agcCountSlabo && !yes) agcCountSlabo--;
if (agcCountDown) agcCountDown--;
if (agcCountDownSila) agcCountDownSila--;
if (agcCountSlaboUp) agcCountSlaboUp--;
if (bank == 2) {
s = FRAME_SIZE2;
po = FRAME_SIZE - 1;
}
for (int i = s; i <= po; i++) {
// if (adcSilaSumValue < IN_Buffer_sila[ s ]) adcSilaSumValue = IN_Buffer_sila[ s ];
//if (adcSlaboSumValue < IN_Buffer_slabo[ s ]) adcSlaboSumValue = IN_Buffer_slabo[ s ];
adcSlaboSumValue += IN_Buffer_slabo[ i ];
adcSilaSumValue += IN_Buffer_sila[ i ];
}
adcSlaboSumValue /= FRAME_SIZE2;
adcSilaSumValue /= FRAME_SIZE2;
// uint32_t dd = (uint32_t) ((IN_Buffer_slabo[po] + IN_Buffer_slabo[po - 1] + IN_Buffer_slabo[po - 2]+ IN_Buffer_slabo[po - 3]) / 4);
// if (dd > adcSlaboSumValue) {
// adcSlaboSumValue = dd;
// }
// adcSlaboSumValue=(adcSlaboSumValue);
// if (!adcSlaboSumValue)adcSlaboSumValue = oldSlabo;
// adcSlaboSumValue = (adcSlaboSumValue + oldSlabo) >> 1;
oldSlabo = adcSlaboSumValue;
//sila
if (//adcSilaSumValue < ADC_LEVEL_NORM_SILA + ADC_LEVEL_DELTA_SILA &&
adcSilaSumValue >= ADC_LEVEL_NORM_SILA - ADC_LEVEL_DELTA_SILA//
) {
agcCountSila = agcHoldTimeSILA;
} //если сигнал еще высокий то продолжаем задержку
if ((adcSilaSumValue > ADC_LEVEL_NORM_SILA + ADC_LEVEL_DELTA_SILA ||
adcSilaSumValue < ADC_LEVEL_NORM_SILA - ADC_LEVEL_DELTA_SILA)//- ADC_LEVEL_DELTA_SILA
) {
if (adcSilaSumValue > ADC_LEVEL_NORM_SILA + ADC_LEVEL_DELTA_SILA) {//если растет на входе + ADC_LEVEL_DELTA_SILA
uint16_t step;
agcCountSila = 0;//agcHoldTimeSILA;
// uint32_t delta = (ADC__MAX_SILA - ADC_LEVEL_NORM_SILA) / 100;
float proc = (float) (adcSilaSumValue - (ADC_LEVEL_NORM_SILA + ADC_LEVEL_DELTA_SILA)) /
delta; // % от максимально возможного на сколько процентов выше сигнал.
yesSi = 1;
// if (proc > 25) {//
// step = (uint16_t) (25 * proc);//100
// // stepDraw = (uint16_t) proc;
//
// } else {
// if (proc > 23) {//
// step = (uint16_t) (7 * proc);
//
// } else {
// if (proc > 17) {//
// step = (uint16_t) (4* proc);
//
// } else {
// if (proc > 2) {//15
// step = (uint16_t) (proc);
// yesSi = 0;
// } else {
// yesSi = 0;
// step = 1;
// }
// }
// }
// }
step = cap[(uint8_t) proc];
if (step < 40)yesSi = 0;
if (step > 300) stepUp = 1;
if (nowDacLevelSila + step <= DAC_LEVEL_MAX_SILA) { nowDacLevelSila += step; }
else { nowDacLevelSila = DAC_LEVEL_MAX_SILA; }
agcDacWrite(nowDacLevelSila, 1);
//agcDacWrite(0, 1);
}
if (adcSilaSumValue < ADC_LEVEL_NORM_SILA - 250)//- ADC_LEVEL_DELTA_SILA
{//-------------------если падает
if (!agcCountSila || yesSi) { //если задержка закончилась, поднимать усиление
uint16_t step;
float proc = (float) ((ADC_LEVEL_NORM_SILA - 250) - adcSilaSumValue) /
delta; // % от нормы , на сколько процентов ниже сигнал.
// if (proc > 10) {
// step = (uint16_t) (1000 * proc / nowDacLevelSila);
// } else {
// step = (uint16_t) (proc);
// yesSi = 0;
// if (!step)step = 1;
// }
if (!agcCountSila)proc = agcAngleSLABO; //угол наклона
yesSi = 1;
if (proc > 80) {//
step = (uint16_t) (2 * proc);//100
} else {
if (proc > 40) {//
step = (uint16_t) (proc);
} else {
if (proc > 25) {//
step = (uint16_t) (proc);
} else {
if (proc > 5) {//15
step = (uint16_t) (proc);
yesSi = 0;
} else {
yesSi = 0;
step = 1;
}
}
}
}
if (!agcCountDown) {
if (nowDacLevelSila - step >= DAC_LEVEL_MIN_SILA) { nowDacLevelSila -= step; }
else { nowDacLevelSila = DAC_LEVEL_MIN_SILA; }
agcDacWrite(nowDacLevelSila, 1);
//agcDacWrite(0, 1);
agcCountDownSila = 0;
}
}
}
} else yesSi = 0;
//
//
//slabo
//
//
if (//adcSlaboSumValue < ADC_LEVEL_NORM_SLABO + ADC_LEVEL_DELTA_SLABO &&
adcSlaboSumValue >= ADC_LEVEL_NORM_SLABO //- ADC_LEVEL_DELTA_SLABO
) {
agcCountSlabo = agcHoldTimeSLABO;
} //если сигнал еще высокий то продолжаем задержку
if (((adcSlaboSumValue > ADC_LEVEL_NORM_SLABO + 100 ||//+ ADC_LEVEL_DELTA_SLABO
adcSlaboSumValue < ADC_LEVEL_NORM_SLABO - 100))
) {
if (adcSlaboSumValue > ADC_LEVEL_NORM_SLABO + 100) {//+ ADC_LEVEL_DELTA_SLABO если растет на входе
agcCountSlabo = agcHoldTimeSLABO;
uint16_t step;
float proc = (float) (adcSlaboSumValue - (ADC_LEVEL_NORM_SLABO + 100)) /
deltaSl; // % от максимально возможного на сколько процентов выше сигнал.
if (proc > 20) {//15
step = (uint16_t) (10 * proc);//100
skip = 1;
yes = 1;
} else {
if (proc > 15) {//15
step = (uint16_t) (4 * proc);
skip = 1;
yes = 1;
} else {
if (proc > 10) {//15
step = (uint16_t) (2 * proc);
yes = 1;
} else {
if (proc > 7) {//15
step = (uint16_t) (proc);
// yes = 0;
} else {
step = (uint16_t) (proc);// /2
// yes = 0;
if (!step)step = 1;
}
}
}
}
// stepDraw = (uint16_t) proc;
// if (!agcCountSlaboUp) {//задержка на возрастание
if (nowDacLevelSlabo + step <= DAC_LEVEL_MAX_SLABO) {
nowDacLevelSlabo += step;
} else {
nowDacLevelSlabo = DAC_LEVEL_MAX_SLABO;
}
// agcDacWrite(1200, 0);
if (!stepUp) agcDacWrite(nowDacLevelSlabo, 0);
// if (yes)
// agcCountSlaboUp = 0;
// else
// agcCountSlaboUp = 0;
// agcCountSlaboUp = 10;// const задержка на возрастание
//}
}
//slabo up
if (adcSlaboSumValue < ADC_LEVEL_NORM_SLABO - 100) { //----------------------------------если падает
uint16_t step;
float proc = (float) ((ADC_LEVEL_NORM_SLABO - 100) - adcSlaboSumValue) /
delta; // % от нормы , на сколько процентов ниже сигнал.
if (!agcCountSlabo || yes) {// быстрой восстановление
if (!agcCountSlabo)proc = agcAngleSLABO; //угол наклона
if (proc > 90) {
step = (uint16_t) (proc * 2);
} else {
if (proc > 80) {
step = (uint16_t) (proc / 2);
} else {
if (proc > 70) {
step = (uint16_t) (proc / 4);
} else {
step = (uint16_t) (proc / 10);
if (!step)step = 1;
}
}
}
yes = 1;
} else {//потдерживание
if (proc < 6 && !countSlaboSlabo) {
step = 1;
countSlaboSlabo = 200;
} else {
if (countSlaboSlabo) countSlaboSlabo--;
step = 0;
}
}
if (nowDacLevelSlabo - step >= DAC_LEVEL_MIN_SLABO) {
nowDacLevelSlabo -=
step;
} else {
nowDacLevelSlabo = DAC_LEVEL_MIN_SLABO;
}
if (step)agcDacWrite(nowDacLevelSlabo, 0);
//agcDacWrite(1200, 0);
}
} else {
yes = 0;
}
}
-
Вы пока посмотрите на процедуру. Пойдут вопросы ...я тут
-
Просмотрел, смотрите почту.
-
Пишите здесь, коли начали 33wr
-
Всё таки я пойду по проторенному пути, то что уже делал, только с прерыванием от таймера.
-
Дма включите. Ацп в память будет писать без участия процессора.