So the company selected personnel from each different project group to form a team. I was responsible for the software part, responsible for writing drivers and debugging circuit boards. It was a
brand new project and had certain challenges. After analysis, it was decided to use the STM32 bus mode (FSMC) to drive PCL6045B. Compare the four bus operation timings of FSMC and the operation timing of PCL6045B. It was believed that the PCCARD mode of STM32 should be used. I searched for some literature in the database and started working.
Two hardware engineers designed the hardware circuit board according to my requirements.
The following steps are divided into the following steps:
First, establish communication. Let ARM establish communication with PCL6045B.
This step mainly configures the FSMC of STM32 to PCCARD mode. The configuration process is configured according to the official manual. First, initialize the system and configure the clock of STM32 (not repeated here). Then initialize the port. It should be noted here that all ports related to FSMC should be set as special function ports AF. As follows:
void PCCARD_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD RCC_APB2Periph_GPIOE RCC_APB2Periph_GPIOF RCC_APB2Periph_GPIOG,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO _Pin_1 GPIO_Pin_2 GPIO_Pin_3 GPIO_Pin_4 GPIO_Pin_12 GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_AF_PP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 GPIO_Pin_8 GPIO_Pin_9 GPIO_Pin_10 GPIO_Pin_11 GPIO_Pin_12 GPIO_Pin_13 GPIO_Pin_14 GPIO_Pin_15;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitS structure.GPIO_Pin = GPIO_Pin_14 GPIO_Pin_15 GPIO_Pin_10 GPIO_Pin_9 GPIO_Pin_8 GPIO_Pin_1 GPIO_Pin_0;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 GPIO_Pin_5; //NOE, NWE pins
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //cs
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
The next step is to configure the FSMC PC card mode timing. As follows:
void PCCARD_Init(void)
{
FSMC_PCCARDInitTypeDef FSMC_PCCARDInitStructure;
FSMC_NAND_PCCARDTimingInitTypeDef p;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);////
p.FSMC_SetupTime = 0x02;
p.FSMC_WaitSetupTime = 0x04 ;
p.FSMC_HoldSetupTime = 0x02;
p.FSMC_HiZSetupTime = 0x03;
FSMC_PCCARDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; //Enable wait for
FSMC_PCCARDInitStructure.FSMC_TCLRSetupTime = 0x10;
FSMC_PCCARDInitStructure.FSMC_TARSetupTime = 0x10;
FSMC_PCCARDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_PCCARDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
FSMC_PCCARDInitStructure.FSMC_IOSpaceTimingStruct = &p;
FSMC_PCCARDInit(&FSMC_PCCARDInitStructure);
FSMC_PCCARDCmd(ENABLE);
}
At this point, the configuration is complete. The main function is called.
Then the main function successfully controls one of the ports of PCL6045, so communication is established.
Next, you can try to control the number of pulses specified by the PCL6045 parameters.
So, I wrote the following small test program according to the manual:
p645_wreg(AXS_AU, WPRMD, 0x00000041); //Fixed-length motion mode
p645_wreg(AXS_AU, WRMV, 4012000000);
p645_wreg(AXS_AU, WRFL, 500L);
p645_wreg(AXS_AU, WRFH, 20000L);
p645_wreg(AXS_AU, WRUR, 200L);
p645_wreg(AXS_AU, WRDR, 400L);
p645_wreg(AXS_AU, WRMG, 29L);
p645_wcom(AXS_AU,STAUD);
Run, pulses are generated successfully!
The normal process is very simple, but in actual operation, especially when you are exploring for the first time, you will encounter many tricky problems.
For example, the IF0 IF1 of the PCL6045 hardware part should be connected in 8086 mode.
At the beginning, our hardware circuit was linked as shown below:
It seemed that there was no problem, so we continued to adjust it and found a very frustrating problem. At that time, the problem was described as follows:
#define AXS_AX ((volatile unsigned int ) 0x90000000)
#define AXS_AY ((volatile unsigned int ) 0x90000004)
#define AXS_AZ ((volatile unsigned int ) 0x9000008)
#define AXS_AU ((volatile unsigned int ) 0x900000c)
Among them, AXS_AX, AXS_AY, AXS_AZ, and AXS_AU represent the starting addresses of the X, Y, Z, and U axis registers respectively
. Several addresses can be operated and can control the movement of each axis motor.
STM32 communicates with DSP through FSMC and transmits data through 16 bits.
#define outpw( address,data) (*(unsigned short *)(address)=(data));
unsigned int inpw(unsigned int address) //Read and write a certain section of memory
{
unsigned short data;
data=*(unsigned short*)address;
return data;
}
The register write function is as follows:
void p645_wreg(unsigned int base_addr,unsigned int rwcom,unsigned int data) //Write data to a register of a certain axis
{
union udata{
unsigned int ldata;
unsigned short idata[2];
}udt;
udt.ldata = data;
outpw (base_addr 2, udt. idata[0]);
// Delay_Us(1); //Even if a delay is added, it will not workoutpw
(base_addr 3, udt. idata[1]);
// Delay_Us(1); //Even if a delay is added, it will not workoutpw
(base_addr, rwcom);
}
//The read register function is as follows:
unsigned long p645_rreg (unsigned int base_addr,unsigned int rrcom) //Read register
{
union udata{
unsigned int ldata;
unsigned short idata[2];
}udt;
outpw(base_addr, rrcom);
// Delay_Us(1);
udt.idata[0] = inpw (base_addr 2);
// Delay_Us(1);
udt.idata[1] = inpw (base_addr 3);
return(udt. ldata);
}
When setting the decoding multiplier, I found that no matter which number I wrote (00, 01, 10), the data read out by the encoder could not be changed, that is, it was always the default 1x decoding, that is, the two bits of the relevant register were 00. [page]
So I guessed that the data I wrote could not change the upper 16 bits, but could only change the lower 16 bits.
So I did the following test work:
Now I found that when writing data to the DSP axis buffer, the upper 16 bits could not be written in, but the lower 16 bits could be written in. For example, I wrote p645_wreg(AXS_AX,WRENV1,0x00000001); //Control pulse type.
p645_wreg(AXS_AX,WRENV1,0x00000002);
p645_wreg(AXS_AX,WRENV1,0x00000003);
You can see different types of pulses output respectively. Prove that the low-bit operation is effective!
But when I write a fixed-length test, the code is as follows
p645_wreg(AXS_AZ, WPRMD, 0x00000041); //Fixed-length motion mode
p645_wreg(AXS_AZ, WRMV, 65536L); //Writing numbers below 65535 here can accurately control the number of steps the motor takes. If it exceeds 65535, the motor will continue to move without control. Abnormal situation!
p645_wreg(AXS_AZ, WRFL, 500L);
p645_wreg(AXS_AZ, WRFH, 2000L);
p645_wreg(AXS_AZ, WRUR, 200L);
p645_wreg(AXS_AZ, WRDR, 400L);
p645_wreg(AXS_AZ, WRMG, 5L);
p645_wcom(AXS_AZ,STAUD);
In addition, when the value exceeds 65535, the data in COUNT1 I read is also irregular. When it does not exceed 65535, it is completely normal!
1. When writing 65535, the data read out during the motor operation is as follows:
Counter1 Counter2
Command encoder (here is the default 1 times, which corresponds to our encoder)
0000019662 0000000958
0000039790 0000001937
0000059918 0000002917
0000065535 0000003191
0000065535 0000003191
000065535 0000003191
0000065535 0000003191
2. When writing 65536 or above, the data read out during the motor operation process is as follows:
Counter1 Counter2
instruction Encoder (here is the default 1 times, which corresponds to our encoder)
0000019662 0000000958
0000039790 0000001937
0000059917 0000002917 0000014509
0000003898 0000034637 0000004878
0000054764
0000005857
0000009356 0000006837
0000029484 0000007818
0000049611 0000008797 0000004203
0000009776 0000044458 0000011737 0000064586
0000012718 0000019177 0 000013697 0000039305
0000014676 0000059433
0000015657
0000034152
0000017617
0000054279
0000018596
0000008871 0000019577
0000028999 0000020557
0000049126 0000021536
0000003718 0000022516 0000023846 0000023497
0000043973 0000024476 0000018692
0 000026436 0000058948 0000028397
0000013539
0000029375
0000033667
0000030355
0000053794
The data above 0000031335 does not exceed 65535.
Based on the above phenomenon, I made a program to test reading and writing, and found that when the data I wrote to the buffer exceeded 0x00ffffff, the read data was incorrect. Only the lower 24 bits could be read, and the upper 8 bits were all 0.
The write register function was modified as follows:
void p645_wreg(unsigned int base_addr,unsigned int rwcom,unsigned int data)
{
union udata{
unsigned int ldata;
unsigned short idata[2];
}udt;
udt.ldata = data;
outpw (base_addr 2, udt. idata[0]);
outpw (base_addr 3, udt. idata[1]);
//outpw (base_addr, rwcom);
}
The test code is as follows:
p645_wreg(AXS_AZ,WRENV2,0xffffffff);
data3=inpw (AXS_AZ 2);
data4=inpw (AXS_AZ 3);
the data read out can only be data3=65535; data4=255, that is, the highest 8 bits are lost!
When the data written by p645_wreg(,,); is below 0x00ffffff, the data read out by data3; data4 is correct. That is, what is written is what is read out. This is a detailed description of the problem I am facing now.
After a lot of trouble and a lot of measurements, I found that the order of the high and low bytes in the upper 16 bits was swapped. I was very depressed. So I communicated with the Japanese engineers, and they asked me to connect A1~A4 of STM32 with A1~A4 of PCL6045 (originally A0~A3 of STM32 and A1~A4 of PCL6045).
So the address was also changed to
#define AXS_AX 0x90000000
#define AXS_AY 0x90000008
#define AXS_AZ 0x90000010
#define AXS_AU 0x90000018
. I felt very strange. The difference in the address line should only be the address, how could it cause the high and low 8 bits of the upper two bytes to be swapped? The Japanese said that their chip internal design is like that, but I didn't see any explanation in the Japanese manual.
After further research, my PCL6045 can be controlled freely and all functions have been successfully verified.
The above is my experience in developing PCL6045B. Please indicate the source when reprinting. If you have any questions, please feel free to communicate.
Previous article:Tic and toc in STM32, use SysTick to count the execution time of code segments
Next article:STM32 learning experience
Recommended ReadingLatest update time:2024-11-16 13:29
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Derivation of the Smith Chart Equation
- [RVB2601 Creative Application Development] Handheld Game Console (Bonus-01) Python Program to Convert Files into Arrays
- Blue line appears in vhdl bidirectional bus buffer simulation
- Different backlight structure types in monochrome LCD screens
- 3rd Anniversary
- Instrumentation Amplifiers: CMRR, You Stole My Precision
- Refuse to get something for free. The author of the open source project deleted the library and ran away. Thousands of applications output garbled characters endlessly.
- DSP Flash API Steps
- The physical meaning of FFT results
- MSP430 - Timer_A timer interrupt program