STM32 模拟IIC完整代码

发布者:莫愁前路最新更新时间:2019-04-02 来源: eefocus关键字:STM32  模拟IIC 手机看文章 扫描二维码
随时随地手机看文章

void IIC_Init(void)

{      

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );

   

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

 

IIC_SCL=1;

IIC_SDA=1;

 

}

//产生IIC起始信号

void IIC_Start(void)

{

SDA_OUT();     //sda线输出

IIC_SDA=1;     

IIC_SCL=1;

delay_us(4);

  IIC_SDA=0;//START:when CLK is high,DATA change form high to low 

delay_us(4);

IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 

}   

//产生IIC停止信号

void IIC_Stop(void)

{

SDA_OUT();//sda线输出

IIC_SCL=0;

IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

  delay_us(4);

IIC_SCL=1; 

IIC_SDA=1;//发送I2C总线结束信号

delay_us(4);    

}

//等待应答信号到来

//返回值:1,接收应答失败

//        0,接收应答成功

u8 IIC_Wait_Ack(void)

{

u8 ucErrTime=0;

SDA_IN();      //SDA设置为输入  

IIC_SDA=1;delay_us(1);    

IIC_SCL=1;delay_us(1);  

while(READ_SDA)

{

ucErrTime++;

if(ucErrTime>250)

{

IIC_Stop();

return 1;

}

}

IIC_SCL=0;//时钟输出0    

return 0;  

//产生ACK应答

void IIC_Ack(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=0;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

//不产生ACK应答     

void IIC_NAck(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}      

//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答   

void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

SDA_OUT();     

    IIC_SCL=0;//拉低时钟开始数据传输

    for(t=0;t<8;t++)

    {              

        IIC_SDA=(txd&0x80)>>7;

        txd<<=1;   

delay_us(2);   //对TEA5767这三个延时都是必须的

IIC_SCL=1;

delay_us(2); 

IIC_SCL=0;

delay_us(2);

    }  

}     

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

u8 IIC_Read_Byte(unsigned char ack)

{

unsigned char i,receive=0;

SDA_IN();//SDA设置为输入

  for(i=0;i<8;i++ )

{

    IIC_SCL=0; 

    delay_us(2);

IIC_SCL=1;

    receive<<=1;

    if(READ_SDA)receive++;   

delay_us(1); 

  }  

if (!ack)

IIC_NAck();//发送nACK

else

IIC_Ack(); //发送ACK   

return receive;

}

 

void I2C_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr)

{

IIC_Start();  


if(device_addr==0xA0) //eeprom地址大于1字节

IIC_Send_Byte(0xA0 + ((addr/256)<<1));//发送高地址

else

IIC_Send_Byte(device_addr);     //发器件地址

IIC_Wait_Ack(); 

IIC_Send_Byte(addr&0xFF);   //发送低地址

IIC_Wait_Ack(); 

IIC_Send_Byte(data);     //发送字节    

        IIC_Wait_Ack();         

        IIC_Stop();//产生一个停止条件 

if(device_addr==0xA0) //

delay_ms(10);

else

delay_us(2);

}

 

uint16_t I2C_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead)  //读寄存器或读数据

{

uint16_t data;

IIC_Start();  

if(device_addr==0xA0)

IIC_Send_Byte(0xA0 + ((addr/256)<<1));

else

IIC_Send_Byte(device_addr);

IIC_Wait_Ack();

IIC_Send_Byte(addr&0xFF);   //发送低地址

IIC_Wait_Ack(); 

 

IIC_Start(); 

IIC_Send_Byte(device_addr+1);     //发器件地址

IIC_Wait_Ack();

if(ByteNumToRead == 1)//LM75温度数据为11bit

{

data=IIC_Read_Byte(0);

}

else

{

data=IIC_Read_Byte(1);

data=(data<<8)+IIC_Read_Byte(0);

}

IIC_Stop();//产生一个停止条件     

return data;

}


头文件


//使用IIC1 挂载M24C02,OLED,LM75AD,HT1382    PB6,PB7

 

#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}

#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

 

//IO操作函数  

#define IIC_SCL    PBout(6) //SCL

#define IIC_SDA    PBout(7) //SDA  

#define READ_SDA   PBin(7)  //输入SDA 

 

//IIC所有操作函数

void IIC_Init(void);                //初始化IIC的IO口  

void IIC_Start(void); //发送IIC开始信号

void IIC_Stop(void);   //发送IIC停止信号

void IIC_Send_Byte(u8 txd); //IIC发送一个字节

u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节

u8 IIC_Wait_Ack(void); //IIC等待ACK信号

void IIC_Ack(void); //IIC发送ACK信号

void IIC_NAck(void); //IIC不发送ACK信号

 

void I2C_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr);

uint16_t I2C_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead);//寄存器地址,器件地址,要读的字节数 


下图为实际运行效果

关键字:STM32  模拟IIC 引用地址:STM32 模拟IIC完整代码

上一篇:stm32 I2C自收发测试例程
下一篇:Gpio模拟i2c总线对24c02进行读写

推荐阅读最新更新时间:2024-03-16 16:26

一文详解GD32单片机和STM32单片机
一、GD32单片机的概念、工作原理及内部结构 1.概念 GD32单片机是中国龙芯集成电路公司推出的一款ARM Cortex-M3内核的微控制器。它具有与STM32单片机相同的架构和指令集,但是价格相比STM32更为便宜。同时,GD32单片机有着更高的品质和可靠性,成为一个理想的低成本单片机解决方案。 2.工作原理 GD32单片机的工作原理基于时钟周期,其中时钟周期是单片机执行机器指令的重要组成部分。单片机中的每个时钟周期都包含多个时钟周期,每个时钟周期都可以执行一组基本指令。这些指令对应于单片机内部的不同部分,例如处理器、总线、存储器、IO等。 3.内部结构 GD32单片机的内部结构包含三个主要元件:处理器、存储器和输
[单片机]
STM32学习记录8:DMA
官方的例子:STM32F10x_StdPeriph_Lib_V3.1.2\Project\STM32F10x_StdPeriph_Examples\DMA\FLASH_RAM /* DMA1 channel6 configuration */ DMA_DeInit(DMA1_Channel6); //peripheral base address 外设地址是自己的一个定义 //例如#define SPI1_DR_Addr ( (u32)0x4001300C ) DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer; //memory base
[单片机]
<font color='red'>STM32</font>学习记录8:DMA
STM32菜鸟成长记录---GPIO的使用
#include stm32f10x_lib.h #include stm32f10x.h GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO宏操作结构体 void Delay(__IO uint32_t nCount)//__IO的宏定义volatile { for(; nCount != 0; nCount--); } /*初始化嵌入式Flash接口,初始化PLL使其达到系统可用频率*/ void RCC_Configuration(void) { /* Setup the microcontroller system. Initialize the Embedd
[单片机]
<font color='red'>STM32</font>菜鸟成长记录---GPIO的使用
STM32_DAC之软件触发
stm32_DAC可以用来输出固定的电压值,有些时候需要按键可调输出的电压值。其中一种方法是使用外部中断EXTI9, 另外一种方法就是使用软件触发。 如果将DAC_InitTypeDef.DAC_Trigger设置为DAC_Trigger_None, 那么,不需要其他任何的触发源,直接使用DAC_SetChannelxData(),就可以设定输出电压的大小。如果使用了软件触发,那么,每次在使用DAC_SetChannelxData()修改输出电压后,还需要调用DAC_SoftwareTriggerCmd(),目的是使能软件触发。由于:软件触发是硬件在一个APB1时钟周期后自动关断的,于是,每次修改输出电压的值后,都要调用DAC
[单片机]
STM32系列第10篇--看门狗
看门狗的作用: 在启动正常运行的时候,系统不能复位。 在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行 STM32有两个看门狗: 独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。 窗口看门狗由从APB1时钟分频后得到时钟驱动。通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作。 窗口看门狗最适合那些要求看门狗在精确计时窗口起作用的程序。 看门狗一般用法: while(1) { 喂狗; if(定时标识) { 里面就是按键程序; } }12345678 计算一下,主循环执
[单片机]
STM32 FSMC 详解
LCD有如下控制线: CS:Chip Select 片选,低电平有效 RS:Register Select 寄存器选择 WR:Write 写信号,低电平有效 RD:Read 读信号,低电平有效 RESET:重启信号,低电平有效 DB0-DB15:数据线 假如这些线,全部用普通IO口控制。根据LCD控制芯片手册(大部分控制芯片时序差不多): 如果情况如下: DB0-DB15的IO全部为1(表示数据0xff),也可以为其他任意值,这里以0xff为例。 CS为0(表示选上芯片,CS拉低时,芯片对传入的数据才会有效) RS为1(表示DB0-15上传递的是要被写到寄存器的值),如果为0,表示传递的是数据。(这里原作者应该是搞反了,应该是
[单片机]
单片机与计算机通信(上位机)——基于VS2017和stm32
**程序说明:**VSwin32命令控制台程序 调用串口,可以根据自己需要配置串口,完成windows与单片机的数据传输。可作为开发参考使用。 直接先贴代码 //32与单片机通信,差不多成功了 #include iostream #include cstdlib #include windows.h #include stdlib.h using namespace std; HANDLE hComm; OVERLAPPED OverLapped; COMSTAT Comstat; DWORD dwCommEvents; char g_UartRxBuffer = { 0x0d,1,2,3,4,0x
[单片机]
单片机与计算机通信(上位机)——基于VS2017和<font color='red'>stm32</font>
基于STM32控制的声音导引系统
摘要:设计了一个基于STM32控制的声音导引系统。该系统由1个可移动声源S和3个声音接收器A、B、C构成。由一片从控STM32单片机控制无线发送模块,实现声音导引信号的发送。主控单片机根据无线接收模块所接收到的信息来判断可移动声源运动的启停。 关键词:无线收发模块;STM32单片机;声音导引;移动声源 引言 声音导引系统,主要是靠声音来完成对机器的智能控制,既方便又快捷。尤其是环境比较恶劣、不适合人类停留的地方,可以依靠声音来控制机器的正常运行。声音导引系统也是智能化控制的一个方面,对未来的智能化发展有较大的促进作用,对未来智能机器人的研究也大有帮助。 1 系统总体方案 如图1所示,声音导引系统由1个可移动声源S,声音
[单片机]
基于<font color='red'>STM32</font>控制的声音导引系统
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved