This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRV8823: How to use DRV8823

Part Number: DRV8823

Hi,Ti

I am now using DRV8823 to control the two-step motor,Now I have the following problem.

1.How to make one motor run and the other motor shut down by register command control?

2.The attachment is the source code that I control the motor operation through registers. Is there any problem?

3.What are the overheat protection and overcurrent protection values of DRV8823?Schematic and source screenshots.docx

#include "timer.h"
#include "led.h"
#include "adc.h"
#include "can.h"
#include "step.h"
#include "string.h"
#include "speed.h"
#include "spi.h"     
#include "delay.h"
#include "key.h"

uint32_t  system_count;
uint32_t  sys_event_ms;
uint32_t  sys_delay_count;
unsigned char cap_count;
unsigned char five_send_count;
extern  unsigned char change_ok;
int  cap_state;
uint32_t   time_dec,timecount1;
uint32_t  cap_val;      //����ֵ
uint32_t bicycle_cur_speed;   //������ǰ�ٶ�
//float  f_count;
//float  current_rate;
//unsigned int  un_current_rate;
unsigned char cap_flag;                     //����ɹ���־λ
unsigned int CanTaskCount; 
//float  final_per_time;                        //�����Ÿ�֮������ʱ��
extern unsigned char CanSendBuffer[8];    

void TIM1_CAP_Init(u16 arr,u16 psc)        //���벶�������     TIM3_CH4ͨ��   
{	 
		TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; 
		NVIC_InitTypeDef NVIC_InitStructure;
  	GPIO_InitTypeDef GPIO_InitStructure;
	  TIM_ICInitTypeDef  TIM1_ICInitStructure;
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);   
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //ʹ��GPIOAʱ��
	   
	  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;   
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	
   	TIM_TimeBaseStructure.TIM_Period = arr;     //�趨�������Զ���װֵ 
		TIM_TimeBaseStructure.TIM_Prescaler =psc; 	//Ԥ��Ƶ��   
		TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //����ʱ�ӷָ�:TDTS = Tck_tim
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM���ϼ���ģʽ
	   
		TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);  //����TIM_TimeBaseInitStruct��ָ���IJ�����ʼ��TIMx��ʱ�������λ

	  TIM1_ICInitStructure.TIM_Channel = TIM_Channel_1;   //CC1S=01 	ѡ������� IC1ӳ�䵽TI1��
  	TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;	   //�½���
  	TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //ӳ�䵽TI1��
  	TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	    //���������Ƶ,����Ƶ 
  	TIM1_ICInitStructure.TIM_ICFilter = 0x00;             //IC1F=0000 ���������˲��� ���˲�
  	TIM_ICInit(TIM1, &TIM1_ICInitStructure);
		
		NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;          //TIM3�ж�
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   //��ռ���ȼ�1��
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;              //�����ȼ�0��
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQͨ����ʹ��
		NVIC_Init(&NVIC_InitStructure);                                              //����NVIC_InitStruct��ָ���IJ�����ʼ������NVIC�Ĵ��� 
		
	 	TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);   //��������ж� ,����CC1IE�����ж�	
	  TIM_Cmd(TIM1,ENABLE); 	      //ʹ�ܶ�ʱ��1
}

void TIM2_Init(u16 arr,u16 psc)
{	    
			TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
			NVIC_InitTypeDef NVIC_InitStructure;
			RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 ); 
			//��ʼ����ʱ��2 TIM2	 
			TIM_TimeBaseStructure.TIM_Period = arr;          //�趨�������Զ���װֵ 
			TIM_TimeBaseStructure.TIM_Prescaler =psc;  	//Ԥ��Ƶ��   
			TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //����ʱ�ӷָ�:TDTS = Tck_tim
			TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM���ϼ���ģʽ
			TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  //����TIM_TimeBaseInitStruct��ָ���IJ�����ʼ��TIMx��ʱ�������λ
			
			NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;               //TIM2�ж�
			NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //��ռ���ȼ�1��
			NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   //�����ȼ�0��
			NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨ����ʹ��
			NVIC_Init(&NVIC_InitStructure);    //����NVIC_InitStruct��ָ���IJ�����ʼ������NVIC�Ĵ��� 
			
		  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);    //��������ж� ,����CC1IE�����ж�	
		  TIM_Cmd(TIM2,ENABLE); 	 //ʹ�ܶ�ʱ��2
}

void TIM4_Init(u16 arr,u16 psc)
{	 
			TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
			NVIC_InitTypeDef NVIC_InitStructure;
			RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
			//��ʼ����ʱ��2 TIM4
			TIM_DeInit(TIM4);
			TIM_TimeBaseStructure.TIM_Period = arr;             //�趨�������Զ���װֵ 
			TIM_TimeBaseStructure.TIM_Prescaler =psc;      	//Ԥ��Ƶ��   
			TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;   //����ʱ�ӷָ�:TDTS = Tck_tim
			TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM���ϼ���ģʽ
			TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    //����TIM_TimeBaseInitStruct��ָ���IJ�����ʼ��TIMx��ʱ�������λ
			
			NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;    //TIM2�ж�
			NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //��ռ���ȼ�1��
			NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   //�����ȼ�0��
			NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨ����ʹ��
			NVIC_Init(&NVIC_InitStructure);   //����NVIC_InitStruct��ָ���IJ�����ʼ������NVIC�Ĵ��� 
			
			TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    //��������ж� ,����CC1IE�����ж�
		  TIM_Cmd(TIM4,ENABLE); 	//ʹ�ܶ�ʱ��2
}

extern VCU_to_MCU_INF vcu_to_mcu_inf;  
unsigned char five_send_count;
unsigned char m1_finshed;  
unsigned char m2_finshed;  
unsigned char H_count;
extern uint32_t self_cheak_count;  //�Լ쳬ʱ����
unsigned char CanTestBuffer[8];
uint32_t  speed_store[10];             //�ٶ�ֵ�ݴ�    
unsigned char speed_store_count;  
unsigned char simul_dis_buff[8];   //��DZ��������
short int send_gear;

void TIM2_IRQHandler( void )
{
    if(TIM_GetITStatus( TIM2 , TIM_IT_Update ) != RESET)
    {
			   TIM_ClearITPendingBit( TIM2 , TIM_FLAG_Update);       //��������жϱ�־λ����һֱ�ж�
			 	 sys_event_ms++;  
         CanTaskCount++;	
			   if( (sys_step==self_cheak_swicth)||Nspeed_update_flag)     //û���ٶȸ���   
				 {
				     self_cheak_count++;					 
				 }
	       //memcpy(CanSendBuffer,(uint8_t *)&motor_status,2);	
         vcu_to_mcu_inf.control_mcu=motor_status.Gear_change_sta;					 
			   if((CanTaskCount%10)==0) 
				 {       		
								Key_return=ReadKeyValue(); 
								if(Key_return & KEY_UP)	                           
								{
												 if(Key_return & PRESS_KEY1)                 //����1����        //����һ��������־λ  ��Ŀ�굵λ
												 {
															 if( ( Is_change_gear==0x01) &&( UP_chan_gear_cmd==0))      //��������ʱ������Ӧ�Ӽ�����
															 {
																			if( motor_status.Gear_position!=0x04)       //����������ʱ����λ��4������Ӧ
																			{ 
																						 UP_chan_gear_cmd= 0x01;
																						 will_go_gear=  motor_status.Gear_position+1;   
																			}								
															 }
												 }	 
												if(Key_return & PRESS_KEY2)       //����2����       //����һ��������־λ ��Ŀ�굵λ
												{
															 if( ( Is_change_gear==0x01 ) &&( DOWN_chan_gear_cmd==0) )       //���ڽ���ʱ������Ӧ��������
															 {
																		 if(motor_status.Gear_position!=0x01)          //�н�������ʱ����λ��һ������Ӧ
																		 {
																						DOWN_chan_gear_cmd=0x01;
																						will_go_gear= motor_status.Gear_position-1;	
																		 }
															 }
												}
								}
							 CanSendBuffer[0]=vcu_to_mcu_inf.to_goal_torque;             //Ŀ��ת��   //��λ��ǰ  ��λ�ں�
							 CanSendBuffer[1]=vcu_to_mcu_inf.to_goal_torque>>8;           
							 CanSendBuffer[2]=vcu_to_mcu_inf.to_goal_speed;              //Ŀ��ת��
							 CanSendBuffer[3]=vcu_to_mcu_inf.to_goal_speed>>8;					 
							 CanSendBuffer[4]=vcu_to_mcu_inf.control_mcu;        
							 CanSendBuffer[5]=motor_status.Gear_position;						 
  					   CanSendBuffer[6]= vcu_to_mcu_inf.to_mcu_stop|vcu_to_mcu_inf.to_mcu_is_Ngear<<1|vcu_to_mcu_inf.to_mcu_is_drive<<2|\
					                                  vcu_to_mcu_inf.to_mcu_brake<<3|vcu_to_mcu_inf.to_mcu_Reversegear<<4|vcu_to_mcu_inf.to_mcu_Forwardgear<<5|\
					                                   vcu_to_mcu_inf.to_mcu_mode<<6;												
				      CanSendBuffer[7]=0x00;      
					   	Can_Send_Msg_buff(0x0c07f003, CanSendBuffer,8);    
					    //�������ݷ�������
					     CanTestBuffer[0]=bicycle_cur_speed;
				  	   CanTestBuffer[1]=bicycle_cur_speed>>8;
					     CanTestBuffer[2]=mcu_motor_inf.mcu_speed;
	   			     CanTestBuffer[3]=mcu_motor_inf.mcu_speed>>8;
							//CanTestBuffer[2]=motor_info[0].motor_steps;                         //����
							//CanTestBuffer[3]=GPIO_ReadInputDataBit( ZERO_POINT2_PORT,ZERO_POINT2_PIN );  //��㿪��		
     				    CanTestBuffer[4]= chan_gear_sta;				
			        Can_Send_Msg_buff(0x00000001, CanTestBuffer,5);    
		     }
//				 if( (sys_event_ms%300)==0)     //300msȡһ��ֵ   ȡ10��
//				 {
//					   if( speed_store_count==10 )
//						 {
//						      speed_store_count=0;       
//						 }
//						 else
//						 {
//						         speed_store[speed_store_count] = bicycle_cur_speed;
//						         speed_store_count++;
//						 }
//				 }
				 if( (sys_event_ms%100)==0)      //100ms����  
				 {
							send_gear=motor_status.Gear_position*100;
							simul_dis_buff[0]= motor_status.Gear_position;     //��ǰ��λ
							simul_dis_buff[1]= send_gear;
							simul_dis_buff[2]= send_gear>>8;
					     simul_dis_buff[3]=  50 ;
	   				   simul_dis_buff[4]= 00;
							 simul_dis_buff[5]=0x02;
							 simul_dis_buff[6]=  mcu_motor_inf.mcu_torque ;     //����ֵ
							 simul_dis_buff[7]=  mcu_motor_inf.mcu_torque>>8  ;		 
								Can_Send_Msg_x(0x02,0x1f,0x00,0x32,0x00,simul_dis_buff,3);     
				 }
				 if( (sys_event_ms%250)==0)     //250ms����     //����ʵ��
				 {
					     actual_speed=actual_speed*100;
							 simul_dis_buff[0]=actual_speed;
							 simul_dis_buff[1]=actual_speed>>8;
							 Can_Send_Msg_x(0x02,0x1f,0x00,0x32,0x01,simul_dis_buff,2);         
				 }
    }			
}

void TIM1_CC_IRQHandler(void)
{
	      if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
				{
					        cap_count++; 
				}	
				if(TIM_GetITStatus(TIM1,TIM_IT_CC1)!=RESET)
				{
					        cap_state++;		   
									if( cap_state==1)   
									{
										    cap_count=0;
										    time_dec = sys_event_ms;        						
									}
									else if( cap_state== 17 )                     //��Ȧ һȦ32���ź�
									{
										   cap_state=0;
										   timecount1=sys_event_ms;
										   cap_val=timecount1-time_dec;
					   					 cap_flag=1;
			//			   timecount1=0;
			//			   time_dec=0;
//										    cap_state=0;
//										    timecount1=TIM_GetCapture1(TIM1);  
//										   if(timecount1>time_dec)
//											 {
//													   cap_val=(timecount1-time_dec)/100;  
//														 cap_val=cap_val+cap_count*653;
//												     cap_val=cap_val/10;
//												     cap_count=0;    
//												     cap_flag=1;
//											 } 								
//												else
//												{
//												  	 cap_val=((0xffff - time_dec)+timecount1)/100;     
//										    		 cap_count=cap_count-1;
//  													 cap_val=cap_val+cap_count*653;
//												  	cap_val=cap_val/10;
//  													 cap_count=0;
//														 cap_flag=1;
//												}
									}
				}
        TIM_ClearITPendingBit(TIM1, TIM_IT_CC1|TIM_IT_Update);     
}	

unsigned char timer1_count;
unsigned char count;
unsigned char timer4_count;
unsigned char i;

short int clear_m0=0x0000;
short int clear_m1=0x1000;

void TIM4_IRQHandler(void)    
{ 
		if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
		{	
		   TIM_ClearITPendingBit(TIM4, TIM_IT_Update); 
		   timer4_count++;
		   cheak_zero_position();     
			 for(i=0;i<motor_num;i++)
			 {
	 	     if(motor_info[i].motor_num_en==0x01)                  //���1ʹ��
				 	{
										 if( motor_info[i].motor_dir==0x01)              //������
										 {
														if( motor_info[i].motor_steps!=0)         //������Ϊ0
														{  
																SLEEP_HIGH();									
																if(i==0)      //��1�ŵ��  ��ת 
																{	    
													           //command_send(0x0000);    
																		 command_send(motor1_ZZ_cmd[motor_info[i].send_count]);
																		 motor_info[i].send_count++; 	  
																		 if(motor_info[i].send_count==0x04)              
																		 {		
																					motor_info[i].send_count=0;   
																					motor_info[i].motor_steps--;  	 					   
																		 }				 
																}
																if(i==1)   //��2�ŵ��  ��ת
																{
														        // command_send(0x1000);
																		 command_send( motor2_ZZ_cmd[motor_info[i].send_count]);
																		 motor_info[i].send_count++;				  
																		 if(motor_info[i].send_count==0x04)    
																		 {
																					motor_info[i].send_count=0;   
																					motor_info[i].motor_steps--;   
																		 }		 
																} 		
														}
														else
														{
																 motor_info[i].motor_num_en=0;
																 motor_info[i].send_count=0;
																 motor_info[i].motor_dir=0;
																 SLEEP_LOW();   
																 motor_info[i].running=0;
																
														}
												 }
												 else
												 {
														if( motor_info[i].motor_steps!=0)    //������Ϊ0
														{  
																SLEEP_HIGH();
																if(i==0)    //��1�ŵ��  ��ת
																{
												        //     command_send(0x0000);
																		 command_send( motor1_FZ_cmd[motor_info[i].send_count]);
																		 motor_info[i].send_count++;	  
																		 if(motor_info[i].send_count==0x04)  
																		 {  
																				motor_info[i].send_count=0;
																				motor_info[i].motor_steps--;    		 			
																		 }		
																}
																if(i==1)   //��2�ŵ��  ��ת
																{
									        			      // command_send(0x1000);    
																		 command_send( motor2_FZ_cmd[motor_info[i].send_count]);  
																		 motor_info[i].send_count++;  
																		 if(motor_info[i].send_count==0x04)
																		 {
																				motor_info[i].send_count=0;
																				motor_info[i].motor_steps--;      	
																		 }	 
																}    		
														}
														else
														{
																 SLEEP_LOW();  
																 motor_info[i].motor_num_en=0;  
																 motor_info[i].send_count=0;
																 motor_info[i].motor_dir=0;
																 motor_info[i].running=0;
																//motor_info[i].is_find_zero=0;
																//motor_info[i].find_zero=0;
														}
										 }
			     	}		
			 }				 
		 }		
}	

  • Hello, Dominic:

    1. The xENBL bits in the serial interface registers enable current flow in each H-bridge when set to 1. Bit xENBL=0 can shut down the motor.

    2. We don't review the source code. But, the EVM firmware is provided as reference which can be downloaded from  https://www.ti.com/lit/zip/slvc423

    3.  All motor driver device datasheets provide the OCP and OTS parameters in the spec table.