I got the stm32f3discovery these days. The first thing I did was to test the hardware i2c, using stm32cube to generate the library, and the test objects were AD5934 and ADG715. After two days of debugging, it was perfectly tuned. I also encountered some problems in the middle.
1. I2C1 was used at the beginning, and the system would freeze during simulation.
Since I2C1 and swd interfaces overlap, the system crashes after calling the HAL_I2C_Init() function. The problem is solved after changing to I2C2.
2. Unable to access the device at the specified address
The entry address in the library function is not a 7-bit address, but an 8-bit address. My device address was 13, but I could not access the device. I changed it to 26 and it solved the problem.
3. Data of a single address can be read and written, but multi-byte reading and writing is not possible.
(1) For multi-byte writes, the library function
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
MemAddSize indicates the number of bits in the address, 0 indicates a 7-bit address, and 1 indicates a 10-bit address. I mistakenly thought this was the number of bytes to be written, so it caused an error when writing multiple bytes.
(2) For multi-byte read, there is a discrepancy between the read operation of AD5934 and the read operation of the library function, which results in a constant read error. In the library function, the read operation starts after the memory address is written, while in AD5934, after the block read is completed, a number bytes read is written before the read operation starts. Therefore, the library function needs to be modified and a new function needs to be added to suit the block read of AD5934.
The i2c of stm32f3 has three modes: Reload, AutoEnd and SoftEnd mode.
Each time i2c sends a byte, it will generate a TXIS flag. When the last byte is sent:
For the Reload mode, when the bytes are greater than 255 bytes, this mode must be used. In this mode, a tcr flag will be generated after the transmission is completed.
For AutoEnd mode, a STOP is automatically generated after the last byte is sent.
For SoftEnd mode, a tc flag is generated when the last byte is sent. This mode is used when a restart is required during the sending process.
For the read operation of AD5934, you can work in SoftEnd mode in advance, send block read and number bytes read, and then switch to AutoEnd mode for Restart. After reading the specified bytes, STOP is automatically generated. The operation process is as follows:
HAL_StatusTypeDef HAL_I2C_Mem_Read_AD5934_Block(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint32_t Sizetmp = 0;
/* Check the parameters http://tiyubisai.com/video_news/news_135585.html */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
if(hi2c->State == HAL_I2C_STATE_READY)
{
if((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
/*
//Send Slave Address and Memory Address
if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
// Process Unlocked
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
else
{
// Process Unlocked
__HAL_UNLOCK(hi2c);
return HAL_TIMEOUT;
}
}*/
I2C_TransferConfig(hi2c,DevAddress,MemAddSize+1, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
/* Wait until TXIS flag is set */
if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
return HAL_ERROR;
}
else
{
return HAL_TIMEOUT;
}
}
/* If Memory address size is 8Bit */
if(MemAddSize == I2C_MEMADD_SIZE_8BIT)
{
/* Send Memory Address */
hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);
}
/* If Mememory address size is 16Bit */
else
{
/* Send MSB of Memory Address */
hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_MSB(MemAddress);
/* Wait until TXIS flag is set */
if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
return HAL_ERROR;
}
else
{
return HAL_TIMEOUT;
}
}
/* Send LSB of Memory Address */
hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);
}
/* Wait until TXIS flag is set */
if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
return HAL_ERROR;
}
else
{
return HAL_TIMEOUT;
}
}
hi2c->Instance->TXDR = Size;
/* Wait until TC flag is set */
if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* Send Slave Address */
/* Set NBYTES to write and reload if size > 255 and generate RESTART */
/* Size > 255, need to set RELOAD bit */
if(Size > 255)
{
I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
Sizetmp = 255;
}
else
{
I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
Sizetmp = Size;
}
do
{
/* Wait until RXNE flag is set */
if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* Read data from RXDR */
(*pData++) = hi2c->Instance->RXDR;
/* Decrement the Size counter */
Sizetmp--;
Size--;
if((Sizetmp == 0)&&(Size!=0))
{
/* Wait until TCR flag is set */
if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
if(Size > 255)
{
I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
Sizetmp = 255;
}
else
{
I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
Sizetmp = Size;
}
}
}while(Size > 0);
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is reset */
if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
return HAL_ERROR;
}
else
{
return HAL_TIMEOUT;
}
}
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
/* Clear Configuration Register 2 */
__HAL_I2C_RESET_CR2(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
Previous article:STM32 drives temperature and humidity sensor HTU21D
Next article:STM32 I2C deadlock issue
Recommended ReadingLatest update time:2024-11-16 13:30
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
- Intelligently Connected World—Application of Internet of Vehicles and Future Development of Digitalization
- Motor drive circuit design 1
- Free Review - Topmicro Intelligent Display Module (5) Touch Screen
- How to deal with the acidic wastewater from acid salt spray testing of metal electronic products and devices?
- Summary: annysky2012's practical journey of motor development based on "STM32F746ZG+IHM07M1"
- Smart home management based on ESP8266 WIFI network control and Gizwits Cloud
- Engineer, if you don't develop from the perspective of engineering or product, how can you be worthy of the word "engineering"...
- Understand the past and present of NFC in one article!
- When power saving is required, how should the LCD screen's SEG pin, COM pin, VLVD1-3, and VLCDH related configurations be configured?
- [New version of Bluesun AB32VG1 RISC-V development board] - 1: From "New" to "0 errors, 0 warnings."