STM32 软件模拟 IIC 代码,标准库、HAL库可用

 1 #ifndef _IIC_H
 2 #define _IIC_H
 3 
 4 #include "stdio.h"    
 5 #include "stm32f1xx_hal.h"
 6 
 7 
 8 /* 定义控制 SDA SCL 的宏 标准库版
 9 #define I2C_SDA_UP        GPIO_SetBits  (GPIOC,GPIO_PIN_8)    //SDA高电平
10 #define I2C_SDA_LOW        GPIO_ResetBits(GPIOC,GPIO_PIN_8)    //SDA低电平
11 #define I2C_SCL_UP        GPIO_SetBits  (GPIOC,GPIO_PIN_9)    //SCL高电平
12 #define I2C_SCL_LOW        GPIO_ResetBits(GPIOC,GPIO_PIN_9)    //SCL低电平
13 */
14 
15 
16 /* 定义控制 SDA SCL 的宏 HAL库版    */
17 
18 #define I2C_SDA_UP        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET)                //SDA高电平
19 #define I2C_SDA_LOW        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET)            //SDA低电平
20 #define I2C_SCL_UP        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET)              //SCL高电平
21 #define I2C_SCL_LOW        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET)            //SCL低电平
22 
23 
24 
25 /* 获取 SDA SCL 引脚状态,标准库版也是用相同逻辑    */
26 
27 #define I2C_SDA        HAL_GPIO_ReadPin(GPIOC ,GPIO_PIN_8)        //获取SDA引脚状态
28 #define I2C_SCL        HAL_GPIO_ReadPin(GPIOC ,GPIO_PIN_9)        //获取SCL引脚状态
29 
30 
31 void         iic_stare(void);                    //*    开始信号    
32 void         i2c_ack(void);                        //*    应答信号    
33 void         I2C_No_ack(void);                    //*    非应答信号    
34 void         i2c_stop(void);                        //*    停止信号    
35 char         i2c_wit_ack(void);                //*    等待应答
36 void         i2c_send(uint8_t dat);        //* 发送数据
37 uint8_t i2c_read(void);                        //* 接收数据
38 
39 void SDA_OUT(void);                //*    SDA 设置为输出    
40 void SDA_IN(void);                //*    SDA 设置为输入    
41 
42 void delay_us(uint32_t i);        //*延时    
43 
44 #endif
/*****************************************************************************
*                                                                                                                                                         *
*                        File:    软件模拟IIC, HAL库版本,标准库也                                                     *
*                                    可用,只需要做一些相对应修改即可                                                     *
*                                                                                                                                                         *
*****************************************************************************/#include "iic.h"/*******************************************************************************
* 函 数 名         : i2c_stare
* 函数功能         : iic开始信号,SCL高电平时,SDA出现一个下跳沿表示启动信号 
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void i2c_stare(void)
{SDA_OUT();  I2C_SDA_UP;I2C_SCL_UP;delay_us(4);I2C_SDA_LOW;        //启动开始信号delay_us(4);I2C_SCL_LOW;      //钳住I2C总线,准备发送或接收数据
}/*******************************************************************************
* 函 数 名         : i2c_stop
* 函数功能         : iic停止信号,SCL高电平时,SDA出现一个上跳沿表示停止信号
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void i2c_stop(void)
{SDA_OUT();            //sda线输出I2C_SDA_LOW;         //发送结束条件的数据信号
    I2C_SCL_UP;delay_us(4);         //结束条件建立时间大于4μI2C_SDA_UP;         //发送I2C总线结束信号delay_us(4);I2C_SCL_LOW; 
}/*******************************************************************************
* 函 数 名         : i2c_send
* 函数功能         : iic发送数据
* 输    入         : uint8_t dat,要发送的数据
* 输    出         : 无
*******************************************************************************/
void i2c_send(uint8_t dat)
{unsigned char temp;SDA_OUT();for(temp=0x80;temp!=0;temp>>=1){if((temp & dat)== 0){I2C_SDA_LOW;}else{I2C_SDA_UP;}delay_us(1);I2C_SCL_UP;delay_us(4);I2C_SCL_LOW;}
}/*******************************************************************************
* 函 数 名         : i2c_read
* 函数功能         : iic接收数据
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
uint8_t i2c_read(void)
{unsigned char temp;unsigned char dat;I2C_SDA_UP;                     //释放总线准备接收
     SDA_IN();for(temp=0x80;temp!=0;temp>>=1){delay_us(1);I2C_SCL_UP;if(I2C_SDA==1){dat|=temp;}else{dat&=~temp;}I2C_SCL_LOW;}return dat;
}/*******************************************************************************
* 函 数 名         : i2c_wit_ack
* 函数功能         : iic等待应答
* 输    入         : 无
* 输    出         : 0/1,返回1表示无应答信号,返回0表示应答
*******************************************************************************/
char i2c_wit_ack(void)
{uint8_t con=0;I2C_SDA_UP;       //释放数据线,准备接收应答delay_us(1);I2C_SCL_UP;                //CPU驱动SCL = 1, 此时器件会返回ACK应答
    SDA_IN(); delay_us(1);while( I2C_SDA )    //CPU读取SDA口线状态
  {con++;if(con>255){i2c_stop();return 1;     //无应答信号
        }}I2C_SCL_LOW; delay_us(1);return 0;             //有应答
}/*******************************************************************************
* 函 数 名         : i2c_ack
* 函数功能         : iic应答信号
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void i2c_ack(void)
{SDA_OUT();I2C_SDA_LOW;delay_us(1);I2C_SCL_UP;            //CPU产生1个时钟delay_us(4);         //时钟低电平周期大于4μI2C_SCL_LOW;         //清时钟线,钳住I2C总线以便继续接收delay_us(4);I2C_SDA_UP;            //CPU释放SDA总线
}/*******************************************************************************
* 函 数 名         : I2C_No_ack
* 函数功能         : iic非应答信号
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void I2C_No_ack(void)
{SDA_OUT();I2C_SDA_UP;delay_us(1);I2C_SCL_UP;delay_us(4);I2C_SCL_LOW; delay_us(4);
}/*******************************************************************************
* 函 数 名         : SDA_OUT
* 函数功能         : SDA 设置为输出
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void SDA_OUT(void)
{ /*    标准库使用,修改端口引脚可用GPIO_InitTypeDef GPIO_InitTypeStruct;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  GPIO_InitTypeStruct.GPIO_Mode=GPIO_Mode_Out_PP;  GPIO_InitTypeStruct.GPIO_Pin=GPIO_Pin_7;  GPIO_InitTypeStruct.GPIO_Speed=GPIO_Speed_50MHz;  GPIO_Init(GPIOB,&GPIO_InitTypeStruct); 
*/    /*    HAL库使用,HAL库注意要把初始化函数的静态标记去掉    */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = SDA_Pin;                    //使用STM3cubemx是定义好的SDA_Pin为GPIO_PIN_8的标签GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}/*******************************************************************************
* 函 数 名         : SDA_IN
* 函数功能         : SDA 设置为输入
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void SDA_IN(void)  
{/*    标准库使用,修改端口引脚可用GPIO_InitTypeDef GPIO_InitTypeStruct;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);       GPIO_InitTypeStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;  GPIO_InitTypeStruct.GPIO_Pin=GPIO_Pin_7;  GPIO_InitTypeStruct.GPIO_Speed=GPIO_Speed_50MHz;  GPIO_Init(GPIOB,&GPIO_InitTypeStruct);  
*/    /*    HAL库使用, HAL库注意要把初始化函数的静态标记去掉    */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = SDA_Pin    ;                    //使用STM3cubemx是定义好的SDA_Pin为GPIO_PIN_8的标签GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
} /*******************************************************************************
* 函 数 名         : delay_us
* 函数功能         : 延时函数,延时us
* 输    入         : i
* 输    出         : 无
*******************************************************************************/
void delay_us(uint32_t i)
{uint32_t temp;SysTick->LOAD=9*i;                     //设置重装数值, 72MHZ时SysTick->CTRL=0X01;                 //使能,减到零是无动作,采用外部时钟源SysTick->VAL=0;                 //清零计数器do{temp=SysTick->CTRL;                            //读取当前倒计数值
    }while((temp&0x01)&&(!(temp&(1<<16))));     //等待时间到达
        SysTick->CTRL=0;         //关闭计数器SysTick->VAL=0;        //清空计数器
}

 

该代码,标准库可用,HAL库也可用,只需要代码做一些修改即可!

转载于:https://www.cnblogs.com/xingboy/p/9585350.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

作用域及上下文理解

书本中的解释 [[scope]]:每个javascript函数都是一个对象&#xff0c;对象中有些属性我们可以访问&#xff0c;但有些不可以&#xff0c;这些属性仅供javascript引擎存取&#xff0c;[[scope]]就是其中一个。[[scope]]:指的就是我们所说的作用域&#xff0c;其中存储了运行期上…

[css] css中Scroll-behavior属性有什么应用场景?

[css] css中Scroll-behavior属性有什么应用场景&#xff1f; 当用户手动点击导航或者API调用导致触发滚动操作时&#xff0c;scroll-behavior属性可以为滚动框设定滚动行为。auto表示立即滚动到指定位置&#xff0c;smooth则表示平滑过渡&#xff0c;需要一定的过度时间滚动到…

windows下安装ElasticSearch的Head插件

es5以上版本安装head需要安装node和grunt(之前的直接用plugin命令即可安装) (一)从地址&#xff1a;https://nodejs.org/en/download/ 下载相应系统的msi&#xff0c;双击安装。 &#xff08;二&#xff09;安装完成用cmd进入安装目录执行 node -v可查看版本号 &#xff08;三&…

立即执行函数

定义&#xff1a; 此类函数没有声明&#xff0c;在一次执行过后即释放。适合做初始化工作。 //立即执行函数格式&#xff0c;此类函数执行完即销毁&#xff0c;除了这点&#xff0c;和其它函数一样 (function (){}()); W3C建议使用这种 (function (){})();//只有表达式才能被…

[css] 使用css实现对话气泡的效果

[css] 使用css实现对话气泡的效果 方法&#xff1a;使用圆角矩形作为对话的主体框&#xff0c;左侧或右侧增加附加三角形&#xff0c;三角形使用border样式设置来实现&#xff0c;相对定位和绝对定位结合使三角形附于圆角矩形左侧或右侧&#xff1b; html: <div class"…

iframe嵌套其它网站页面详解

iframe基本内涵 通常我们使用iframe直接直接在页面嵌套iframe标签指定src就可以了。 <iframe src"demo_iframe_sandbox.htm"></iframe> 但是&#xff0c;有追求的我们&#xff0c;并不是想要这么low的iframe. 我们来看看在iframe中还可以设置些什么属…

JavaScript 闭包

闭包概念&#xff1a; 当内部函数被保存到外部时&#xff0c;将会生成闭包。闭包会导致原有作用域链不释放&#xff0c;造成内存泄漏。 什么时候才会触发闭包呢&#xff1f; 当两个函数互相嵌套&#xff0c;把里面的函数被保存到了外部&#xff08;全局&#xff09;&#xff…

[css] 如何隐藏没有静音、自动播放的音视频?

[css] 如何隐藏没有静音、自动播放的音视频&#xff1f; 浏览器已禁止打开页面时自动播放&#xff0c;可以用iframe先播触发播放权限&#xff0c;然后再播放 做一个opacity:0 的假隐藏个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但…

PyAutoIt 安装(Windows 版)

转载于:https://www.cnblogs.com/Crixus3714/p/9592635.html

[css] 你有使用过css的writing-mode属性吗?说说它有哪些应用场景?

[css] 你有使用过css的writing-mode属性吗&#xff1f;说说它有哪些应用场景&#xff1f; 用于规定文字的书写方式 horizontal-tb 从左到右从上到下(水平书写) vertical-rl 从上到下从右到左 (垂直书写) vertiacl-lr 从上到下从左到右 sideways-rl&#xff1a;内容垂直方向从上…

文案资源

策划与营销类网站 全球顶尖创意分享平台 OPEN YOUR MIND 数英网-数字媒体及职业招聘网站 SocialBeta | 领先的社交媒体和数字营销内容与招聘平台 梅花网&#xff0d;营销者的信息中心 视觉素材类网站 花瓣网_发现、采集你喜欢的一切 昵图网_原创素材共享平台www.nipic.co…

scp命令:服务器间远程复制代码

scp是secure copy的简写&#xff0c;用于在Linux下进行远程拷贝文件的命令&#xff0c;和它类似的命令有cp&#xff0c;不过cp只是在本机进行拷贝不能跨服务器&#xff0c;而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system时&#xff0c…

[css] 怎么使用css选择空链接?

[css] 怎么使用css选择空链接&#xff1f; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style type"text/css">a[href], a:not(href) {color: #ff3333;}<…

构造函数内部原理 包装类

构造函数内部原理 在函数体最前面隐式得加上this {}执行 this.xxx xxx;隐式的返回this 包装类 定义一个原始数字或字符串&#xff0c;在JS里面&#xff0c;其实有两种方法 var num 123; var str abcd;var num new number(123); var str new string(abcd); 但是这两…

[css] 说说你对table-layout的理解,它有什么运用场景?

[css] 说说你对table-layout的理解&#xff0c;它有什么运用场景&#xff1f; table-layout 值为 fixed时单元格的宽度只与表格&#xff0c;单元格的宽度有关&#xff0c;与内容无关 table-layout 值为 auto 时&#xff0c;单元格的宽度为当前列的最长行有的宽度来计算 如果想…

Centos7安装部署Zabbix3.4

1.关闭selinux和firewall 1.1检测selinux是否关闭 [rootlocalhost ~]# getenforce Disabled #Disabled 为关闭 1.1.1临时关闭[rootlocalhost ~]# setenforce 0 #设置SELinux 成为enforcing模式1.1.2永久关闭 [rootlocalhost ~]# vi /etc…

[css] 颜色hsla的字母分别表示什么?

[css] 颜色hsla的字母分别表示什么&#xff1f; H&#xff1a;Hue(色调)。0(或360)表示红色&#xff0c;120表示绿色&#xff0c;240表示蓝色&#xff0c;也可取其他数值来指定颜色。取值为&#xff1a;0 - 360 S&#xff1a;Saturation(饱和度)。取值为&#xff1a;0.0% - 10…

JavaScript中的回调函数(callback)

前言 callback&#xff0c;大家都知道是回调函数的意思。如果让你举些callback的例子&#xff0c;我相信你可以举出一堆。但callback的概念你知道吗&#xff1f;你自己在实际应用中能不能合理利用回调实现功能&#xff1f; 我们在平时的学习中容易犯不去深究的病&#xff0c;功…

javascript构造函数类和原型prototype定义的属性和方法的区别

1、把方法写在原型中比写在构造函数中消耗的内存更小&#xff0c;因为在内存中一个类的原型只有一个&#xff0c;写在原型中的行为可以被所有实例共享&#xff0c; 实例化的时候并不会在实例的内存中再复制一份 而写在类中的方法&#xff0c;实例化的时候会在每个实例中再复制一…

[css] 如何禁用移动的选择高亮?

[css] 如何禁用移动的选择高亮&#xff1f; *{ -webkit-touch-callout:none; /*系统默认菜单被禁用*/ -webkit-user-select:none; /*webkit浏览器*/ -khtml-user-select:none; /*早期浏览器*/ -moz-user-select:none;/*火狐*/ -ms-user-select:none; /*IE10*/ user-sele…