嵌入式单片机基础篇(三十四)之I2C通信以及stm32单片机程序详解

I2C通信以及stm32单片机程序详解

1、初始化IO口:

#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //输入SDA 

(1)在固件库中操作IDR寄存器读取IO端口数据是通过GPIO_ReadInputDataBit函数实现的:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
比如 要读GPIOA.5的电平状态,那么方法是: GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
返回值是1(Bit_SET)或者0(Bit_RESET);
在STM32固件库中,通过BSRR和BRR寄存器设置GPIO端口输出是通过函数 GPIO_SetBits()和函数GPIO_ResetBits()来完成的。
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) ;
在多数情况下,都是采用这两个函数来设置GPIO端口的输入和输出状态。
比如要设置GPIOB.5输出1,方法为:
GPIO_SetBits(GPIOB, GPIO_Pin_5);
如果要设置GPIOB.5输出0,方法为:
GPIO_ResetBits (GPIOB, GPIO_Pin_5);
(2)位带操作:
宏定义:
#define LED0 PBout(5)
#define LED1 PEout(5)

位带操作来实现操作某个IO口的1个位,通过位带操作PB5输出高低电平的方法如下:
LED0=1; //通过位带操作控制引脚PB5输出高电平
LED0=0; //通过位带操作控制引脚PB5输出低电平
比如,要PORTA的第七个IO口输出1,PAout(6)=1;
要判断PORTA的第15个位是否等于1,则可以使用if(PAin(14)==1)…;

void IIC_Init(void)
{
   					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟   
	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);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
}

2、初始化时钟线SCL与数据线SDA,此时可以看到这两个引脚都是输出引脚,根据I2C通信协议可知:SDA信号线上不仅仅只输出信号,有时也有输入信号,也就是说SDA信号线的引脚有时需要配置成输出,有时需要配置成输入,程序如下:

void IIC_setSDAMode_Out(void)
{
   
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //PB7推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void IIC_setSDAMode_In(void)
{
   
  GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU ;   //推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

3、信号线的引脚初始化状态配置好后,开始写I2C通信协议,程序如下:
(1)起始信号:

void IIC_Start(void)
{
   
	IIC_setSDAMode_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总线,准备发送或接收数据 
}	

注意:起始信号产生后,SCL信号线为低电平状态
(2)写单字节函数:

void IIC_Send_Byte(u8 txd)
{
                           
    u8 t;   
	IIC_setSDAMode_Out(); 	    
    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);
    }	 
} 	

注意:写单字节函数完成后,SCL信号线为低电平状态
(3)读单字节函数:

u8 IIC_Read_Byte()
{
   
	unsigned char i,receive=0;
    IIC_setSDAMode_In();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
   
       IIC_SCL=1; 
	   receive<<=1;
	   receive|=(unsigned char)READ_SDA; 
	   IIC_SCL=0;
       delay_us(2);
    }					 
       return receive;
}

注意:读单字节函数完成后,SCL信号线为低电平状态
(4)应答信号:

u8 IIC_Wait_Ack(void)
{
   
	u8 a;
	IIC_setSDAMode_In();      //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32单片机是一种非常流行的嵌入式系统,它可以用C语言进行编程。下面是一些STM32单片机C语言程序的知识点详解: 1. 数据类型:C语言中的数据类型包括整型、浮点型、字符型等。在STM32单片机程序中,需要注意变量的长度,因为单片机的处理速度相对较慢,所以使用最小的数据类型可以提高程序的运行速度。 2. 循环结构:循环结构在STM32单片机程序中非常常见,可以使用for、while、do-while等循环结构。需要注意的是,在使用循环结构时需要特别小心,避免死循环。 3. 条件语句:条件语句通常用于根据某些条件执行不同的代码。在STM32单片机程序中,可以使用if、else if、else等条件语句。 4. 数组:数组是一组连续的内存空间,可以用来存储多个相同类型的数据。在STM32单片机程序中,数组非常常见,可以用来存储传感器数据、控制信号等。 5. 函数函数是一段可以重复调用的代码,可以接受参数并返回值。在STM32单片机程序中,函数的使用非常广泛,可以用来实现各种不同的功能模块。 6. 指针:指针是一个变量,它存储了一个内存地址。在STM32单片机程序中,指针可以用来访问某些特定的内存地址,例如外设寄存器等。 7. 中断:中断是一种特殊的程序执行方式,它可以在程序运行的任何时候中断当前的执行流程,执行一段特定的代码。在STM32单片机程序中,中断可以用来处理外部事件,例如按键输入、定时器超时等。 以上是一些STM32单片机C语言程序的知识点详解,掌握这些知识点可以帮助你更好地编写STM32单片机程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值