树莓派4b的i2c配置及wiringPi通信

一、配置i2c设备
1)在终端中操作,输入指令

sudo raspi-config

2)然后会出现设置界面,然后跟着如下图片操作
树莓派4b的i2c配置及wiringPi通信_第1张图片
第一项:Change User Password: 更改用户登录密码,也就是登录树莓派的raspberry 密码。点击进入就可以设置新的登陆密码。

第二项:Network Options : 网络设置, 打开这个设置后可以连接wifi,设置机器名称 ,接口启用禁止等

第三项:Boot Options : 启动时选择进入的环境(命令模式/图形化模式)

**第四项:Localisation Options :**本地化设置包含:language语言设 置/Timezone时区设置/Keyboard键盘布局/wifi country 无线wif国家设置。

第五项:Interfacing Options : 系统功能设置,包含Camera摄像头启用 / SSH启用/VNC启用/SPI启用/I2C启用/serial启用/wire/GPIO 需要用到哪些就开启哪些功能

第六项:Overclock : 超频会减少树莓派使用寿命,正常情况下不建议超频使用。

第七项: Advanced Options : 高级设置,包含扩展TF卡使用空间/显示器overscan’设置/memorySplit设置/Audio音频输出设置/分辨率设置/等等

**第八项:Update :**系统更新,用于升级更新系统

第九项:About raspi-cofnig : 关于设置的系统
树莓派4b的i2c配置及wiringPi通信_第2张图片
树莓派4b的i2c配置及wiringPi通信_第3张图片
最后选择“是”
3)i2c总线扫描
通过i2cdetect -l指令可以查看树莓派上的I2C总线,从返回的结果来看树莓派含有两个I2C总线,通过阅读相关的资料,树莓派1代使用I2C0,而树莓派2代使用I2C1。

pi@raspberrypi:~/wiringPi $ i2cdetect -l
i2c-1   i2c             bcm2835 I2C adapter                     I2C adapter

4)i2c设备查询
若总线上挂载I2C从设备,可通过i2cdetect扫描某个I2C总线上的所有设备。

i2cdetect -y 1

树莓派4b的i2c配置及wiringPi通信_第4张图片
我挂在i2c总线上的是stm32的硬件i2c,从机地址设置为0x50(即0x28<<1)
二、通信代码指令
1、树莓派4b调用wiringPi库

#include "stdio.h"
#include "wiringPi.h"
#include "wiringPiI2C.h"
#include "pthread.h"
#include "unistd.h"

void *pthread_fun(void *arg)
{
	int fd = *((int*)arg);	
	int Tx_buf = 12;
	while(1)
	{
	    wiringPiI2CWrite(fd, Tx_buf);
	    sleep(1);
	}
	return NULL;
}

int main(int argc, char *argv[])
{
	int fd, err;
	int Rx_buf;
	pthread_t tid;

	//对wiringPi初始化
	if(wiringPiSetup() != 0)
	{
		printf("wiringPi error!\n");
		return -1;
	}
	
	//指定i2c从机设备,并初始化i2c
	fd = wiringPiI2CSetup(0x28);
	if(fd < 0)
	{
		printf("wiringPiI2CSetup error!\n");
		return fd;
	}
	
	err = pthread_create(&tid, NULL, pthread_fun, &fd);
	if(err != 0)
	{
		printf("create pthread error\n");	
		return -2;
	}

	while(1)
	{
		Rx_buf = 0;
		//读取数据
		Rx_buf = wiringPiI2CRead(fd);

		//判断是否读取成功
		if(Rx_buf != 0)
			printf("Temperature is %d ℃\n", Rx_buf);

		sleep(1);
	}
	
	return 0;
}

2、STM32F103硬件i2c代码

/*********************************************************************************************************
* 模块名称: iic.c
* 摘    要: 硬件IIC从机实验
* 当前版本: 1.0.0
* 作    者: 杨
* 完成日期: 2019年4月19日
* 内    容:
* 注    意:                                                               
**********************************************************************************************************
* 取代版本: 
* 作    者:
* 完成日期: 
* 修改内容:
* 修改文件: 
*********************************************************************************************************/

/*********************************************************************************************************
*                                              包含头文件
*********************************************************************************************************/
#include "iic.h"

/*********************************************************************************************************
*                                              宏定义
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部变量
*********************************************************************************************************/
u8 IIC1_Rx_Buff = 0;
u8 IIC1_Tx_Buff = 67;

//#define SIZE2 sizeof(IIC1_Tx_Buff)
uint32_t state;
/*********************************************************************************************************
*                                              内部函数声明
*********************************************************************************************************/

/*********************************************************************************************************
*                                              内部函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称:  
* 函数功能: 
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 创建日期:  
* 注 意:   
*********************************************************************************************************/ 

/*********************************************************************************************************
*                                              API函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称: InitI2C1
* 函数功能: 初始化I2C1
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日 
* 注    意: PB6:SCL; PB7:SDA
*********************************************************************************************************/ 
void InitI2C1(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  I2C_InitTypeDef I2C_InitStruct;
  NVIC_InitTypeDef NVIC_InitStruct;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  
  //GPIO配置
  GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_OD;         //设置为复用开漏输出,实现iic的线与逻辑
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
  
  //I2C1配置
  I2C_InitStruct.I2C_Ack                 = I2C_Ack_Enable; //使能ack
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7位设备地址
  I2C_InitStruct.I2C_DutyCycle           = I2C_DutyCycle_2;//占空比为1/2              
  I2C_InitStruct.I2C_ClockSpeed          = 100000;         //时钟频率为100k
  I2C_InitStruct.I2C_Mode                = I2C_Mode_I2C;
  I2C_InitStruct.I2C_OwnAddress1         = 0x50;           //设置硬件从机地址
  I2C_Init(I2C1, &I2C_InitStruct);
  
  //NVIC配置
  NVIC_InitStruct.NVIC_IRQChannel                   = I2C1_EV_IRQn;   //事件中断
  NVIC_InitStruct.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStruct.NVIC_IRQChannelSubPriority        = 0;
  NVIC_Init(&NVIC_InitStruct);
  
  NVIC_InitStruct.NVIC_IRQChannel                   = I2C1_ER_IRQn;   //错误中断
  NVIC_InitStruct.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStruct.NVIC_IRQChannelSubPriority        = 0;
  NVIC_Init(&NVIC_InitStruct);
  
  I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR | I2C_IT_BUF, ENABLE);
  I2C_Cmd(I2C1, ENABLE);
}

/*********************************************************************************************************
* 函数名称: I2C1_EV_IRQHandler
* 函数功能: I2C1事件中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日 
* 注    意: 
*********************************************************************************************************/
void I2C1_EV_IRQHandler(void)
{ 
  //static u8 s_iRdata;
  //static u8 s_iTdata;
  
  state = I2C_GetLastEvent(I2C1);
  switch(state)
  { 
    //EV1(receive)(从机匹配地址成功)
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: 
       I2C_ReadRegister(I2C1, I2C_Register_SR1);   //读取SR1
       I2C_ReadRegister(I2C1, I2C_Register_SR2);   //读取SR2后,硬件自动将SR1->ADDR清零
       //s_iRdata = 0;
       break;
    
    //EV2(Byte received)
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:
			 IIC1_Rx_Buff = I2C_ReceiveData(I2C1);//读取DR寄存器硬件将自动将SR1->RxNE清零
       //IIC1_Rx_Buff[s_iRdata] = I2C_ReceiveData(I2C1);//读取DR寄存器硬件将自动将SR1->RxNE清零
       //s_iRdata++;
       break;
    
    //EV4(stop) 
    case I2C_EVENT_SLAVE_STOP_DETECTED:
       I2C_ReadRegister(I2C1, I2C_Register_SR1);   //读取SR1
       I2C1->CR1 |= 0x0001;                        //写CR1->PE为1,启动I2C1
       break;
    
    //EV1(transmitter)
    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
       I2C_ReadRegister(I2C1, I2C_Register_SR1);   //读取SR1
       I2C_ReadRegister(I2C1, I2C_Register_SR2);   //读取SR2后,硬件自动将SR1->ADDR清零
       //s_iTdata = 0;  
       break;
    
    //EV3、EV3-1(Byte transmit)
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
       //I2C_SendData(I2C1, IIC1_Tx_Buff[s_iTdata++]); //写I2C->DR后硬件将自动清除TxE位
			 I2C_SendData(I2C1, IIC1_Tx_Buff); //写I2C->DR后硬件将自动清除TxE位
       break;
    
    //EV3-2 
    case I2C_EVENT_SLAVE_ACK_FAILURE:
       I2C1->SR1 &= 0xFBFF;           //写SR1->AF = 0以清除AF位
       break;
    default:
       break;
  }
}

/*********************************************************************************************************
* 函数名称: I2C1_ER_IRQHandler
* 函数功能: I2C1错误中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日 
* 注    意: 
*********************************************************************************************************/
void I2C1_ER_IRQHandler(void) 
{  
  if(I2C_GetITStatus(I2C1, I2C_IT_SMBALERT))
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_TIMEOUT);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_PECERR))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_PECERR);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_OVR))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_OVR);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_AF))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_ARLO))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_ARLO);
  }
  else if(I2C_GetITStatus(I2C1, I2C_IT_BERR))  
  {
    I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
  }
  I2C1->CR1 |= 0x0001;       //启动I2C1
  I2C1->SR1 = 0;
  I2C1->SR2 = 0;
}


3、编译运行结果

编译

pi@raspberrypi:~/wiringPi $ gcc i2c_wiringPi.c -o i2c_wiringPi -lpthread -lwiringPi
pi@raspberrypi:~/wiringPi $ ./i2c_wiringPi

运行结果

在这里插入图片描述
树莓派4b的i2c配置及wiringPi通信_第5张图片

你可能感兴趣的:(树莓派,树莓派4b,i2c,stm32,i2c配置,wiringPi)