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

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
31void        iic_stare(void);                    //*    开始信号
32void        i2c_ack(void);                        //*    应答信号
33void        I2C_No_ack(void);                    //*    ⾮应答信号
34void        i2c_stop(void);                        //*    停⽌信号
35char        i2c_wit_ack(void);                //*    等待应答
36void        i2c_send(uint8_t dat);        //* 发送数据
37 uint8_t i2c_read(void);                        //* 接收数据
38
39void SDA_OUT(void);                //*    SDA 设置为输出
40void SDA_IN(void);                //*    SDA 设置为输⼊
41
42void delay_us(uint32_t i);        //*延时
43
44#endif
/*****************************************************************************
*                                                                                                                                                        *
*                        File:    软件模拟IIC, HAL库版本,标准库也                                                    *
*                                    可⽤,只需要做⼀些相对应修改即可                                                    *
*                                                                                                                                                        *
*****************************************************************************/
#include "iic.h"
/*******************************************************************************
* 函数名        : i2c_stare
* 函数功能        : iic开始信号,SCL⾼电平时,SDA出现⼀个下跳沿表⽰启动信号
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接收数据
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();
return1;    //⽆应答信号
}
}
I2C_SCL_LOW;
delay_us(1);
return0;            //有应答
}
/*******************************************************************************
* 函数名        : i2c_ack
* 函数功能        : iic应答信号
* 输⼊        : ⽆
* 输出        : ⽆
*******************************************************************************/
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 设置为输⼊
* 输⼊        : ⽆
* 输出        : ⽆
*******************************************************************************/
/*    标准库使⽤,修改端⼝引脚可⽤
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库也可⽤,只需要代码做⼀些修改即可!

本文发布于:2024-09-21 11:02:59,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/398855.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   应答   标准   信号   总线
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议