我TMD也是服了,反正我板子搞了半天也不成功我也不知道为什么,野火STM32-MINI,一直卡EV5,不管了 先代码沾上

工程目录(板子为野火STM32 MINI)

串口相关代码:

bsp_usart.h

#ifndef __USART_H
#define __USART_H #include "stm32f10x.h"
#include <stdio.h> /**
* 串口宏定义,不同的串口挂载的总线和IO不一样,移植时需要修改这几个宏
* 1-修改总线时钟的宏,uart1挂载到apb2总线,其他uart挂载到apb1总线
* 2-修改GPIO的宏
*/ // 串口1-USART1
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200 // USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 #define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler void USART_Config(void); #endif /* __USART_H */

bsp_usart.c

 

#include "./usart/bsp_usart.h"

 /**
* @brief USART GPIO 配置,工作参数配置
* @param 无
* @retval 无
*/
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure; // 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
// 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No ;
// 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置
USART_Init(DEBUG_USARTx, &USART_InitStructure); // 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
} ///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch); /* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); return (ch);
} ///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(DEBUG_USARTx);
}

bsp_i2c_ee.h

#ifndef __I2C_EE_H
#define __I2C_EE_H #include "stm32f10x.h"
#include "bsp_usart.h" #define EEPROM_ADDR 0xA0 void I2C_EE_Config(void);
void EEPROM_Byte_Write(uint8_t addr,uint8_t data);
void EEPROM_Page_Write(uint8_t addr,uint8_t *data,uint8_t numByteToWrite);
void EEPROM_Read(uint8_t addr,uint8_t *data,uint8_t numByteToRead);
void EEPROM_WaitForWriteEnd(void); #endif /* __I2C_EE_H */

bsp_i2c_ee.c

#include "bsp_i2c_ee.h"

void I2C_EE_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure; // 打开IIC GPIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 打开IIC 外设的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // 将IIC SCL SDA的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置IIC的工作参数
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;//使能应答
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit ;//使用7位地址模式
I2C_InitStructure.I2C_ClockSpeed = 400000; //配置SCL时钟频率
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2 ;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;
I2C_InitStructure.I2C_OwnAddress1 = 0x5f; //这是STM32 IIC自身设备地址,只要是总线上唯一即可 I2C_Init(I2C1,&I2C_InitStructure); // 使能串口
I2C_Cmd (I2C1, ENABLE);
} //向EEPROM写入一个字节 void EEPROM_Byte_Write(uint8_t addr,uint8_t data)
{
//产生起始信号
I2C_GenerateSTART(I2C1,ENABLE); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) == ERROR); //EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(I2C1,EEPROM_ADDR,I2C_Direction_Transmitter); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) == ERROR); //EV6事件被检测到,发送要操作的存储单元地址
I2C_SendData (I2C1,addr); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING ) == ERROR); //EV8事件被检测到,发送要存储的数据
I2C_SendData (I2C1,data); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED ) == ERROR); //数据传输完成
I2C_GenerateSTOP(I2C1,ENABLE); } //向EEPROM写入多个字节(页写入),每次写入不能超过8个字节 void EEPROM_Page_Write(uint8_t addr,uint8_t *data,uint8_t numByteToWrite)
{
//产生起始信号
I2C_GenerateSTART(I2C1,ENABLE); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) == ERROR); //EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(I2C1,EEPROM_ADDR,I2C_Direction_Transmitter); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) == ERROR); //EV6事件被检测到,发送要操作的存储单元地址
I2C_SendData (I2C1,addr); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING ) == ERROR); while(numByteToWrite)
{
//EV8事件被检测到,发送要存储的数据
I2C_SendData (I2C1,*data); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED ) == ERROR); data++;
numByteToWrite--; }
//数据传输完成
I2C_GenerateSTOP(I2C1,ENABLE); } //从EEPROM读取数据 void EEPROM_Read(uint8_t addr,uint8_t *data,uint8_t numByteToRead)
{
//产生起始信号
I2C_GenerateSTART(I2C1,ENABLE); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) == ERROR); //EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(I2C1,EEPROM_ADDR,I2C_Direction_Transmitter); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) == ERROR); //EV6事件被检测到,发送要操作的存储单元地址
I2C_SendData (I2C1,addr); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING ) == ERROR); //第二次起始信号
//产生起始信号
I2C_GenerateSTART(I2C1,ENABLE); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT) == ERROR); //EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(I2C1,EEPROM_ADDR,I2C_Direction_Receiver); while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) == ERROR); while(numByteToRead)
{
if(numByteToRead == 1)
{
//如果为最后一个字节
I2C_AcknowledgeConfig (I2C1,DISABLE);
} //EV7事件被检测到
while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED ) == ERROR); //EV7事件被检测到,即数据寄存器有新的有效数据
*data = I2C_ReceiveData(I2C1); data++; numByteToRead--; } //数据传输完成
I2C_GenerateSTOP(I2C1,ENABLE); //重新配置ACK使能,以便下次通讯
I2C_AcknowledgeConfig (I2C1,ENABLE); } //等待EEPROM内部时序完成
void EEPROM_WaitForWriteEnd(void)
{ do
{
//产生起始信号
I2C_GenerateSTART(I2C1,ENABLE); while(I2C_GetFlagStatus (I2C1,I2C_FLAG_SB) == RESET); //EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(I2C1,EEPROM_ADDR,I2C_Direction_Transmitter);
}
while(I2C_GetFlagStatus (I2C1,I2C_FLAG_ADDR) == RESET ); //EEPROM内部时序完成传输完成
I2C_GenerateSTOP(I2C1,ENABLE);
}

main.c

#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./i2c/bsp_i2c_ee.h" uint8_t readData[10]={0};
uint8_t writeData[8]={4,5,6,7,8,9,10,11};
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
uint8_t i=0;
USART_Config();
printf("这是一个IIC通讯实验\n"); I2C_EE_Config();
//向 EEPROM 11地址写入0x55,
EEPROM_Byte_Write(11,0x55);
EEPROM_WaitForWriteEnd();
//读出 EEPROM 11地址的内容,保存到readData中(数组的第一个址位)
EEPROM_Read(11,readData,1);
printf("%x",readData[0]); //addr%8 == 0 ,即为地址对齐
EEPROM_Page_Write(16,writeData,8); //等待写入操作完成
EEPROM_WaitForWriteEnd(); //读取数据
EEPROM_Read(16,readData,8);
for(i=0;i<8;i++)
{
printf("%d ",readData[i]);
}
while(1);
}
/*********************************************END OF FILE**********************/

硬件实现IIC协议读取EEPROM的更多相关文章

  1. 第十六章 IIC协议详解+UART串口读写EEPROM

    十六.IIC协议详解+Uart串口读写EEPROM 本文由杭电网友曾凯峰根据小梅哥FPGA IIC协议基本概念公开课内容整理并最终编写Verilog代码实现使用串口读写EEPROM的功能. 以下为原文 ...

  2. IIC协议建模——读写EEPROM

    案例采用明德扬设计思想完成.IIC协议是非常常用的接口协议,在电子类岗位招聘要求中经常出现它的身影.关于IIC协议这里只做简要介绍,详细信息请自行百度或查阅相关Datasheet,网上资料非常多.该篇 ...

  3. 基于STM8的IIC协议--实例篇--时钟模块(DS3231)读取

    1. 综述 由上篇博客可知道IIC协议如何用代码实现,本篇博客就不涉及协议内容,只讲解如何使用. 本次的实验传感为:DS3231(时钟模块),对于时钟模块的具体信息我也就不多介绍,大家可以自行度娘,具 ...

  4. IIC协议理解(转)

    目录 IIC协议理解(转) 个人小结记录 (记一下这个就够了) 以下为转载记录 概述 概述 输出级 主设备与从设备 速率 时序 空闲状态 起始位与停止位 数据的有效性 数据的传送 工作过程 主设备向从 ...

  5. IIC协议解释(转)

    IIC协议解释 推荐资源: http://m.elecfans.com/article/574049.html       and       https://blog.csdn.net/firefl ...

  6. 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)

     版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...

  7. IIC协议解释

    IIC协议解释 (1)概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量 ...

  8. IIC协议解析

    (1)概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距 ...

  9. IIC协议学习笔记

    "移植"的重要性:并非所有的电路都得自己设计,到了一定阶段,"移植"也是一种学习能力.--CrazyBingo 转眼间期末又到了,最近开始了所谓的期末总预习,比 ...

随机推荐

  1. PHP 之Html标签转义与反转义

    1.htmlentities()函数转义html 2.html_entity_decode()函数反转义html 我这里是用来反转义富文本编辑器的内容

  2. python3编程基础之一:注释模块和包

    1.注释 python中的注释和其他任何编程语言中的注释都不一样,有的注释有特殊要求,而是还是有用的. 1).单行注释:注释以#开始到语句结尾,#号后一般跟一个空格 2).多行注释:文档注释,以&qu ...

  3. mysql的配置文件解释

    1 在执行mysqld命令时,下列配置会生效,即mysql服务启动时生效 [mysqld] character_set_server=utf8collation-server=utf8_general ...

  4. GIS 空间分析案例分析-错误排除经验总结

    GIS 空间分析案例分析-错误排除经验总结 商务科技合作:向日葵,135—4855__4328,xiexiaokui#qq.com 目录:问题发现,问题分析,解决方法,结果 1. problem di ...

  5. python开发-实现redis中的发布订阅功能

    Python3学习(二十七):python实现Redis的订阅与发布(sub-pub机制) 先介绍一下redis的pub/sub功能: Pub/Sub功能(means Publish, Subscri ...

  6. linux服务器下安装phpstudy 如何命令行进入mysql

    配置了phpstudy 可是进不去mysql 老是报-bash: mysqld: command not found 解决方法:在linux环境下运行:ln -s /phpstudy/mysql/bi ...

  7. 建站之星v2.7快速更换模版

    网站建设很多人使用建站之星因为它的拖拽功能非常友好.但是很多人不会使用建站之星更换模版,网上的教程又复杂难懂,现在教大家一个简单快捷的办法. 方法/步骤     废话不多说,从模版目录找到你喜欢的模版 ...

  8. VS2015 osgEarth 编译

    E:\OpenSourceGraph\CURL_install\includeE:\GDAL\includeE:\Geos\geos_3_5_install\includeE:\OpenSourceG ...

  9. web自动化-selenium+Chrome驱动国内下载地址+驱动对应Chrome版本号

    selenium各版本下载地址 http://selenium-release.storage.googleapis.com/index.html 国内下载:http://npm.taobao.org ...

  10. 123457123457---com.threeapp.ShuiShiYanLiWang01----谁是眼力王

    com.threeapp.ShuiShiYanLiWang01----谁是眼力王