一、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); // 延迟
}
}
点击工具中选择串口;
再依次点击如图所示按钮:
再在工具中打开串口监视器: