===== 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.