1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#include "main.h"
#include "py32f030xx_ll_Start_Kit.h"
#define I2C_ADDRESS 0xA0 /* 从机地址 */
#define I2C_SPEEDCLOCK 100000 /* 100K 标准速率 */
#define I2C_STATE_READY 0
#define I2C_STATE_BUSY_TX 1
#define I2C_STATE_BUSY_RX 2
uint8_t aTxBuffer[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uint8_t aRxBuffer[15] = {0};
uint8_t *pBuffPtr = NULL;
__IO uint16_t XferCount = 0;
__IO uint32_t Devaddress = 0;
__IO uint32_t State = I2C_STATE_READY;
static void APP_SystemClockConfig(void);
static void APP_ConfigI2cMaster(void);
static void APP_MasterTransmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void APP_MasterReceive(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void APP_CheckEndOfTransfer(void);
static uint8_t APP_Buffercmp8(uint8_t* pBuffer1, uint8_t* pBuffer2, uint8_t BufferLength);
static void APP_LedBlinking(void);
int main(void)
{
APP_SystemClockConfig();
BSP_LED_Init(LED_GREEN);
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
APP_ConfigI2cMaster();
while (BSP_PB_GetState(BUTTON_KEY) == 1); /* 等待按键按下 */
APP_MasterTransmit(I2C_ADDRESS, (uint8_t *)aTxBuffer, sizeof(aTxBuffer));
while (State != I2C_STATE_READY); /* 等发送完 */
APP_MasterReceive(I2C_ADDRESS, (uint8_t *)aRxBuffer, sizeof(aRxBuffer));
while (State != I2C_STATE_READY); /* 等接收完 */
APP_CheckEndOfTransfer(); /* 比对结果 */
while (1) {}
}
/**
* @brief I2C 主机 GPIO + 外设配置
*/
static void APP_ConfigI2cMaster(void)
{
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
/* SCL=PA9, SDA=PA10:复用、开漏、上拉、AF6 */
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; /* I2C 必须开漏 */
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 复位 I2C 外设 */
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
LL_I2C_InitTypeDef I2C_InitStruct = {0};
I2C_InitStruct.ClockSpeed = I2C_SPEEDCLOCK;
I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_16_9;
I2C_InitStruct.OwnAddress1 = I2C_ADDRESS;
I2C_InitStruct.TypeAcknowledge = LL_I2C_NACK;
LL_I2C_Init(I2C1, &I2C_InitStruct);
}
/**
* @brief LL 主机发送:起始→地址→数据→停止,全程轮询标志
*/
static void APP_MasterTransmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
pBuffPtr = pData; XferCount = Size; Devaddress = DevAddress;
State = I2C_STATE_BUSY_TX;
LL_I2C_GenerateStartCondition(I2C1);
while (LL_I2C_IsActiveFlag_SB(I2C1) != 1); /* 等起始条件发送完 */
LL_I2C_TransmitData8(I2C1, (Devaddress & (uint8_t)(~0x01))); /* 发写地址(末位0) */
while (LL_I2C_IsActiveFlag_ADDR(I2C1) != 1);
LL_I2C_ClearFlag_ADDR(I2C1); /* 清地址标志 */
while (XferCount > 0)
{
while (LL_I2C_IsActiveFlag_TXE(I2C1) != 1); /* 等发送寄存器空 */
LL_I2C_TransmitData8(I2C1, *pBuffPtr); /* 发一字节 */
pBuffPtr++; XferCount--;
while (LL_I2C_IsActiveFlag_BTF(I2C1) != 1); /* 等字节发完(BTF) */
}
LL_I2C_GenerateStopCondition(I2C1); /* 发停止条件 */
State = I2C_STATE_READY;
}
/**
* @brief LL 主机接收:起始→地址(读)→接收 N 字节→停止
*/
static void APP_MasterReceive(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
pBuffPtr = pData; XferCount = Size; Devaddress = DevAddress;
State = I2C_STATE_BUSY_RX;
LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK); /* 先允许 ACK */
LL_I2C_GenerateStartCondition(I2C1);
while (LL_I2C_IsActiveFlag_SB(I2C1) != 1);
LL_I2C_TransmitData8(I2C1, (Devaddress | 0x1)); /* 发读地址(末位1) */
while (LL_I2C_IsActiveFlag_ADDR(I2C1) != 1);
LL_I2C_ClearFlag_ADDR(I2C1);
while (XferCount > 0)
{
while (LL_I2C_IsActiveFlag_RXNE(I2C1) != 1); /* 等收到一字节 */
*pBuffPtr = LL_I2C_ReceiveData8(I2C1); /* 读一字节 */
pBuffPtr++; XferCount--;
}
State = I2C_STATE_READY;
}
/* APP_CheckEndOfTransfer / APP_Buffercmp8 / APP_LedBlinking / 时钟与错误处理
与前述示例同构,略 */
|