昆山那个网站推广好,wordpress html,商城网站的开发怎么做的,十大app黄皮软件排行榜存储器模式#xff1a;在HAL库中#xff0c;I2C有专门对存储器外设设置的库函数 I2C#xff08;一#xff09;#xff1a;存储器模式的使用 1、I2C轮询式写读AT24C02一页数据2、I2C轮询式写读AT24C02多页数据3、I2C中断式写读AT24C02一页数据4、I2C使用DMA式写读AT24C02一…存储器模式在HAL库中I2C有专门对存储器外设设置的库函数 I2C一存储器模式的使用 1、I2C轮询式写读AT24C02一页数据2、I2C轮询式写读AT24C02多页数据3、I2C中断式写读AT24C02一页数据4、I2C使用DMA式写读AT24C02一页数据 1、I2C轮询式写读AT24C02一页数据
AT24C02 是一款常见的 2 Kbit256 字节I²C 接口的 EEPROM电可擦可编程只读存储器。它的存储结构如下
存储容量AT24C02 的总存储容量为 2 Kbit即 256 字节
页Page大小AT24C02 的每一页Page的大小为 8 字节。
写数据时最多一次型写入1页8字节超过即会从页的开头覆盖
读数据时没有限定字节数。①I2C.c文件的代码如下
#include I2C.h/*** briefI2C1初始化函数*/
I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE(); //使能I2C1的时钟hi2c1.Instance I2C1; //选择I2C1hi2c1.Init.ClockSpeed 100000; //通信速率100K标志模式HAL_I2C_Init(hi2c1);
}/*** briefHAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init; //IO口初始化结构体if(hi2c-Instance I2C1){/* I2C1引脚的初始化PB6 SCL,PB7 SDA*/__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB的时钟GPIO_Init.Mode GPIO_MODE_AF_OD; //复用开漏输出GPIO_Init.Pin GPIO_PIN_6 | GPIO_PIN_7; //PB6和PB7GPIO_Init.Speed GPIO_SPEED_FREQ_LOW; //最大输出速度低HAL_GPIO_Init(GPIOB, GPIO_Init);}else if(hi2c-Instance I2C2){}
}②I2C.h文件的代码如下
#ifndef __I2C_H
#define __I2C_H#include stm32f1xx_hal.h
extern I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void);#endif③main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include UART.h
#include I2C.h#define AT24C02_Address 0xA0uint8_t WriteData[8] {1,2,3,4,5,6,7,88};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();printf(启动判断\r\n);/* 存储器模式对AT24C02第一页进行写 */HAL_I2C_Mem_Write(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8, 1000);//I2C1从机地址从机内部地址每次传输的数据大小需要写入的数据缓冲区需要写入多少个数据/* 查询从机知否准备就绪 */if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK)//I2C1从机地址查询次数超时时间{/* 存储器模式向从机第一页读取数据 */HAL_I2C_Mem_Read(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8, 1000);}else{printf(芯片忙碌\r\n);}/* 将读取到的数据通过串口打印 */for(uint8_t i 0; i8; i){printf(ReadData[%d] %d\r\n,i,ReadData[i]);}while(1){}
}2、I2C轮询式写读AT24C02多页数据
①I2C.c文件的代码如下
#include I2C.h/*** briefI2C1初始化函数*/
I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE(); //使能I2C1的时钟hi2c1.Instance I2C1; //选择I2C1hi2c1.Init.ClockSpeed 100000; //通信速率100K标志模式HAL_I2C_Init(hi2c1);
}/*** briefHAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init; //IO口初始化结构体if(hi2c-Instance I2C1){/* I2C1引脚的初始化PB6 SCL,PB7 SDA*/__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB的时钟GPIO_Init.Mode GPIO_MODE_AF_OD; //复用开漏输出GPIO_Init.Pin GPIO_PIN_6 | GPIO_PIN_7; //PB6和PB7GPIO_Init.Speed GPIO_SPEED_FREQ_LOW; //最大输出速度低HAL_GPIO_Init(GPIOB, GPIO_Init);}else if(hi2c-Instance I2C2){}
}②I2C.h文件的代码如下
#ifndef __I2C_H
#define __I2C_H#include stm32f1xx_hal.h
extern I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void);#endif③main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include UART.h
#include I2C.h#define AT24C02_Address 0xA0uint8_t WriteData[16] {1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1};
uint8_t ReadData[16];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();printf(启动判断\r\n);uint8_t i 0;for(i 0; i2; i){/* 存储器模式对AT24C02的页进行写 */HAL_I2C_Mem_Write(hi2c1, AT24C02_Address, i*8, I2C_MEMADD_SIZE_8BIT, WriteData[i*8], 8, 1000);//while(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) ! HAL_OK);HAL_Delay(10);}/* 查询从机知否准备就绪 */if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK)//I2C1从机地址查询次数超时时间{/* 存储器模式向从机读取数据 */HAL_I2C_Mem_Read(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 16, 1000);}else{printf(芯片忙碌\r\n);}/* 将读取到的数据通过串口打印 */for(i 0; i16; i){printf(ReadData[%d] %d\r\n,i,ReadData[i]);}while(1){}
}3、I2C中断式写读AT24C02一页数据
实验要求连接PB0的按键按下后单片机主机向从机AT24C02写入数据。连接PB1的按键按下后主机向从机AT24C02读取数据然后通过串口打印。
①Key.c文件的代码如下
#include Key.h/*** 按键引脚的初始化,使用PB0和PB1*/
void Key_GPIO_Init(void)
{/* 1、开启GPIOB的时钟 */__HAL_RCC_GPIOB_CLK_ENABLE();/* 2、对GPIOB0进行配置 */GPIO_InitTypeDef GPIO_Init;GPIO_Init.Pin GPIO_PIN_0|GPIO_PIN_1; //选择PB0GPIO_Init.Mode GPIO_MODE_INPUT; //选择输入模式GPIO_Init.Pull GPIO_PULLUP; //选择上拉模式HAL_GPIO_Init(GPIOB, GPIO_Init);
}/*** brief判断是按键1按下还是按键2按下*/
uint8_t Key_Scan(void)
{uint8_t Key_Num 0;if(PB0_IN GPIO_PIN_RESET) //PB0按下{HAL_Delay(10); //延时消抖while(PB0_IN GPIO_PIN_RESET);Key_Num 1;}if(PB1_IN GPIO_PIN_RESET) //PB1按下{HAL_Delay(10); //延时消抖while(PB1_IN GPIO_PIN_RESET);Key_Num 2;} return Key_Num;
}①I2C.c文件的代码如下
#include I2C.h/*** briefI2C1初始化函数*/
I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE(); //使能I2C1的时钟hi2c1.Instance I2C1; //选择I2C1hi2c1.Init.ClockSpeed 100000; //通信速率100K标志模式HAL_I2C_Init(hi2c1);/* 配置I2C1的NVIC */HAL_NVIC_SetPriority(I2C1_EV_IRQn,3,0);HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
}/*** briefHAL_I2C_Init()调用此函数*/
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init; //IO口初始化结构体if(hi2c-Instance I2C1){/* I2C1引脚的初始化PB6 SCL,PB7 SDA*/__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB的时钟GPIO_Init.Mode GPIO_MODE_AF_OD; //复用开漏输出GPIO_Init.Pin GPIO_PIN_6 | GPIO_PIN_7; //PB6和PB7GPIO_Init.Speed GPIO_SPEED_FREQ_LOW; //最大输出速度低HAL_GPIO_Init(GPIOB, GPIO_Init);}else if(hi2c-Instance I2C2){}
}②I2C.h文件的代码如下
#ifndef __I2C_H
#define __I2C_H#include stm32f1xx_hal.h
extern I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void);#endif③main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include UART.h
#include I2C.h
#include Key.h#define AT24C02_Address 0xA0uint8_t WriteData[8] {1,2,3,4,5,6,7,8};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();Key_GPIO_Init();printf(启动判断\r\n);while(1){switch(Key_Scan()){case 1://按键PB0按下if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK){/* 存储器模式对AT24C02的页进行写且开启写入完成中断 */HAL_I2C_Mem_Write_IT(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8);}break;case 2://按键PB1按下if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK){/* 存储器模式对AT24C02的页进行读且开启读取完成中断 */HAL_I2C_Mem_Read_IT(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8);}break; }}
}④stm32f1xx_it.c文件的代码如下
#include stm32f1xx_hal.h
#include stm32f1xx_it.h
#include I2C.h
#include UART.h/*** I2C1中断服务函数 */
void I2C1_EV_IRQHandler(void)
{HAL_I2C_EV_IRQHandler(hi2c1);//中断服务总函数
}/******************* 下面的中断的回调函数 ***************************/
/*** 存储器模式I2C1主机发送完成中断回调函数*/
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c-Instance I2C1){printf(发送完成了\r\n);}else if(hi2c-Instance I2C2){}
}/*** 存储器模式I2C1主机读取完成中断回调函数*/
extern uint8_t ReadData[8];
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c-Instance I2C1){printf(读取完成了\r\n);for(uint8_t i 0; i8; i){printf(ReadData[%d] %d\r\n,i,ReadData[i]);}}else if(hi2c-Instance I2C2){}
}4、I2C使用DMA式写读AT24C02一页数据
实验要求连接PB0的按键按下后单片机主机向从机AT24C02写入数据。连接PB1的按键按下后主机向从机AT24C02读取数据然后通过串口打印。 I2C的DMA非常的难用需要配置I2C的NVIC中断和配置I2C的中断函数。才会调用I2C的DMA中断。还不知直接使用I2C的中断回调函数。 ①I2C.c文件的代码如下
#include I2C.h/*** briefI2C1初始化函数*/
I2C_HandleTypeDef hi2c1; //I2C初始化结构体
void I2C1_Init(void)
{/* 1、对I2C1进行初始化 */__HAL_RCC_I2C1_CLK_ENABLE(); //使能I2C1的时钟hi2c1.Instance I2C1; //选择I2C1hi2c1.Init.ClockSpeed 100000; //通信速率100K标志模式HAL_I2C_Init(hi2c1);/* 配置I2C1的NVIC */HAL_NVIC_SetPriority(I2C1_EV_IRQn,3,0);HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
}/*** briefHAL_I2C_Init()调用此函数*/
DMA_HandleTypeDef hdma1_I2C_Tx; //DMA1配置结构体
DMA_HandleTypeDef hdma1_I2C_Rx; //DMA1配置结构体
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{GPIO_InitTypeDef GPIO_Init; //IO口初始化结构体if(hi2c-Instance I2C1){/* I2C1引脚的初始化PB6 SCL,PB7 SDA*/__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB的时钟GPIO_Init.Mode GPIO_MODE_AF_OD; //复用开漏输出GPIO_Init.Pin GPIO_PIN_6 | GPIO_PIN_7; //PB6和PB7GPIO_Init.Speed GPIO_SPEED_FREQ_LOW; //最大输出速度低HAL_GPIO_Init(GPIOB, GPIO_Init);/* 2、初始化DMA1的通道6 */__HAL_RCC_DMA1_CLK_ENABLE(); //使能DMA1的时钟hdma1_I2C_Tx.Instance DMA1_Channel6; //选择DMA1的通道6hdma1_I2C_Tx.Init.PeriphDataAlignment DMA_PDATAALIGN_BYTE; //外设站点数据宽度,8位hdma1_I2C_Tx.Init.PeriphInc DMA_PINC_DISABLE; //外设地址是否递增选择不自增hdma1_I2C_Tx.Init.MemDataAlignment DMA_MDATAALIGN_BYTE; //内存站点数据宽度,8位hdma1_I2C_Tx.Init.MemInc DMA_MINC_ENABLE; //内存地址是否递增选择自增hdma1_I2C_Tx.Init.Direction DMA_MEMORY_TO_PERIPH; //传输方向这里选择内存----寄存器hdma1_I2C_Tx.Init.Mode DMA_NORMAL; //计数器传输模式选择不自动重装hdma1_I2C_Tx.Init.Priority DMA_PRIORITY_MEDIUM; //通道1传输优先级选择中等__HAL_LINKDMA(hi2c1,hdmatx,hdma1_I2C_Tx); //将I2C1_TX和DMA1通道6连接起来HAL_DMA_Init(hdma1_I2C_Tx);/* 配置DMA1通道6的NVIC */HAL_NVIC_SetPriority(DMA1_Channel6_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);/* 3、配置DMA1的通道7 */hdma1_I2C_Rx.Instance DMA1_Channel7; //选择DMA1的通道7hdma1_I2C_Rx.Init.PeriphDataAlignment DMA_PDATAALIGN_BYTE; //外设站点数据宽度,8位hdma1_I2C_Rx.Init.PeriphInc DMA_PINC_DISABLE; //外设地址是否递增选择不自增hdma1_I2C_Rx.Init.MemDataAlignment DMA_MDATAALIGN_BYTE; //内存站点数据宽度,8位hdma1_I2C_Rx.Init.MemInc DMA_MINC_ENABLE; //内存地址是否递增选择自增hdma1_I2C_Rx.Init.Direction DMA_PERIPH_TO_MEMORY; //传输方向这里选择寄存器----内存hdma1_I2C_Rx.Init.Mode DMA_NORMAL; //计数器传输模式选择不自动重装hdma1_I2C_Rx.Init.Priority DMA_PRIORITY_MEDIUM; //通道1传输优先级选择中等__HAL_LINKDMA(hi2c1,hdmarx,hdma1_I2C_Rx); //将I2C1_RX和DMA1通道7连接起来HAL_DMA_Init(hdma1_I2C_Rx);/* 配置DMA1通道6的NVIC */HAL_NVIC_SetPriority(DMA1_Channel7_IRQn,3,0);HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);}else if(hi2c-Instance I2C2){}
}②I2C.h文件的代码如下
#ifndef __I2C_H
#define __I2C_H#include stm32f1xx_hal.h
extern I2C_HandleTypeDef hi2c1; //I2C初始化结构体
extern DMA_HandleTypeDef hdma1_I2C_Tx; //DMA1配置结构体
extern DMA_HandleTypeDef hdma1_I2C_Rx; //DMA1配置结构体
void I2C1_Init(void);#endif③main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include UART.h
#include I2C.h
#include Key.h#define AT24C02_Address 0xA0uint8_t WriteData[8] {1,2,3,4,5,6,7,8};
uint8_t ReadData[8];int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);I2C1_Init();Key_GPIO_Init();printf(启动判断\r\n);while(1){switch(Key_Scan()){case 1://按键PB0按下if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK){/* 存储器模式对AT24C02的页进行写且开启DMA写入完成中断 */HAL_I2C_Mem_Write_DMA(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, WriteData, 8);}break;case 2://按键PB1按下if(HAL_I2C_IsDeviceReady(hi2c1, AT24C02_Address, 20, 1000) HAL_OK){/* 存储器模式对AT24C02的页进行读且开启DMA读取完成中断 */HAL_I2C_Mem_Read_DMA(hi2c1, AT24C02_Address, 0, I2C_MEMADD_SIZE_8BIT, ReadData, 8);}break; }}
}④stm32f1xx_it.c文件的代码如下
#include stm32f1xx_hal.h
#include stm32f1xx_it.h
#include I2C.h
#include UART.h/*** I2C1中断服务函数 */
void I2C1_EV_IRQHandler(void)
{HAL_I2C_EV_IRQHandler(hi2c1);//中断服务总函数
}
/*** DMA1通道6的中断服务函数 */
void DMA1_Channel6_IRQHandler(void)
{HAL_DMA_IRQHandler(hdma1_I2C_Tx);
}/*** DMA1通道7的中断服务函数 */
void DMA1_Channel7_IRQHandler(void)
{HAL_DMA_IRQHandler(hdma1_I2C_Rx);
}
/******************* 下面的中断的回调函数 ***************************/
/*** 存储器模式I2C1的DMA发送完成中断回调函数*/
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c-Instance I2C1){printf(发送完成了\r\n);}else if(hi2c-Instance I2C2){}
}/*** 存储器模式I2C1的DMA读取完成中断回调函数*/
extern uint8_t ReadData[8];
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{if(hi2c-Instance I2C1){printf(读取完成了\r\n);for(uint8_t i 0; i8; i){printf(ReadData[%d] %d\r\n,i,ReadData[i]);}}else if(hi2c-Instance I2C2){}
}