0% found this document useful (0 votes)
100 views9 pages

TS5700N8401 STM32

The document discusses the Tamagawa protocol communication using the STM32F4 microcontroller, focusing on the implementation of a 17-bit absolute encoder for precise position feedback in servo control applications. It details the encoder's electrical parameters, communication circuit, and the necessary control, status, and data words for effective data transmission. Additionally, the document covers the configuration of the STM32F405 microcontroller's serial port and DMA for efficient communication at a baud rate of 2.5Mbps.

Uploaded by

bokic88
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views9 pages

TS5700N8401 STM32

The document discusses the Tamagawa protocol communication using the STM32F4 microcontroller, focusing on the implementation of a 17-bit absolute encoder for precise position feedback in servo control applications. It details the encoder's electrical parameters, communication circuit, and the necessary control, status, and data words for effective data transmission. Additionally, the document covers the configuration of the STM32F405 microcontroller's serial port and DMA for efficient communication at a baud rate of 2.5Mbps.

Uploaded by

bokic88
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Tamagawa protocol communication based on STM32F4

The drizzle Posted on 2023-03-19 16:57:10 Read 5.8k Collection 78 Likes 21


Category columns: MCU Learning Article Tags: stm32 Microcontroller Embedded Hardware

MCU Learning This column includes this content 0 Subscribe 2 articles S

1. Introduction

The previous project happened to use Yuheng's 17-bit absolute encoder . I took advantage of the weekend to sort out the development ideas
them with those in need for reference.

Back to encoders, we all know that in servo control, in order to obtain higher position accuracy and complete more precise absolute positioning
absolute photoelectric encoders are usually used as position feedback sensors. The two most common types are 17-bit and 23-bit. In order to enha
reliability of information transmission, encoder manufacturers generally output the encoding information in serial mode and control it through a spec
communication protocol. Here we mainly introduce the 17-bit absolute photoelectric encoder.

2. Encoder

2.1 Interface Definition

Note: In actual application, if there is no need to record multi-turn values, you do not need to connect the battery. However, if you need to retain mul
for a long time, such as the origin data of a multi-axis robot , you need to connect the battery.

2.2 Electrical parameters

Note: 1. The output signal complies with the RS485 interface, load current Imax: ±50mA;

2. Current consumption: ≤120mA (no load);

3. Insulation resistance is above 10MΩ (between 0V and shell, DC500V);

2.2 Communication circuit

After logging in, you can enjoy the following benefits:


×

Free Copy Code Interact with bloggers

Download massive Post updates/write


resources articles/join the community

Feeling
good?
Note: 1. IC1 is a linear differential driver, which is equivalent to MAX485 in function;
The drizzle focus on twenty one
2. IC2 is a linear differential receiver, which is equivalent to MAX485 in function. ADM485 is recommended.

3. Matching resistance: The encoder matching resistance R2 is 220Ω, and the user receiving end matching resistance R5 ≥ 120Ω is recommended

4. Pull-up/pull-down resistor: The encoder pull-up/pull-down resistors R1 and R3 are 4.7KΩ. It is recommended that the user receiving end pull-up
resistors R4 and R6 be no less than 1KΩ .

2.3. Agreement

According to the electrical parameters of the encoder and the communication circuit, we can determine the communication method. STM32 uses
module and the serial port baud rate is set to 2.5Mbps. The following is the timing diagram of the Tamagawa protocol:

Note: 1. CF: control domain, the command CF sent by the user is consistent with the CF returned by the encoder;

2. SF: Status field, the encoder returns error information and alarm information;

3. DF: data field, encoder returns data;

4. CRC: check field, CRC polynomial: G(X)= 𝑋8+1 , check range CF , SF , DF .

2.3.1 Control Word CF

Note: 1. According to the timing diagram, we can know that sending a request only requires sending CF. The specific CF value can be analyzed acc
the table above. The CF structure is mainly start bit (0) + sink code + Data ID code + ID parity + Delimiter (1). Here, please note that the start bit (0)
end bit (1) are the same as the start bit and end bit in the serial port non-checked transmission. Therefore, we only need to send sink code + Data I
parity.

2. According to the timing diagram, you can see that the sink code is fixed to 010. The remaining Data ID code + ID parity can be matched accordi
needs. The most commonly used ones are ID0=0x02 and ID3=0x1A. I will not explain the rest. I will just post the code.

× proc
3. Please note that the CF bit of the message returned by the encoder must be consistent with the sent CF, and it needs to be checked when
After logging in, you can enjoy the following benefits:
received message.
Free Copy Code Interact with bloggers
/* Macro definition declaration----------------------------------------------------------------*/
#define DataId0 0x02 /* Read single turn */ Download massive Post updates/write
#define DataId1 0x8A resources
/* Read the number of turns */ articles/join the community
#define DataId2 0x92 /* Read encoder number */
Feeling
#define DataId3 0x1A /* Read single turn + number of turns */
good?
#define DataId6 0x32 /* Write EEPROM*/
#define DataIdD 0xEA The/*drizzle focus on
Read EEPEOM*/ twenty one
#define DataId7 0xBA /* Reset error ERROR*/
#define DataId8 0xC2 /* Reset the number of turns */
#define DataIdC 0x62 /* Reset the number of turns and ERROR*/

2.3.2 Status word SF

Description: The status bit SF mainly feedbacks the encoder status, including whether the encoder is overheated, whether the battery power supply
whether the data analysis is correct, etc.

2.3.3 Data word DF

Depending on the CF sent, the DF returned by the encoder will also be different. The specific correspondence is as follows:

After logging in, you can enjoy the following benefits:


×

Free Copy Code Interact with bloggers

Download massive Post updates/write


resources
Note: 1. ABS0-ABS2: encoder single-turn value. Since the serial port of STM32 is in little-endian articles/join
mode, the actual encoder the community
single-turn position value
(ABS2<<16)|(ABS1<<8)|(ABS0<<0);
Feeling
2. ABM0-ABM2: encoder circle value, actual encoder circle value = (ABM2<<16)|(ABM1<<8)|(ABM0<<0). good?
The drizzle focus on twenty one
Description: ALMC: Encoder error. Different values ​have corresponding faults. You can check the corresponding table.

2.4.4、CRC

Note: Please note that we use the little-endian XOR calculation method. According to the polynomial G(X)=𝑋8+1, the corresponding binary number
Ploy value is 0x01, and LSB First=0x80. We need to process CF+SF+DF in byte form at LSB First. The final result is the CRC8 check result. See th
the specific implementation process.

/******************************************************************************
* Function: CRC8 check function
* Input parameters: *message: received data pointer
len: data length
* Return value: CRC8 checksum
* Description: Polynomial: G(X)=X^8+1 LSB first Poly: 0000 0001
LSB first: 1000 0000 =0X80
*******************************************************************************/
uint8_t APP_Math_CRC8_ChkValue ( uint8_t * message , uint8_t len ​)
{
uint8_t crc_val ;
uint8_t i ;
crc_val = 0 ;
while ( len --)
{ After logging in, you can enjoy the following benefits:
×
crc_val ^= * message ++;
for ( i = 0 ; i < 8 ; i ++) Free Copy Code Interact with bloggers
{
Download massive Post updates/write
if ( crc_val & 0x01 )
resources articles/join the community
crc_val = ( crc_val >> 1 ) ^ 0X80 ;
else
Feeling
crc_val >>= 1 ;
good?
}
The drizzle focus on twenty one
}
return crc_val ;
}

3. Single chip microcomputer

3.1 Microcontroller

At that time, in order to get started quickly and to prevent the serial port baud rate from being insufficient, I chose an STM32F405RGT6, which has a
main frequency and is more than enough. Now I think it was a bit of an overkill, so here I will mainly mention the serial port and DMA that will be use
STM32F405 has a 16-stream DMA, supports FIFOs mode and trigger mode, and has 4 USARTs/2 UARTs (with a rate of up to 10.5 Mbit/s and supp
ISO7816 interface).

3.2 Serial port + DMA

The serial port (UART) is a low-speed serial asynchronous communication, and the baud rateAfter
usually used
logging in, is
youless
canthan
enjoyorthe
equal × For
to 115200bps.
following benefits:
communication scenarios with small data volumes, it is generally unnecessary to use DMA, or the use of DMA does not fully play the role of DMA. W
Free Copy
with large quantities or high baud rates, DMA must be used to release CPU resources, because high baud Code Interact
rates may lead with bloggers
to excessive waste of CP
resources. Here, the electrical parameters of the encoder require a communication rate of ≥2.5MHz. We generally choose to set the serial port baud
Download massive Post updates/write
2.5MHz. At the same time, in order not to occupy too many CPU resources, DMA will be used for CF sending and encoder data reception. The spec
resources articles/join the community
settings are as follows:

Feeling
/****************************************************************************** good?
* Function: USART2+DMA initialization function The drizzle focus on twenty one
* Input parameters: None
* Return value: None
* Description: External call-Tamagawa encoder 1
*******************************************************************************/
void BSP_Encoder1_InitConfig ( void )
{
GPIO_InitTypeDef GPIO_InitStructure ;
USART_InitTypeDef USART_InitStructure ;
DMA_InitTypeDef DMA_InitStructure ;
NVIC_InitTypeDef NVIC_InitStructure ;

RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOA , ENABLE );


RCC_APB1PeriphClockCmd ( RCC_APB1Periph_USART2 , ENABLE );
GPIO_PinAFConfig ( GPIOA , GPIO_PinSource2 , GPIO_AF_USART2 ); /*UART2-TX*/
GPIO_PinAFConfig ( GPIOA , GPIO_PinSource3 , GPIO_AF_USART2 ); /*UART2-RX*/
GPIO_InitStructure .GPIO_OType = GPIO_OType_PP ;
GPIO_InitStructure .GPIO_PuPd = GPIO_PuPd_UP ;​
GPIO_InitStructure .GPIO_Mode = GPIO_Mode_AF ;​
GPIO_InitStructure . GPIO_Pin = GPIO_Pin_2 ; /*UART2-TX*/
GPIO_InitStructure .GPIO_Speed ​= GPIO_Speed_100MHz ;​
GPIO_Init ( GPIOA , & GPIO_InitStructure );
GPIO_InitStructure .GPIO_Pin = GPIO_Pin_3 ;​
GPIO_Init ( GPIOA , & GPIO_InitStructure ); /*UART2-RX*/

RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOC , ENABLE );


GPIO_InitStructure . GPIO_Pin = GPIO_Pin_15 ; /*DIR1-PC15*/
GPIO_InitStructure .GPIO_Speed ​= GPIO_Speed_100MHz ; ​
GPIO_InitStructure .GPIO_Mode = GPIO_Mode_OUT ;​
GPIO_InitStructure .GPIO_OType = GPIO_OType_PP ;
GPIO_InitStructure .GPIO_PuPd = GPIO_PuPd_UP ; ​
GPIO_Init ( GPIOC , & GPIO_InitStructure );
GPIO_ResetBits ( GPIOC , GPIO_Pin_15 ); /* Initialize and close communication */

RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_DMA1 , ENABLE ); /* Serial port DMA configuration */


NVIC_PriorityGroupConfig ( NVIC_PriorityGroup_2 ); /* Preemption priority 0-3 , response priority 0-3*/
NVIC_InitStructure . NVIC_IRQChannel = DMA1_Stream6_IRQn ;
NVIC_InitStructure . NVIC_IRQChannelPreemptionPriority = 1 ; /* Preemption priority 1*/
NVIC_InitStructure . NVIC_IRQChannelSubPriority = 0 ;
NVIC_InitStructure . NVIC_IRQChannelCmd = ENABLE ;
NVIC_Init (& NVIC_InitStructure ); /*DMA send interrupt */
DMA_DeInit ( DMA1_Stream6 ); /*DMA channel configuration */
while ( DMA_GetCmdStatus ( DMA1_Stream6 )!= DISABLE ){}
DMA_InitStructure .DMA_Channel = DMA_Channel_4 ;​
DMA_InitStructure . DMA_PeripheralBaseAddr = ( uint32_t )(& USART2 -> DR ); /* peripheral address */
DMA_InitStructure . DMA_Memory0BaseAddr = ( uint32_t )Ed_Tx_Buf1; /* memory address */
DMA_InitStructure . DMA_DIR = DMA_DIR_MemoryToPeripheral ; /*dma transmission direction */
DMA_InitStructure . DMA_BufferSize = USART_MAX_TX_LEN ; /* Set the length of the DMA buffer during
DMA_InitStructure . DMA_PeripheralInc = DMA_PeripheralInc_Disable ; /* Set DMA peripheral increment mode, o
DMA_InitStructure . DMA_MemoryInc = DMA_MemoryInc_Enable ; /* Set DMA memory increment mode */
DMA_InitStructure . DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte ; /* Peripheral data word length */
DMA_InitStructure . DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte ; /* Memory data word length */
DMA_InitStructure . DMA_Mode = DMA_Mode_Normal ; /* Set DMA transfer mode */
DMA_InitStructure . DMA_Priority = DMA_Priority_High ; /* Set DMA priority level */
DMA_InitStructure . DMA_FIFOMode = DMA_FIFOMode_Disable ; /* Specify if FIFO mode or direct mode w
specified stream : disable FIFO mode */
DMA_InitStructure . DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull ; /* Specifies the FIFO threshold level */
DMA_InitStructure . DMA_MemoryBurst = DMA_MemoryBurst_Single ; ×
/* Specified Burst transfer configuration
After logging in, you can enjoy the following benefits:
DMA_InitStructure . DMA_PeripheralBurst = DMA_PeripheralBurst_Single ; /* Specified Burst transfer configuration
DMA_Init ( DMA1_Stream6 , & DMA_InitStructure ); /* Configure
Free Copy Code DMA1 channel Interact*/with bloggers
DMA_ITConfig ( DMA1_Stream6 , DMA_IT_TC , ENABLE ); /* Enable interrupt */
Download massive Post updates/write

DMA_DeInit ( DMA1_Stream5 ); resources


/* Serial articles/join the*/community
port receive DMA configuration
while ( DMA_GetCmdStatus ( DMA1_Stream5 )!= DISABLE ){}
Feeling
DMA_InitStructure .DMA_Channel = DMA_Channel_4 ;​
good?
DMA_InitStructure . DMA_PeripheralBaseAddr = ( uint32_t )(& USART2 -> DR ); /* peripheral address */
The drizzle focus on twenty one
DMA_InitStructure . DMA_Memory0BaseAddr = ( uint32_t )Ed_Rx_Buf1; /* memory address */
DMA_InitStructure . DMA_DIR = DMA_DIR_PeripheralToMemory ; /*DMA transfer direction */
DMA_InitStructure . DMA_BufferSize = USART_MAX_RX_LEN ; /* Set the length of DMA buffer during tran
DMA_InitStructure . DMA_PeripheralInc = DMA_PeripheralInc_Disable ; /* Set DMA peripheral increment mode, o
DMA_InitStructure . DMA_MemoryInc = DMA_MemoryInc_Enable ; /* Set DMA memory increment mode */
DMA_InitStructure . DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte ; /* Peripheral data word length */
DMA_InitStructure . DMA_MemoryDataSize = DMA_MemoryDataSize_Byte ; /* Memory data word length */
DMA_InitStructure . DMA_Mode = DMA_Mode_Normal ; /* Set DMA transfer mode */
DMA_InitStructure . DMA_Priority = DMA_Priority_VeryHigh ; /* Set DMA priority level */
DMA_InitStructure . DMA_FIFOMode = DMA_FIFOMode_Disable ; /* Specify if FIFO mode or direct mode w
specified stream: Disable FIFO mode */
DMA_InitStructure . DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull ; /* Specifies the FIFO threshold level */
DMA_InitStructure . DMA_MemoryBurst = DMA_MemoryBurst_Single ; /* Specified Burst transfer configuration

DMA_InitStructure . DMA_PeripheralBurst = DMA_PeripheralBurst_Single ; /* Specified Burst transfer configuration


DMA_Init ( DMA1_Stream5 , & DMA_InitStructure ); /* Configure DMA1 channel */
DMA_Cmd ( DMA1_Stream5 , ENABLE ); /* Enable channel */
USART_InitStructure . USART_BaudRate = ENCODER1_BAUDRATE ; /* Configuration 8 1 0*/
USART_InitStructure . USART_WordLength = USART_WordLength_8b ;
USART_InitStructure . USART_StopBits = USART_StopBits_1 ;
USART_InitStructure . USART_Parity = USART_Parity_No ;
USART_InitStructure . USART_HardwareFlowControl = USART_HardwareFlowControl_None ;
USART_InitStructure . USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
USART_Init ( USART2 , & USART_InitStructure );

NVIC_InitStructure . NVIC_IRQChannel = USART2_IRQn ; /* Channel is set as serial port interrupt */


NVIC_InitStructure . NVIC_IRQChannelPreemptionPriority = 1 ; /* Interrupt preemption level */
NVIC_InitStructure . NVIC_IRQChannelSubPriority = 1 ; /* Interrupt response priority */
NVIC_InitStructure . NVIC_IRQChannelCmd = ENABLE ; /* Enable interrupt */
NVIC_Init (& NVIC_InitStructure ); /* Configure interrupt */

USART_DMACmd ( USART2 , USART_DMAReq_Tx , ENABLE ); /* Send using DMA */


USART_DMACmd ( USART2 , USART_DMAReq_Rx , ENABLE ); /* Receive using DMA */
USART_ITConfig ( USART2 , USART_IT_TC , DISABLE ); /* interrupt configuration */
USART_ITConfig ( USART2 , USART_IT_RXNE , DISABLE );
USART_ITConfig ( USART2 , USART_IT_TXE , DISABLE );
USART_ITConfig ( USART2 , USART_IT_IDLE , ENABLE ); /* Enable USART2 idle interrupt */
USART_Cmd ( USART2 , ENABLE ); /* Start the serial port */
}

Also attached are the 8 data streams and their corresponding channels controlled by DMA1 and DMA2:

After logging in, you can enjoy the following benefits:


×

Free Copy Code Interact with bloggers

Download massive Post updates/write


resources articles/join the community

Feeling
good?
The drizzle focus on twenty one
4. Code Implementation

At this point, the serial port DMA initialization is completed. The next step is to send and receive. The sending directly uses the DMA transfer comple
interrupt. The receiving requires a little processing. Because we receive data of indefinite length, we need to use the idle interrupt of the serial port t
the end of data reception. After the data is received, the CF and CRC need to be checked. Only after the check is passed can the DF data be consi
available. The specific code implementation is as follows:

/******************************************************************************
* Function: USART2 interrupt processing function
* Input parameters: None
* Return value: None
* Description: External call-Tamagawa encoder 1
*******************************************************************************/
void USART2_IRQHandler ( void ) /* Serial port 2 interrupt service routine */
{
if ( USART_GetITStatus ( USART2 , USART_IT_IDLE )!= RESET ) /* Idle interrupt triggered */
{
DMA_Cmd ( DMA1_Stream5 , DISABLE ); /* Temporarily close DMA data not yet processed */
ED_RX_LEN1 = USART_MAX_RX_LEN - DMA_GetCurrDataCounter ( DMA1_Stream5 ); /* Get the length of received dat
BSP_Encoder1_DMA_DataProcess ( Ed_Tx_Buf1 , Ed_Rx_Buf1 , ED_RX_LEN1 ); /* Message data processing */
DMA_ClearFlag ( DMA1_Stream5 , DMA_FLAG_TCIF5 ); /* Clear DMA flag */
DMA_SetCurrDataCounter ( DMA1_Stream5 , USART_MAX_RX_LEN ); /* Reassign the count value, which mus
than or equal to the maximum number of data frames that can be received */
DMA_Cmd ( DMA1_Stream5 , ENABLE ); /* Turn on DMA*/
USART_ReceiveData ( USART2 ); /* Clear the idle interrupt flag . The receiving function has the
clearing the flag */
Ed_Flag_Rx_Busy1 = 1 ; /* Status bit update -USART2 reception completed */
}
if ( USART_GetFlagStatus ( USART2 , USART_IT_TXE )== RESET ) /* Serial port transmission completed */
{
Ed_Flag_Tx_Busy1 = 0 ;
USART_ITConfig ( USART2 , USART_IT_TC , DISABLE ); After logging in, you can enjoy the following benefits:
×
}
} Free Copy Code Interact with bloggers

/******************************************************************************
Download massive Post updates/write
* Function: DMA1_Stream6 interrupt processing function
resources articles/join the community
* Input parameters: None
* Return value: None Feeling
* Description: External call-Tamagawa encoder 1 good?
*******************************************************************************/
The drizzle focus on twenty one
void DMA1_Stream6_IRQHandler ( void )
{
if ( DMA_GetFlagStatus ( DMA1_Stream6 , DMA_FLAG_TCIF6 )!= RESET ) /* Wait for DMA1_Stream6 transfer to
{
DMA_ClearFlag ( DMA1_Stream6 , DMA_FLAG_TCIF6 ); /* Clear DMA1_Stream6 transfer completion flag
DMA_Cmd ( DMA1_Stream6 , DISABLE ); /* Disable enable */
USART_ITConfig ( USART2 , USART_IT_TC , ENABLE ); /* Open the serial port sending completion inte
}
}
/******************************************************************************
* Function: DMA_USART2 send function
* Input parameters: *data: pointer to the data to be sent
size: data length
* Return value: None
* Description: External call-Tamagawa encoder 1
*******************************************************************************/
void BSP_Encoder1_DMA_SendBuffer ( u8 * data , u16 size )
{
Ed_Flag_Tx_Busy1 = 1 ; /* Status bit update -USART2 sending */
memcpy ( Ed_Tx_Buf1 , data , size ); /* Copy data to DMA transmit buffer */
while ( DMA_GetCmdStatus ( DMA1_Stream6 ) != DISABLE ); /* Make sure DMA can be set up */
DMA_SetCurrDataCounter ( DMA1_Stream6 , size ); /* Set data transfer length */
DMA_Cmd ( DMA1_Stream6 , ENABLE ); /* Open DMA data stream and start sending */
}
/******************************************************************************
* Function: DMA_USART2 data processing function
* Input parameters: *data: received data pointer
size: data length
* Return value: None
* Description: External call-Tamagawa encoder 2
*******************************************************************************/
void BSP_Encoder1_DMA_DataProcess ( u8 * txdata , u8 * rxdata , u16 size )
{
uint8_t crc = 0 ;
uint8_t buf [ USART_MAX_RX_LEN ]={ 0 };
for ( int i = 0 ; i < size ; i ++)
buf [ i ]=* rxdata ++;
if ( buf [ 0 ] == * txdata )
{
crc = APP_Math_CRC8_ChkValue ( buf , size - 1 );
if ( crc == buf [ size - 1 ])
{
Encoder1_CodeValue = buf [ 4 ]<< 16 | buf [ 3 ]<< 8 | buf [ 2 ];
}
else
{
Encoder_ReadFaultNum ++;
if ( Encoder_ReadFaultNum > ED_READ_FAULT_MAXNUM )
Encoder_ReadStatus = 1 ;
}
}
else
{
Encoder_ReadFaultNum ++;
if ( Encoder_ReadFaultNum > ED_READ_FAULT_MAXNUM )
Encoder_ReadStatus = 1 ;
}
After logging in, you can enjoy the following benefits:
×
}
Free Copy Code Interact with bloggers
5. Conclusion
Download massive Post updates/write
The whole project is not difficult. For me, the time spent is mainly on understanding DMA, CRCresources
check principle, and send/receive interrupt
articles/join the processi
community
a novice in microcontrollers, and I have to learn a lot of things from scratch. However, no matter how things change, they still remain essentially the
Feeling
you spend more time to understand the principles, many puzzled places will suddenly become clear. This is the end of the technical sharing. I hope
good?
helpful to you! !
The drizzle focus on twenty one

You might also like