对比了GD32、N32之后,发现MM32的MindSDK操作I2C确实简单很多,跟stm32的hal库函数有的一拼。
继续使用PC6 PC7 这一组I2C,外面接了一个AT24C02 ,实验中写入20个数据,然后读出来,看是否一致。
void BOARD_I2C1_Init(void)
{
GPIO_Init_Type gpio_init;
/* GPIOC. */
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOC);
/* I2C1 */
RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_I2C1, true);
RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_I2C1);
/* PC6 - I2C1_SCL. */
gpio_init.Pins = GPIO_PIN_6;
gpio_init.PinMode = GPIO_PinMode_AF_OpenDrain;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &gpio_init);
GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);
/* PC7 - I2C1_SDA. */
gpio_init.Pins = GPIO_PIN_7;
gpio_init.PinMode = GPIO_PinMode_AF_OpenDrain;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &gpio_init);
GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);
/* Setup I2C initialization values. */
I2C_Master_Init_Type i2c_init;
i2c_init.ClockFreqHz = CLOCK_APB1_FREQ;
i2c_init.BaudRate = I2C_BaudRate_100K;
app_i2c_xfer.TargetAddr = APP_I2C_TARGET_ADDR;
/* Initialize I2C master. */
I2C_InitMaster(I2C1, &i2c_init);
/* The target device address needs to be configured before enabling. */
I2C_SetTargetAddr(I2C1, app_i2c_xfer.TargetAddr);
/* Enable I2C. */
I2C_Enable(I2C1, true);
NVIC_EnableIRQ(I2C1_IRQn);
}
注意读函数中还有两个回调函数,一个异常回调,一个发送完成的回调。
/* When I2C tx done, use app_i2c_tx_done_callback. */
void app_i2c_tx_done_callback(void *param)
{
printf("write data: ");
for (uint32_t i = 0u; i < sizeof(app_i2c_tx_buf); i++)
{
printf("0x%02X, ", app_i2c_tx_buf[i]);
}
printf("\r\n");
app_i2c_xfer_done = true;
}
/* When I2C tx abort, use app_i2c_tx_abort_callback. */
void app_i2c_tx_abort_callback(void *param)
{
printf("tx_abort\r\n");
app_i2c_xfer_done = true;
}
写函数:
/* Put data to device. */
void app_i2c_write(void)
{
/* Setup I2C tx. */
app_i2c_xfer.Direction = I2C_Direction_Tx; /* Setup the xfer direction. */
app_i2c_xfer.TxBuf = app_i2c_tx_buf; /* Setup tx buffer. */
app_i2c_xfer.TxLen = sizeof(app_i2c_tx_buf); /* Setup the number of data tx. */
app_i2c_xfer.DoneCallback = app_i2c_tx_done_callback; /* Transmission abort callback. */
app_i2c_xfer.AbortCallback = app_i2c_tx_abort_callback; /* Transmission done callback. */
app_i2c_xfer_done = false; /* Setup xfer done flag status. */
I2C_MasterXfer(I2C1, &app_i2c_xfer); /* I2C xfer. */
while (false == app_i2c_xfer_done) /* Wait to xfer done. */
{
}
}
同样两个回调函数,一个读取完成的回调,一个异常的回调。
/* When I2C received done, use app_i2c_rx_done_callback. */
void app_i2c_rx_done_callback(void *param)
{
printf("read data from device register address: 0x%02X\r\n", app_i2c_tx_buf[0u]);
printf("read data: ");
for (uint32_t i = 0u; i < sizeof(app_i2c_rx_buf); i++)
{
printf("0x%02X, ", app_i2c_rx_buf[i]);
}
printf("\r\n");
app_i2c_xfer_done = true;
}
/* When I2C received abort, use app_i2c_rx_abort_callback. */
void app_i2c_rx_abort_callback(void *param)
{
printf("rx_abort\r\n");
app_i2c_xfer_done = true;
}
/* Get data from device. */
void app_i2c_read(void)
{
app_i2c_xfer.Direction = I2C_Direction_Rx; /* Setup the xfer direction. */
app_i2c_xfer.TxBuf = app_i2c_tx_buf; /* Setup tx buffer. */
app_i2c_xfer.RxBuf = app_i2c_rx_buf; /* Setup rx buffer. */
app_i2c_xfer.TxLen = 1; /* One data needs to be write to the target address before reading operation. */
app_i2c_xfer.RxLen = sizeof(app_i2c_rx_buf); /* Setup the number of receive data. */
app_i2c_xfer.DoneCallback = app_i2c_rx_done_callback; /* Transmission abort callback. */
app_i2c_xfer.AbortCallback = app_i2c_rx_abort_callback; /* Transmission done callback. */
app_i2c_xfer_done = false; /* Setup xfer done flag status. */
I2C_MasterXfer(I2C1, &app_i2c_xfer); /* I2C xfer. */
while (false == app_i2c_xfer_done) /* Waiting for xfer done. */
{
}
}
#include
#include "key.h"
#include "systick.h"
#include "i2c.h"
#include "hal_i2c.h"
#include "clock_init.h"
#define APP_I2C_TARGET_ADDR 0x50u /* I2C target device address. */
static I2C_MasterXfer_Type app_i2c_xfer;
static uint8_t app_i2c_rx_buf[20]; /* I2C rx buffer. */
static uint8_t app_i2c_tx_buf[20]; /* I2C tx buffer. */
volatile static bool app_i2c_xfer_done; /* Xfer done flag. */
void BOARD_I2C1_Init(void)
{
GPIO_Init_Type gpio_init;
/* GPIOC. */
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOC);
/* I2C1 */
RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_I2C1, true);
RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_I2C1);
/* PC6 - I2C1_SCL. */
gpio_init.Pins = GPIO_PIN_6;
gpio_init.PinMode = GPIO_PinMode_AF_OpenDrain;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &gpio_init);
GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);
/* PC7 - I2C1_SDA. */
gpio_init.Pins = GPIO_PIN_7;
gpio_init.PinMode = GPIO_PinMode_AF_OpenDrain;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &gpio_init);
GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);
/* Setup I2C initialization values. */
I2C_Master_Init_Type i2c_init;
i2c_init.ClockFreqHz = CLOCK_APB1_FREQ;
i2c_init.BaudRate = I2C_BaudRate_100K;
app_i2c_xfer.TargetAddr = APP_I2C_TARGET_ADDR;
/* Initialize I2C master. */
I2C_InitMaster(I2C1, &i2c_init);
/* The target device address needs to be configured before enabling. */
I2C_SetTargetAddr(I2C1, app_i2c_xfer.TargetAddr);
/* Enable I2C. */
I2C_Enable(I2C1, true);
NVIC_EnableIRQ(I2C1_IRQn);
}
/* When I2C tx done, use app_i2c_tx_done_callback. */
void app_i2c_tx_done_callback(void *param)
{
printf("write data: ");
for (uint32_t i = 0u; i < sizeof(app_i2c_tx_buf); i++)
{
printf("0x%02X, ", app_i2c_tx_buf[i]);
}
printf("\r\n");
app_i2c_xfer_done = true;
}
/* When I2C tx abort, use app_i2c_tx_abort_callback. */
void app_i2c_tx_abort_callback(void *param)
{
printf("tx_abort\r\n");
app_i2c_xfer_done = true;
}
/* When I2C received done, use app_i2c_rx_done_callback. */
void app_i2c_rx_done_callback(void *param)
{
printf("read data from device register address: 0x%02X\r\n", app_i2c_tx_buf[0u]);
printf("read data: ");
for (uint32_t i = 0u; i < sizeof(app_i2c_rx_buf); i++)
{
printf("0x%02X, ", app_i2c_rx_buf[i]);
}
printf("\r\n");
app_i2c_xfer_done = true;
}
/* When I2C received abort, use app_i2c_rx_abort_callback. */
void app_i2c_rx_abort_callback(void *param)
{
printf("rx_abort\r\n");
app_i2c_xfer_done = true;
}
/* Put data to device. */
void app_i2c_write(void)
{
/* Setup I2C tx. */
app_i2c_xfer.Direction = I2C_Direction_Tx; /* Setup the xfer direction. */
app_i2c_xfer.TxBuf = app_i2c_tx_buf; /* Setup tx buffer. */
app_i2c_xfer.TxLen = sizeof(app_i2c_tx_buf); /* Setup the number of data tx. */
app_i2c_xfer.DoneCallback = app_i2c_tx_done_callback; /* Transmission abort callback. */
app_i2c_xfer.AbortCallback = app_i2c_tx_abort_callback; /* Transmission done callback. */
app_i2c_xfer_done = false; /* Setup xfer done flag status. */
I2C_MasterXfer(I2C1, &app_i2c_xfer); /* I2C xfer. */
while (false == app_i2c_xfer_done) /* Wait to xfer done. */
{
}
}
/* Get data from device. */
void app_i2c_read(void)
{
app_i2c_xfer.Direction = I2C_Direction_Rx; /* Setup the xfer direction. */
app_i2c_xfer.TxBuf = app_i2c_tx_buf; /* Setup tx buffer. */
app_i2c_xfer.RxBuf = app_i2c_rx_buf; /* Setup rx buffer. */
app_i2c_xfer.TxLen = 1; /* One data needs to be write to the target address before reading operation. */
app_i2c_xfer.RxLen = sizeof(app_i2c_rx_buf); /* Setup the number of receive data. */
app_i2c_xfer.DoneCallback = app_i2c_rx_done_callback; /* Transmission abort callback. */
app_i2c_xfer.AbortCallback = app_i2c_rx_abort_callback; /* Transmission done callback. */
app_i2c_xfer_done = false; /* Setup xfer done flag status. */
I2C_MasterXfer(I2C1, &app_i2c_xfer); /* I2C xfer. */
while (false == app_i2c_xfer_done) /* Waiting for xfer done. */
{
}
}
void I2C_InterruptTest(void)
{
BOARD_I2C1_Init();
for (uint32_t i = 0u; i < 20; i++) /* Setup the data to be transmitted. */
{
app_i2c_tx_buf[i] = i;
}
app_i2c_write(); /* I2C write data to target device. */
BOARD_Delay1Ms(10u); /* Wait for i2c xfer finish. */
app_i2c_read(); /* I2C read data from target device. */
BOARD_Delay1Ms(10u); /* Wait for i2c xfer finish. */
while(1)
{
}
}
/* I2C interrupt handler */
void I2C1_IRQHandler(void)
{
uint32_t flag = I2C_GetInterruptStatus(I2C1); /* Get current interrupt status. */
I2C_ClearInterruptStatus(I2C1, flag); /* Clear the interrupt flag that can be cleared by software. */
I2C_MasterXferHandler(I2C1, &app_i2c_xfer, flag); /* I2C master xfer interrupt handler. */
}
代码下载