基于I2C及Ardunio的简单通信实验

一、I2C总线通信协议

a. I2C概述

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。

它只需要两根线即可在连接于总线上的器件之间传送信息。

I2C 通讯协议由于引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。

I2C协议包括“软件I2C”和“硬件I2C”

b. 软件I2C

将芯片的两个GPIO引脚分别用作SCL及SDA,按照I2C的时序要求,直接控制引脚的输出信号(若是接收数据时则读取 SDA 电平),就可以实现I2C通讯。由于是直接控制GPIO引脚的高低电平产生通讯时序,需要由CPU控制每个时刻的引脚状态,所以称为“软件模拟协议”方式即软件I2C方式。

c. 硬件I2C

硬件I2C对应芯片上的I2C外设,具有相应的I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C,但是程序较为繁琐。硬件I2C是直接调用内部寄存器进行配置。

如何区分软件I2C和硬件I2C

可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC,否则就是模拟。

可以看IIC写函数,看里面有没有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。

根据代码量判断,模拟的代码量肯定比固件的要大。

二、AHT20温湿度数据

实验代码及串口要求参考网址:

链接: https://github.com/Thee24LYJ/STM32_AHT20.

在这里插入图片描述
连接好之后如图所示:

打开下载的代码:

在这里插入图片描述
修改main.c:

#include "led.h"
#include "delay.h"
#include "temhum.h"
#include "sys.h"
#include "usart.h"

 int main(void)
 {	 	
    u32 CT_data[2]={0};
    volatile float  hum=0,tem=0;     
     
    delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 //串口初始化为115200
    LED_Init();			     //LED端口初始化
    temphum_init();     //ATH20初始化    
	
	while(1)
	{
        AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据 

        hum = CT_data[0]*100*10/1024/1024;  //计算得到湿度值(放大了10倍)
        tem = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)

        printf("湿度:%.1f%%\r\n",(hum/10));
        printf("温度:%.1f度\r\n",(tem/10));
        printf("\r\n");
        
        //延时2s,LED闪烁提示串口发送状态
        LED=0;
        delay_ms(1000);
        LED=1;
        delay_ms(1000);
	 }
}


生成.hex文件之后烧录:(烧录过程参考前面博客)

在这里插入图片描述

三、基于Ardunio的STM32板的串口通信程序

安装Ardunio

在这里插入图片描述
将Arduino_STM32文件夹复制到hareware下:

在这里插入图片描述
打开软件,在工具中找到开发板,选择Generic STM32F103V series(指南者)
依次进行如下操作:

在这里插入图片描述
CPU不管(默认72MHz)

在这里插入图片描述
之后连接到开发板:

1.USB线连接到"USB转串口";
2.用黄色跳帽将BOOT0与3v3相连,BOOT1与GND相连,RXD与A9相连,TXD与A10相连;

将以下代码替换掉图中:

在这里插入图片描述
下面展示一些 内联代码片

int flag=1;   
char Stop[]="stop\n";
void setup() {
//初始化
pinMode(PB0, OUTPUT);//PB0为绿色,PB1为蓝色,PB5为红色,可根据需要改动
Serial.begin(115200);
}
void loop() {
int i=0,flag_s=0;
char inByte[50];
digitalWrite(PB0, HIGH); //小灯亮
delay(500); // 延迟
digitalWrite(PB0, LOW); //小灯灭
delay(500); // 延迟
while (Serial.available()> 0)     //当发送缓冲区有数据时
{
        inByte[i] = Serial.read();    //从串口的缓冲区取出并读取一个Byte的数据
        delay(10); 
        i++ ;                              
}
if(Stop[i]=inByte[i])
{
  if(Stop[i-1]==inByte[i-1]&&Stop[i-2]==inByte[i-2]&&Stop[i-3]==inByte[i-3])
  {
  flag=0;
  Serial.println("收到!");
  }//当收到stop命令时停止并回复收到
}
if(flag==1)
{  
Serial.println("Hello World!");//向串口发送数据
delay(100); // 延迟
}
}

点击工具中选择串口;

再依次点击如图所示按钮:

在这里插入图片描述
再在工具中打开串口监视器:

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Arduino ESP32 中,可以使用软串口(SoftwareSerial)库来实现串口通信。软串口是通过软件模拟的串口,可以通过任意两个 GPIO 引脚来实现串口通信。 下面是一个示例代码,演示了如何使用软串口在 ESP32 上进行串口通信: ```c++ #include <SoftwareSerial.h> // 设置软串口的引脚 SoftwareSerial mySerial(2, 3); // RX, TX void setup() { Serial.begin(9600); // 打开硬串口,用于调试输出 mySerial.begin(9600); // 打开软串口 } void loop() { if (mySerial.available()) { // 如果软串口有数据可读 char c = mySerial.read(); // 读取一个字符 Serial.print(c); // 在硬串口上输出字符 } if (Serial.available()) { // 如果硬串口有数据可读 char c = Serial.read(); // 读取一个字符 mySerial.write(c); // 在软串口上发送字符 } } ``` 在上面的代码中,我们使用了引脚 2 和 3 作为软串口的 RX 和 TX 引脚,分别连接到另一个串口设备。在 `setup()` 函数中,我们打开了硬串口和软串口,分别用于调试输出和串口通信。 在 `loop()` 函数中,我们使用了 `mySerial.available()` 和 `Serial.available()` 函数来检查软串口和硬串口是否有数据可读。如果有数据可读,我们就使用 `mySerial.read()` 和 `Serial.read()` 函数来读取数据,并通过 `mySerial.write()` 和 `Serial.print()` 函数来发送和输出数据。 需要注意的是,在使用软串口时,需要确保 RX 和 TX 引脚不会被其他设备占用。此外,软串口的波特率需要与另一个串口设备的波特率相同,否则数据可能无法正确传输。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值