Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:motor-ncv70514

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.

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

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

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.

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.

2014/motor-ncv70514.txt · Poslední úprava: 2015/01/18 23:02 autor: Jan Hořák