TomasL skrev: ↑3 januari 2021, 01:02:18
Dessutom, om du skapar ett eget protokoll så lär ingen i hela världen kunna prata med dig, eftersom alla andra använder standardiserade protokoll.
Tror det blir lite för komplext. Men finns det färdigt bibliotek till detta i Java och C så tar jag gärna detta.
Jag har använt J1939 för CAN-bus. Det var bra. Men problemet är att jag måste bygga logiken själv.
hummel skrev: ↑3 januari 2021, 00:58:28
Om du nu av någon anledning ska skapa ett eget protokoll vad för typ av checksumma använder för att detektera trasig data? Vilken typ av handskaning har du i protokollet? Hur sköter du omsändningar?
Jag dekterar inte trasig data. Det jag har gjort är att jag sätter en DMA på 25 bytes hos min STM32 och kopplar den till en interrupt. När min STM32 får exakt 25 bytes, eller mer, så körs en funktion som läser bufferten och utför kommandon som den ska göra. Där efter tömmer bufferten. Så får den för mycket, så skrotar den datan. Skulle den också få för mycket så larmar den igenom att skicka tillbaka ett felvärde. Jag vet inte vad du menar med handskakning, men jag börjar först fråga processorn om den är redo att ta emot data. Då svarar den antingen 1 eller 0. Är det 1 så skickar jag min data och inväntar mätvärden. Jag har hört detta på 10 ms och det har fungerat bra, trots att min dator är 13 år gammal och väldigt varm.
Hur som helst så har jag fått det att fungera nu. Men jag är öppen för ett bättre protokoll. Men jag är inte rädd för ett protokoll. Jag är snarare rädd för att oavsett protokoll, så är det inte störningskänsligt. Så då spelar det ingen roll om jag har Modbus som protokoll eller J1939 som protokoll. Det går åt skogen om man skulle få så mycket störningar så att den missuppfattar 49 för 50. Då finns det inget som jag kan göra, utan jag får acceptera felvärdet.
Så här skickar jag min data. Jag bara gör en förfrågan om enheten är upptagen eller inte. Enkelt svar tillbaka. Jag kan köra så pass snabbt att till och med datorn håller på hänga efter.
Kod: Markera allt
// Control loop - When sampling thread are done, then this will quit too
while (ControlView.loggingNow.get()) {
// Ask if ready and then check
serial.askIfReady();
if(!serial.isOK())
continue;
// Send PWM and DAC
PWM[0] = ControlView.sliderSelectedP0;
PWM[1] = ControlView.sliderSelectedP1;
PWM[2] = ControlView.sliderSelectedP2;
PWM[3] = ControlView.sliderSelectedP3;
PWM[4] = ControlView.sliderSelectedP4;
PWM[5] = ControlView.sliderSelectedP5;
PWM[6] = ControlView.sliderSelectedP6;
PWM[7] = ControlView.sliderSelectedP7;
PWM[8] = ControlView.sliderSelectedP8;
DAC[0] = ControlView.sliderSelectedD0;
DAC[1] = ControlView.sliderSelectedD1;
DAC[2] = ControlView.sliderSelectedD2;
serial.transceive_PWM_DAC(PWM, DAC);
// Receive ADC, SDADC, DSDADC and DI
serial.receive_ADC_SDADC_DSDADC_DI(ADC, SDADC, DSDADC, DI);
}
För motsvarande sida.
Kod: Markera allt
// When we got a complete RX message - This function runs
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback can be implemented in the user file.
*/
uint8_t choice = RX_DATA[0];
switch (choice) {
case 48: // Ask if is ready
is_ready();
break;
case 49: // Set PWM and DAC periods and also send measurements back
read_PWM_DAC_periods_send_measurement_back();
break;
case 50: // Set Timers prescalers to memory and send status OK back
write_PWM_TIM_prescalers_to_memory();
break;
default: // Answer back that this uC is not ready
is_not_ready();
break;
}
}
Jag testade även att köra lite PWM med mitt oscilloskop. Det verkar som att oavsett jag sätter prescaler-värderna till, så visar den bara samma frekvens. Gör jag något fel?
Jag har ställt in Timer klockan på 2 Mhz.
namn.png
Bevis på att jag har valt rätt timers
namn.png
Det jag gör för att ändra prescaler.
Kod: Markera allt
int[] prescalerValues = new int[4];
prescalerValues[0] = MAX_VALUE_INTEGER_FIELD / P4_Value -1; //TIM2
prescalerValues[1] = MAX_VALUE_INTEGER_FIELD / P6_P5_Value -1; //TIM3
prescalerValues[2] = MAX_VALUE_INTEGER_FIELD / P3_P7_P8_Value -1; //TIM4
prescalerValues[3] = MAX_VALUE_INTEGER_FIELD / P0_P1_P2_Value -1; //TIM5
Där
MAX_VALUE_INTEGER_FIELD är 2*10^6 Hz = 2 000 000 Hz
Så om jag vill ha 300 Hz som PWM, så sätter jag t.ex.
P4_Value = 300.
Då blir
Kod: Markera allt
prescalerValues[0] = MAX_VALUE_INTEGER_FIELD / P4_Value - 1 = 2*10^6 / 300 - 1 = 6665
Tar jag
6665 som prescaler för (i detta fall)
htim2.Init.Prescaler så skalar jag ned TIM2 till 300 Hz då 2*10^6 Hz / 6665 = 300 Hz
Sedan när jag sätter prescaler
Kod: Markera allt
htim2.Init.Prescaler = TIM_PRESCALES[0];
htim3.Init.Prescaler = TIM_PRESCALES[1];
htim4.Init.Prescaler = TIM_PRESCALES[2];
htim5.Init.Prescaler = TIM_PRESCALES[3];
Men inget verkar hända. Hmm....
Jag kan se att värdera sätts igenom debuggern.
Edit:
Löste det nu. Det skall vara så här. Man blir lite lurad av ST
Kod: Markera allt
htim2.Instance->PSC = TIM_PRESCALES[0];
htim3.Instance->PSC = TIM_PRESCALES[1];
htim4.Instance->PSC = TIM_PRESCALES[2];
htim5.Instance->PSC = TIM_PRESCALES[3];
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.