===== ZADÁNÍ ===== Pomocí vývojové desky 32F429IDISCOVERY ovládejte s využitím SPI komunikace řidič krokového motoru NCV70514. Vyčtené údaje z obvodu využijte k řízení motoru a přepošlete do počítače. ===== ÚVOD ===== Hlavním tématem tohoto projekt je integrovaný obvod NCV70514. Jedná se o inteligentní budič krokových motorů pro automobilový průmysl, strojírenství, zdravotnictví a lodní dopravu. Obvod NCV70514, byl navržen s velkým důrazem na integritu a zároveň širokou možnost přizpůsobení dle požadavků řešení. Proto se v čipu nachází všechny důležité části pro obsluhu krokových motorů. Komunikaci zajišťuje digitální část obvodu, která se taky stará o sběr informací z ostatních funkčních bloků. Nastavování a získávání parametrů probíhá prostřednictvím sběrnice SPI a několika signálních pinů. Získané informace jsou zpracovávány a dle výsledků ovládané výstupní periferie. Součásti výstupních periférií je výkonová část skládající se ze dvou H-můstků. Díky tomuto uspořádání, zapojení integrovaného obvodu vyžaduje minimum externích součástek. K napájení obvodu je použito napětí 12V. Některé části obvodu vyžadují napájení 3,3 V. To je vyřešeno pomocí integrovaného zdroje. Napětí 3,3V je používáno pro napájení digitální části. {{ :2014:motor-ncv70514:blok_ncv70514.png?400 |}} ==== NCV70514 ==== Obvod obsahuje několik pokročilých funkčních bloků, mezi ně patří výstupní dvojice H-můstek, snímače proudu, detektory podpětí a pohybu motoru, autodiagnostika. Hlavní část na kterou se podíváme je způsob komunikace pomocí směrnice SPI a několika řídících pinů. === KOMUNIKACE === V obvodu NCV70514 se nachází paměť o celkové kapacitě (velikosti) 18 bajtů. Ta je rozdělena na řídící část a stavovou část. V řídící části najdeme registry, které nastavují parametry pro funkční bloky. Protože hodnotu jednotlivých bitů, může měnit i samotný stav obvodu, má uživatel možnost do této části paměti jak zapisovat tak i číst. Ve stavové části paměti se nachází informace o stavu obvodu, zároveň se zde nacházejí výstupní hodnoty z jednotlivých funkčních bloků. Z této oblasti má uživatel právo pouze číst. Komunikace s obvodem NCV70514 probíhá pomocí protokolu o velikosti dvou bajtů. V prvním bajtu se nachází informace o adresách, do kterých chceme zapisovat, případně číst. Ve druhém bajtu je uložena hodnota, kterou chceme uložit do řídící části. Během tohoto přenosu nám obvod posílá nazpět také dvojici bajtů. Hodnoty v těchto dvou bajtech, odpovídají hodnotám ze dvou adres, o které jsme žádali v předchozí komunikaci s obvodem, případně jsme do ní zapisovali {{ :2014:motor-ncv70514:spi_komunikace.png?800 |}} ===== HW ===== K ověření komunikace jsem si navrhnul a postavil přípravek, který vidíte na obrázku níže. Na obrázcích vidíte samotné zapojení propojovací desky, která i obsahuje napájecí zdroj a voltmetr. Blokové schéma samotného přípravku pak vidíte na prostředním obrázku. Jako mikrokotrolér jsem vybral STM32F429 na demoboardu DISCOVERY. Jeho zapojení a popis od výrobce najdete v [[http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00093903.pdf|Datasheetu]]. {{:2014:motor-ncv70514:schema_prototyp.png?300|}} {{:2014:motor-ncv70514:zapojeni_prototypu.png?250|}} {{ :2014:motor-ncv70514:foto_pripravku.jpg?300|}} ===== CODE ===== Kod tohoto projektu jsem rozdělil na část v počítači a část v mikrokontroléru STM32F429. K propojení mezi těmito zařízeními jsem použil virtuální COM port vytvořený v programu STMCubeMX. K jeho rozchození je nutné si nainstalovat ovladače od výrobce a v souboru startup_stm34f429xx.s upravit údaj Heap_Size na 400. ==== MATLAB ==== V počítači jsem si vytvořil program na pro, kde je možné řídit komunikaci a zobrazit údaje v jednotlivých registrech. Jeho fotku a část výpisu kódu vidíme níže. {{ :2014:motor-ncv70514:matlab.png?400| }} function Button_step1_Callback(hObject, eventdata, handles) global s %global seriovka if (get(handles.Button_step1,'value')) fprintf(s,'STEP1_SET'); else fprintf(s,'STEP1_CLR'); end function Button_rhb_Callback(hObject, eventdata, handles) if (get(handles.Button_rhb,'value')) fprintf(s,'RHB_SET'); else fprintf(s,'RHB_CLR'); end function Button_send_Callback(hObject, eventdata, handles) global s text1=get(handles.edit_ACR1,'string'); % vyčtení hodnoty adresy pro data disp(text1(1:3)); Data_Adress=AdressHex(text1(1:3)); %volani fnc pro prevod adress text2=get(handles.edit_ACR2,'string'); % vyčtení hodnoty adresy pro čteni disp(text2(1:3)); Read_Adress=AdressHex(text2(1:3)); %Volani fnc pro prevod adress Data_Value = str2double(get(handles.edit_data,'String')); Adress=((Data_Adress*16)+Read_Adress); %disp([Adress,Data_Value]) fprintf(s,[Adress,Data_Value]); Data_In = fscanf(s,'',2); % nacteni dvou hodnot disp(Data_In) Table_temp=get(handles.Table1,'data'); Temp1=rot90(de2bi(Data_In(1),8)); % ohlasi chybu pokud nedojdou data, nutno 8 pozic jinak nefunguje pridani do tabulky Temp2=rot90(de2bi(Data_In(2),8)); % ohlasi chybu pokud nedojdou data, de2bi vyrvari sloupec->rot90 do rady disp(Temp1); disp(Temp2); Table_temp(Data_Adress)=Temp1; Table_temp(Read_Adress)=Temp2; set(handles.Table1,'data',Table_temp); ==== ARM ==== Hlavní části programu nahraného do ARM jsou obsluha přerušení v případě přijetí dat po seriové lince a samotná hlavní smyčka programu. Všechny proměnné v hlavní smyčce jsou označené jako globální, proto je možné je použít i v dalších knihovnách. První část kódu je obsluha přerušení,která se nachází v obsluze přerušení pro přijeti dat po seriové lince. Prvně dojde k načtení do registru buff_RX. Kdy se podle délky obsažené zprávy rozhoduje jestli se jedná o příkazy pro řídící piny, nebo data přímo do NCV70514. int i = 0; USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &buff_RX[0]); USBD_CDC_ReceivePacket(&hUsbDeviceHS); if (buff_RX[5]==0) //rozdeleni mezi COMMAND a daty do NCV70514 { for (i = 0; i < 4; i++){ buff_TX[i] = buff_RX[i]; //nacteni poslanych dat do echa TX[i] = buff_RX[i];} //nacteni dat do TX_SPI } else { for (i = 0; 0!=buff_RX[0]; i++) { COMMAND[i]=buff_RX[i]; } } V samotném hlavním programu dochází k inicializaci všech použitých periferií a čekání na následný stisk tlačítka. Po stisku přejde program do nekonečné smyčky, kdy jsou kontrolovány registry pro příjem a na základě uložených dat do nich jsou buď odeslány po SPI sběrnici dál, případně dojde k nastavení požadovaného pinu. uint8_t TX[4]; uint8_t RX[4]; uint8_t buff_RX[256]; uint8_t buff_TX[256]; char COMMAND[50]; int i = 0; int main(void) { SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); MX_SPI4_Init(); MX_TIM2_Init(); MX_USB_DEVICE_Init(); while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0); //cekani na stisk tlacitka while(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_0)); HAL_GPIO_TogglePin (GPIOG, GPIO_PIN_14); while (1) { //////////////////////////////////////////////////// /* Obsluha Comand */ //////////////////////////////////////////////////// if (strcmp(COMMAND, "KROK_SET") == 0) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_SET); } else if (strcmp(COMMAND, "KROK_CLR") == 0) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "SMER_SET") == 0) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_SET); } else if (strcmp(COMMAND, "SMER_CLR") == 0) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "STEP0_SET") == 0) { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "STEP0_CLR") == 0) { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "STEP1_SET") == 0) { HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "STEP1_CLR") == 0) { HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "RHB_SET") == 0) { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5,GPIO_PIN_RESET); } else if (strcmp(COMMAND, "RHB_CLR") == 0) { HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5,GPIO_PIN_RESET); } else for (i=0;i<50;i++){COMMAND[i]=0;} //Vymazani pameti //////////////////////////////////////////////////// /* Obsluha Data */ //////////////////////////////////////////////////// if (TX[0]!=0) { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4,GPIO_PIN_RESET); HAL_SPI_TransmitReceive(&hspi4,&TX[0],&RX[0],2,20); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4,GPIO_PIN_SET); HAL_GPIO_TogglePin (GPIOG, GPIO_PIN_13); USBD_CDC_SetTxBuffer(&hUsbDeviceHS, &RX[0], 2); USBD_CDC_TransmitPacket(&hUsbDeviceHS); for (i = 0; i < 4; i++){ RX[i] = 0; TX[i] = 0;} } } } ===== ZAVĚR ===== Cílem tohoto projektu bylo čtenáře seznámit se způsoby komunikace s obvodem NCV70514 a jeho propojení s počítačem. V tomto projektu najdete okrajové seznámení se samotným obvodem, způsobem jeho komunikace s okolím a seznámení s jeho vnitřními funkcemi. Vzhledem k specializovanosti samotného obvodu je datasheet nedostupný online. Ke komunikaci jsem vytvořil program v Matlabu pro obsluhu a převodník v ARM. Programem v matlabu je možné řídit jak odesílání dat pro SPI tak i samotné nastavování řídících pinů. V tabulce jdou vidět aktuální hodnoty obsažené v registru NCV70514. Pro vytvořená programu pro STM32F429 jsem použil STM32CubeMX a kód napsal v prostředí Keil 5.