0%

stm32_note_12day

===========================
2022-8-30
===========================

一.温故知新

    USART1的驱动
    初始化
    发送数据
        发送一个字节数据
        发送多个字节数据
            通过遍历有效数据
            把数据按照一个字节一个字节的方式进行发送
        printf进行重定向(重定向到USART1的发送)
            使用微库
            禁用半主机模式
            以上两种方法都需要重新实现fgetc以及fputc函数
    接收数据
        轮询接收数据
        中断接收数据
            使用有限状态机的方法解析字符串数据

    "+IPD,XX:YYYYYYY"
    XX指的是接收到数据的字节数
    YY指的是真实数据
    "+IPD,12:abcdefghijkl"

#define A_FLAG 0
#define I_FLAG 1
#define P_FLAG 2
#define D_FLAG 3
#define H_FLAG 4
#define M_FLAG 5
#define S_FLAG 6
int flag = A_FLAG;
char bytes[4] = {0};//存储数据的字节数(字符串版本)
int i = 0;//循环变量
int length = 0;//存储数据的字节数(整数版本)
char data[128] = {0};//存储数据

void recv_handler(u8 c)
{
    switch(flag)
    {
        case A_FLAG : 	if(c == '+')
                    flag = I_FLAG;
                break;
        case I_FLAG :	if(c == 'I')
                    flag = P_FLAG;
                else
                    flag = A_FLAG;
                break;
        case P_FLAG :	if(c == 'P')
                    flag = D_FLAG;
                else
                    flag = A_FLAG;
                break;
        case D_FLAG:	if(c == 'D')
                    flag = H_FLAG;
                else
                    flag = A_FLAG;
                break;
        case H_FLAG :	if(c == ',')
                    flag = M_FLAG;
                else
                    flag = A_FLAG;
                break;
        case M_FLAG :	if(c == ':')
                    flag = S_FLAG;
                else
                    bytes[i++] = c;
                break;
        case S_FLAG :	length = atoi(bytes);
                while(length--)
                    data[] = c;
    }
}

二.串口之I²C

    1.I²C的简介
    IIC也称为I2C或者I²C(专业的写法就是I²C),属于串行总线中的一种,
    也是数据按顺序一位一位进行发送
    I²C必须要有两条线(一条是数据线<SDA>、一条是时钟线<SCL>),是半双工的工作模式		
    2.I²C与USART的对比
    USART : 通用的同步异步收发器
    两条数据线(一条是发送、一条是接收)
    属于全双工的工作模式
    由于没有时钟线,所以设备通过USART通信之前需要规定好双方的波特率

    I²C : 集成电路总线
    两条线(一条是数据线<SDA>、一条是时钟线<SCL>)	
    属于半双工的工作模式
    由于有时钟线,可以自行调节读写速率,所以不需要规定双方的比特率

    3.I²C总线协议的目的
    需要驱动开发板上的OLED屏幕、EEPROM、SHT30
    1)需要带着大家把EEPROM的外设驱动起来
    2)需要带着大家把OLED的驱动移植成功
    3)自己想办法驱动SHT30
    
    4.通过官方手册了解I²C的协议
    打开<STM32RBT6\DataSheet\其他>目录下<IIC.pdf>P7 - P14中的图
    1)I²C总线需要两条线(SDA/SCL),在I²C总线上可以连接很多的设备,
        设备与设备之间是串联的关系
    2)凡是连接到I²C总线上的设备都需要有一个设备地址
        注意:一般来说设备地址是7bit的
    --------------------------------------------------------------------------
    面试题
    1.I²C总线理论上可以连接多少个设备?	理论上128个设备(设备地址)
    --------------------------------------------------------------------------
    3)I²C总线进行通信时会分为主设备和从设备
        主设备是主动的,从设备是被动的
        I²C总线本身非常公平,任何连接到I²C总线上的设备都既可以做主也可以做从
        (注意:有些设备由于本身的原因只能做从设备做不了主设备)
        如果两个设备同时都想要通信,会触发抢主的机制
        抢到主的设备优先通信,没抢到主的设备等待通信完成之后,再重新抢主
        (注意:抢主的机制,就是谁先产生开始信号,谁就优先通信)
    4)I²C总线在空闲状态时,SDA和SCL要呈现高电平的状态(需要外接上拉电阻)
    5)开始信号和结束信号
        开始信号 : 在SCL为高电平的时候,SDA由高电平拉到低电平
        结束信号 : 在SCL为高电平的时候,SDA由低电平拉到高电平
    6)传输数据
        1>在SCL为低电平的时候,把数据放到SDA数据线上
        2>拉高SCL,当SCL为高电平的时候,SDA的电平要保持不变
        3>拉低SCL,在SCL为低电平的时候,切换下一位数据放到SDA数据线上
    7)I²C总线是高位先出
    8)I²C总线在传输一个字节数据时需要9个周期
        9个周期 = 8个数据周期 + 1个ACK(应答)周期
    9)I²C总线属于停等式的流控,每发送完一个字节数据都需要有一个ACK应答
    A)产生应答 : 在SCL的第9个周期,SCL拉低,从设备拉低SDA,拉高SCL.延时一段时间
        把SCL拉低,从设备拉高SDA
    B)读取应答 : 在SCL的第9个周期,在SCL为高电平时读取SDA的电平
        如果读取到了高电平代表没有ACK,如果读取到了低电平代表有ACK
    C)I²C总线产生开始信号之后,
        发送的第一个字节内容是 = 7bit设备地址 + 1bit读写标志位
    D)主设备发送数据给从设备
        1>主设备产生开始信号
        2>主设备发送从设备的设备地址 + 写的标志(0)
        3>主设备等待ACK
        4>主设备发送一个字节数据
        5>主设备等待ACK
        ...
        n>主设备发送最后一个字节数据
        n+1>主设备可以等待ACK或者不等待ACK
        n+2>主设备产生结束信号
    E)主设备读取从设备发送的数据
        1>主设备产生开始信号
        2>主设备发送从设备的设备地址 + 读的标志(1)
        3>主设备等待ACK
        4>主设备等待接收一个字节数据
        5>主设备产生ACK
        ...
        n>主设备等待接收最后一个字节数据
        n+1>主设备不需要产生ACK
        n+2>主设备产生结束信号

IIC

02.IIC硬件连接

03.IIC协议要求

04.IIC协议(开始信号结束信号)

05.IIC协议_详细

06.IIC协议_ACK产生

07.IIC_主的编程

开发板上的IIC设备

学生发的笔试题