STM32 模拟I2C (STM32F051)
/**
******************************************************************************
* @file i2c simu.c
* @brief simulation function
* @CPU STM32F051
* @compiler Keil uVision V4.74
* @author MetalSeed
* @copyright WSHHB
* @version V1.0.0
* @date 18-Sept-2014
* @modifydate20-Sept-2014
******************************************************************************
* @attention
*/ #include "boardAPI.h"
#include "i2cSimu.h"
#include "delay.h"
#include "uart.h" GPIO_InitTypeDef GPIO_InitStructure; /**
* @brief IIC Init
* @param A:
* @retval None
*/
void IIC_Init(void)
{
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOF, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_6|GPIO_Pin_7); //PB10,PB11 Êä³ö¸ß
} /**
* @brief Set SDA Pin as Output Mode
* @retval None
*/
void SDA_OUT()
{
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
} /**
* @brief Set SDA Pin as Input Mode
* @retval None
*/
void SDA_IN()
{
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// !!!
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
} /**
* @brief read input voltage from SDA pin
* @retval None
*/
BYTE SDA_READ()
{
return GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_7);
} /**
* @brief output high form SDA pin
* @retval None
*/
void IIC_SDA_1()
{
GPIO_SetBits(GPIOF, GPIO_Pin_7);
} /**
* @brief output low form SDA pin
* @retval None
*/
void IIC_SDA_0()
{
GPIO_ResetBits(GPIOF, GPIO_Pin_7);
} /**
* @brief output high form SCL pin
* @retval None
*/
void IIC_SCL_1()
{
GPIO_SetBits(GPIOF, GPIO_Pin_6);
} /**
* @brief output LOW form SCL pin
* @retval None
*/
void IIC_SCL_0()
{
GPIO_ResetBits(GPIOF, GPIO_Pin_6);
} /**
* @brief Simulate IIC conmunication :Create Start signal
* @retval None
*/
void IIC_Start(void)
{
SDA_OUT(); //sda output
IIC_SDA_1();
IIC_SCL_1();
delayus(4);
IIC_SDA_0(); //START:when CLK is high,DATA change form high to low
delayus(4);
IIC_SCL_0(); //hold scl line, prepare to transmit data
} /**
* @brief Simulate IIC conmunication : Create Stop signal
* @retval None
*/
void IIC_Stop(void)
{
SDA_OUT(); //sda output mode
IIC_SCL_0();
IIC_SDA_0(); //STOP:when CLK is high DATA change form low to high
delayus(4);
IIC_SCL_1();
IIC_SDA_1(); //indicate transmit over
delayus(4);
} /**
* @brief Simulate IIC conmunication : wait for target device's ACK
* @retval ACK (0) : receive success
* @retval NACK(1) : receive unsuccess
*/
BYTE IIC_Wait_Ack(void)
{
BYTE ucErrTime = 0;
SDA_IN(); //set as input mode
IIC_SDA_1();
delayus(1);
IIC_SCL_1();
delayus(1);
while(SDA_READ())
{
ucErrTime++;
if(ucErrTime > 250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_0(); //release scl line
return 0;
} /**
* @brief Simulate IIC conmunication : make an ACK
* @retval None
*/
void IIC_Ack(void)
{
IIC_SCL_0();
SDA_OUT();
IIC_SDA_0();
delayus(2);
IIC_SCL_1();
delayus(2);
IIC_SCL_0();
} /**
* @brief Simulate IIC conmunication : don't make an ACK
* @retval None
*/
void IIC_NAck(void)
{
IIC_SCL_0();
SDA_OUT();
IIC_SDA_1();
delayus(2);
IIC_SCL_1();
delayus(2);
IIC_SCL_0();
} /**
* @brief Simulate IIC conmunication : Transmit one byte Data
* @param txd: data to be transmit
* @retval None
*/
void IIC_Send_Byte(BYTE txd)
{
BYTE i;
SDA_OUT();
IIC_SCL_0();//push down scl to start transmit data
for(i = 0; i < 8; ++i)
{
if(txd & 0x80)
{
IIC_SDA_1();
}
else
{
IIC_SDA_0();
}
txd <<= 1;
delayus(2);
IIC_SCL_1();
delayus(2);
IIC_SCL_0();
delayus(2);
}
} //¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK
/**
* @brief Simulate IIC conmunication : Receive one byte Data
* @param ack: Whether transmit ACK
* @retval the data have been receive
*/
BYTE IIC_Read_Byte(unsigned char ack)
{
unsigned char i, res = 0;
SDA_IN(); //SDA input mode
for(i = 0; i < 8; ++i )
{
IIC_SCL_0();
delayus(2);
IIC_SCL_1();
res <<= 1;
if(SDA_READ())
{
res++;
}
delayus(1);
}
if (!ack)
{
IIC_NAck();//make NACK
}
else
{
IIC_Ack(); //make ACK
}
return res;
} /*JUST SOME TEST FUNTION DEMO*/
BYTE ReadData()
{
BYTE temp=0;
IIC_Start(); IIC_Send_Byte(0x80);
IIC_Wait_Ack(); IIC_Send_Byte(0xf5);
IIC_Wait_Ack(); IIC_Start();
IIC_Send_Byte(0XA1);
IIC_Wait_Ack(); temp=IIC_Read_Byte(0);
IIC_Stop();
return temp;
} void WriteData(BYTE DataToWrite)
{
IIC_Start();
IIC_Send_Byte(0x80);
if( IIC_Wait_Ack() == 0)
{
printf("Recieve ACK \n");
} IIC_Send_Byte(0xf5);
IIC_Wait_Ack(); IIC_Send_Byte( DataToWrite );
IIC_Wait_Ack(); IIC_Stop();
delayms(10);
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
STM32 模拟I2C (STM32F051)的更多相关文章
- STM32模拟I2C
之前为了测试, 拿最小板做了一个I2C的主发跟主读, 一开始当然是尝试用硬件I2C, 结果弄了很久, 时间紧迫, 只好用了模拟, 结果发现, 哎, 真特么挺好用的, 现在1片儿顶过去5片儿. 硬件I2 ...
- STM32F4XX中断方式通过IO模拟I2C总线Master模式
STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...
- STM32的I2C特性及架构
软件模拟协议:使用CPU直接控制通讯引脚(GPIO)的电平,产生出符合通讯协议标准的逻辑. 硬件实现协议:由STM32的I2C片上外设专门负责实现I2C通讯协议,只要配置好该外设,它就会自动根据协议要 ...
- 浅谈 STM32 硬件I2C的使用 (中断方式 无DMA 无最高优先级)(转)
引子 STM32的硬件I2C很多人都对它望而却步.因为很多电工都说,STM32 硬件 I2C有BUG.不稳定.死机等等……最后都使用GPIO模拟I2C. 的确,模拟I2C好用.但是在我看来在一个72M ...
- STM32的I2C框图详解及通讯过程
STM32 的I2C 特性及架构 如果我们直接控制STM32 的两个GPIO 引脚,分别用作SCL 及SDA,按照上述信号的时序要求,直接像控制LED 灯那样控制引脚的输出(若是接收数据时则读取SDA ...
- S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
目录:一. 说明 二. 驱动程序说明及问题 三. 案例一 四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...
- STM32 硬件I2C 到底是不是个坑?
/** ****************************************************************************** * @author Maox ...
- MSP430的IO口模拟I2C总线对AT24C25进行读写程序
功能: 实现MSP430口线模拟I2C总线协议与24C04通信. ** 描述: 主系统工作时钟为12MHz,I2C工 ...
- STM8S 模拟I2C程序
STM8S的硬件I2C还是存在问题,不敢贸然使用. 于是决定用模拟I2C. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM P ...
随机推荐
- Windows共享上网的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 现在有这样一个网络应用场景:A机器是一个PC台式机,处在两个网络中,一个是处在192.168.30.1到192.168 ...
- js进阶正则表达式8量词(+*?{}的意义用法)(量词的对象是前面一个字符)
js进阶正则表达式8量词(+*?{}的意义用法)(量词的对象是前面一个字符) 一.总结 1.量词的对象是前面一个字符 量词 描述 n+ 匹配任何包含至少一个 n 的字符串. n* 匹配任何包含零个或多 ...
- Redis的增删改查、持久化你会了吗
原文:Redis的增删改查.持久化你会了吗 Redis是用C语言实现的,一般来说C语言实现的程序"距离"操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多线程 ...
- JavaScript调用ATL COM(二)
作者:朱金灿 来源:http://blog.csdn.net/clever101 在上篇文章中介绍了如何在JS中调用ATL COM: JS调用ATL COM中的C++接口的做法 现在我们可以把它嵌入到 ...
- 【t005】数字构造问题
Time Limit: 1 second Memory Limit: 50 MB [问题描述] 给定一个只包含数字[0..9]的字符串,请使用字符串中的某些字符,构建一个能够整除15最大的整数.注意, ...
- Android View框架的measure机制
概述 Android中View框架的工作机制中,主要有三个过程: 1.View树的測量(measure)Android View框架的measure机制 2.View树的布局(layout) Andr ...
- iOS 通讯录基础
iOS 6 之后应用訪问通讯录须要获得用户授权,而且仅仅授权一次,即使卸载了之后再安装.也不用再次授权. 开发通讯录应用须要两个框架: 1.ABAddressBook 主要用于提供訪问通讯录中 ...
- erlang数字转字符串
http://fengmm521.blog.163.com/blog/static/2509135820147922355273/ 如果有一个数字,你想要转换成字符串这个在Erlang中是怎么操作的, ...
- 欢迎阅读 Erlang OTP 设计原理文档
http://erldoc.com/doc/otp-design-principles/index.html 原文: OTP Design Principles 翻译: ShiningRay 有任何问 ...
- TensorFlow 需注意的细节问题
1. 数据类型 不带小数点的数默认为 int32,带小数点的数默认为 float32: