stm32f407VET6 系统学习 day06 窗口看门狗, IIC 通信协议

1.独立看门狗,与窗口看门狗的差别

1. 差别1 : 窗口看门狗, 有上限   0x7F, 有下限 0x40  ,, 独立看门狗只有下限 0

2. 差别2:  时钟源不同,  独立看门狗:LSI     

                                             窗口看门狗    :APB1时钟  分频后得到时钟驱动


2.窗口看门狗配置过程


3.代码

头文件

#ifndef __MY_WWDG_H__
#define __MY_WWDG_H__
#include "stm32f4xx_wwdg.h"
#include "stm32f4xx_gpio.h"
void mywwdg_init(void);

#endif

 .cpp 文件


#include "mywwdg.h"

void mywwdg_init()
{
    NVIC_InitTypeDef NVIC_InitStruct;
    // 使能看门狗时钟: RCC_APB1PeriphClockCmd();
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
    //设置分频系数:     WWDG_SetPrescaler();
    WWDG_SetPrescaler(WWDG_Prescaler_8);
    //设置上窗口值:
    WWDG_SetWindowValue(0x6f);
    //开启提前唤醒中断并分组
   
    NVIC_InitStruct.NVIC_IRQChannel = WWDG_IRQn ;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    
    NVIC_Init(&NVIC_InitStruct);
    	//6清除提前唤醒中断标志位:防止提前进入中断函数中。
	WWDG_ClearFlag();
     WWDG_EnableIT();
    // 使能看门狗:
    WWDG_Enable(0X7F);
    
}

void WWDG_IRQHandler()
{
    WWDG_SetCounter(0x5f);
    WWDG_ClearFlag();
    
}

4.IIC 的通信协议

基础知识:l2C(Inter-Integrated Circuit)总线是一种由Philips公司开发的两线式串行总线,用于连接微控制器及其外围设备。I2C总线产生于在80年代,由于其简单性,2C总线被非常广泛地应用在EEPROM(指带电可擦可编程只读存储器)、实时钟、小型LCD等设备与CPU的接口中。

I2C总线是一种用于Ic器件之间连接的双向二线制总线,所谓总线,是指它上面可以挂多个器件,并且通个两根线连接,占用空间非常的小。

I2C总线有两根信号线,一根为SDA(数据线),一根为SCL(时钟线)。任何时候时钟信号都是由主控器件产生,读取I2c从控器的数据或向I2C从控器写入数据。l2C总线实现设备通信的框图如下:



5.IIC .的信号内容  (状态, 与信号)

1. 空闲状态 : I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。

2.起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。


3.停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是—种电平跳变时序信号,而不是一个电平信号。

4. 应答信号: 当我们的主机把时钟信号拉高之后,  从机把数据总线的电平变为低电平, 主机收到这个低电平的信号。

5. 当我们的主机把时钟信号拉高之后,  从机把数据总线的电平变为高电平, 主机收到这个高电平的信号。


6.IIC 主机发送数据

发送数据的流程:

 两种情况:

1. 主机发送 一个信号表明自己要发送数据给这个从机 (7 个地址)

2.  主机发送 一个信号表明自己要接收数据从这个从机(7个地址)这里。

数据格式:

1. 第一个 主句发送起始信号

2. 第二个发送  从机的7 为的地址信号 和一位的 读写信号(判断主机  收数据,还是接收数据)

3. 从机应答

4. 第一种情况: 主机发送数据从机应答, 第二种情况: 从机发送数据主句应答。


7.代码:

头文件:

#ifndef __MY_IIC_H__
#define __MY_IIC_H__
#include "stm32F4xx.h"

#define SCL_HIGH()  GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define SDA_HIGH()  GPIO_SetBits(GPIOB,GPIO_Pin_7)

#define SDA_LOW()  GPIO_ResetBits(GPIOB,GPIO_Pin_7)

#define SCL_LOW()  GPIO_ResetBits(GPIOB,GPIO_Pin_6)

void IIC_Init(void);

//起始信号
void IIC_Start(void);

//停止信号
void IIC_Stop(void);

//发送应答信号
void IIC_Ack(void);

//接收应答信号
u8 IIC_Wait_Ack(void);
//发送非应答信号
void IIC_NAck(void);

//发送一个字节数据
void IIC_Send_Byte(u8 sendData);

//读取数据线的高低电平
u8 READ_SDA(void);

//输入输出
void SDA_IN(void);

void SDA_OUT(void);
#endif

.cpp 文件

#include "myii.h"
#include "stm32f4xx_rcc.h"
#include "mysystick.h"
// PB6---SCL   PB7---SDA
void IIC_Init()
{
    GPIO_InitTypeDef GPIO_InitStruct ;
    
    //第一步:AHB1总线上的E组引脚时钟使能;(心脏开始跳动)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

    //设置gpio结构体
   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7  ;   //控制哪一个引脚  PE8
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // 设置引脚为输出
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //设置输出速度
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;   //推挽方式
   GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;  //设置高电平还是低电平
    //设置GPIO口寄存器数据
   GPIO_Init(GPIOE,&GPIO_InitStruct);
   GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}

//起始信号
void IIC_Start()
{
    //设置输出模式
    SDA_OUT();
    //一开始两根线拉高,空闲
    SDA_HIGH();
    SCL_HIGH();
    delay_us(2);
    //数据线产生下降沿,低电平
    SDA_LOW();
    delay_us(2);
    //把时钟线拉低
    SCL_LOW();  
    
}

//停止信号
void IIC_Stop()
{
    //设置输出模式
    SDA_OUT();
    //一开始低电平 数据无效
    SDA_LOW();
    SCL_LOW();
    //时钟线拉高 使在高电平的时候有上升沿
    delay_us(2);
    SCL_HIGH();
    delay_us(2);
    //产生上升沿
    SDA_HIGH();
    delay_us(2);
}

//发送应答信号
void IIC_Ack(void)
{
    //先设置输出模式
    SDA_OUT();
    //时钟线拉低
    SCL_LOW();
    delay_ms(2);
    //发送应答信号
    SDA_LOW();
    delay_ms(2);
    //时钟线拉高,在高电平期间保持SDA稳定
    SCL_HIGH();
    delay_ms(2);
    //拉低,数据线无效
    SCL_LOW();
    
}

//发送非应答信号
void IIC_NAck()
{
   //先设置输出模式
    SDA_OUT();
    //时钟线拉低
    SCL_LOW();
    delay_ms(2);
    //发送应答信号
    SDA_HIGH();
    delay_ms(2);
    //时钟线拉高,在高电平期间保持SDA稳定
    SCL_HIGH();
    delay_ms(2);
    //拉低,数据线无效
    SCL_LOW();
}

//发送一个字节数据
void IIC_Send_Byte(u8 sendData)
{
    u8 i = 0;
    //先设置成输出模式
    SDA_OUT();
    //时钟线拉低
    SCL_LOW();
    for(i = 0; i < 8;++i)
    {
        if(sendData& 0x80)
        {
            SDA_HIGH();
        }
        else
        {
            SDA_LOW();
        }
        sendData <<= 1;
        delay_ms(2);
        //时钟线拉高 开始发数据
        SCL_HIGH();
        delay_ms(2);
        //数据发送完成后,时钟线拉低
        SCL_LOW();
    }
}


u8 IIC_Wait_Ack(void)
{
    u8  count =0;
    //设置输入模式
    SDA_IN();
    //数据线拉高
    SCL_HIGH();
    delay_ms(2);
     //时钟线拉高
    SDA_HIGH();
    delay_ms(2);
   
    //读SDA线高电平还是低电平
    while(READ_SDA() != 0)
    {
        count++;
        if(count > 250)
        {
            IIC_Stop();
            return 1;
        }
    }
    SCL_LOW();
    //时钟线拉低
    return 0;
}

//读取数据线的高低电平
u8 READ_SDA(void)
{
    u8 val = 0;
    val= GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
    return val;
}

//输入输出
void SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStruct ;
    
    //第一步:AHB1总线上的E组引脚时钟使能;(心脏开始跳动)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

    //设置gpio结构体
   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7  ;   //控制哪一个引脚  PE8
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; // 设置引脚为输出
   GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;  //设置高电平还是低电平
    //设置GPIO口寄存器数据
   GPIO_Init(GPIOE,&GPIO_InitStruct);
   GPIO_SetBits(GPIOB,GPIO_Pin_7);
}

void SDA_OUT(void)
{
 GPIO_InitTypeDef GPIO_InitStruct ;
    
    //第一步:AHB1总线上的E组引脚时钟使能;(心脏开始跳动)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

    //设置gpio结构体
   GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7  ;   //控制哪一个引脚  PE8
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // 设置引脚为输出
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //设置输出速度
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;   //推挽方式
   GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_UP;  //设置高电平还是低电平
    //设置GPIO口寄存器数据
   GPIO_Init(GPIOE,&GPIO_InitStruct);
   GPIO_SetBits(GPIOB,GPIO_Pin_7);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值