ARMd7 作业

使用GPIO口实现i2c总线控制

i2c.h

#ifndef __I2C_H__
#define __I2C_H__

#define I2C_SDA_OUT     do{GPIOF->MODER &= (~(0x3<<0x1E));  GPIOF->MODER |= (0x1<<0x1E);}while(0)
#define I2C_SDA_IN          do{GPIOF->MODER &= (~(0x3<<0x1E));  }while(0)
#define I2C_SCL_HIGH    do{GPIOF->ODR |= (0x1<<14);}while(0)
#define I2C_SCL_LOW     do{GPIOF->ODR &= (~(0x1<<14));}while(0)
#define I2C_SDA_HIGH    do{GPIOF->ODR |= (0x1<<15);}while(0)
#define I2C_SDA_LOW     do{GPIOF->ODR &= (~(0x1<<15));}while(0)
//#define I2C_SDA_READ    do{(GPIOF->IDR & (0x1<<0xF))>>0xF}while(0)
extern void printf(const char *fmt, ...);
//delay in microsecond
void delay_us(void);
//delay in millisecond
void delay(int ms); 
//start signal
void i2c_start(void);
//stop signal
void i2c_stop(void);
//write one byte
void i2c_write_byte(unsigned char  dat);
//read one byte
unsigned char i2c_read_byte();
//wait for acknowledge
unsigned char i2c_get_ack(void);
//send acknowledge
void i2c_send_ack(void);
//send not acknowledge
void i2c_send_nack(void);

void i2c_gpio_init();
void i2c_si7006_init();
unsigned short i2c_read_hum();
short i2c_read_tmp();


#endif

i2c.c

#include "i2c.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
/*
port:    GPIOF
pin:      I2C1_SCL/PF14
pin:      I2C1_SDA/PF15
RCC:    PF14/PF15     AHB4
si7006 address 0x40
*/
//delay in microsecond
void delay_us(void){
    unsigned int i = 2000;
    while(i--);
}
//delay in millisecond

//start signal
void i2c_start(void){
    I2C_SDA_OUT;
    I2C_SCL_HIGH;
    I2C_SDA_HIGH;
    delay_us();
    I2C_SDA_LOW;
    delay_us();
    I2C_SCL_LOW;
}
//stop signal
void i2c_stop(void){
    I2C_SDA_OUT;
    I2C_SCL_LOW;
    I2C_SDA_LOW;
    delay_us();
    I2C_SCL_HIGH;
    delay_us();
    I2C_SDA_HIGH;
}
//write one byte
void i2c_write_byte(unsigned char  dat){
    I2C_SDA_OUT;
    for(int i=0;i<8;i++){
        I2C_SCL_LOW;
        delay_us();
        if((dat&(0x1<<0x7))==1){
            I2C_SDA_HIGH;
        }else{
            I2C_SDA_LOW;
        }
        delay_us();
        I2C_SCL_HIGH;
        delay_us();
        delay_us();
        dat=(dat<<0x1);
    }

}
//read one byte
unsigned char i2c_read_byte(){
    I2C_SDA_IN;
    unsigned char dat=0;
    for(int i=0;i<8;i++){
        I2C_SCL_LOW;
        delay_us();
        delay_us();
        I2C_SCL_HIGH;
        dat=(dat<<0x1) | GPIOF->IDR;
        delay_us();
        delay_us();
    }
    return dat;
}
//get acknowledge
unsigned char i2c_get_ack(void){
    I2C_SDA_IN;
    I2C_SCL_LOW;
    I2C_SDA_HIGH;
    delay_us();
    delay_us();
    I2C_SCL_LOW;
    delay_us();
    return (GPIOF->IDR & (0x1<<0xF))>>0xF;
}
//send acknowledge
void i2c_send_ack(void){
    I2C_SDA_OUT;
    I2C_SCL_LOW;
    delay_us();
    I2C_SDA_LOW;
    delay_us();
    I2C_SCL_HIGH;
    delay_us();
    delay_us();
    I2C_SCL_LOW;
}
//send not acknowledge
void i2c_send_nack(void){
    I2C_SDA_OUT;
    I2C_SCL_LOW;
    delay_us();
    I2C_SDA_HIGH;
    delay_us();
    I2C_SCL_HIGH;
    delay_us();
    delay_us();
    I2C_SCL_LOW;
}
void i2c_gpio_init(){
    //enable GPIOF
    RCC->MP_AHB4ENSETR |= (0x1<<0x5);
    //set GPIOF14 to ouput mode
    GPIOF->MODER &= (~(0x3<<0x1c));
    GPIOF->MODER |= (0x1<<0x1c);
}
void i2c_si7006_init(){
    i2c_start();
    i2c_write_byte(0x80);
    if(i2c_get_ack()==0){printf("i2c_si7006_init--------------1");}
    i2c_write_byte(0XE6);
    if(i2c_get_ack()==0){printf("i2c_si7006_init--------------2");}
    i2c_write_byte(0X3A);
    if(i2c_get_ack()==0){printf("i2c_si7006_init--------------3");}
    i2c_stop();
};
unsigned short i2c_read_hum(){
    unsigned short hum=0;
    unsigned char hum_high,hum_low;
    i2c_start();
    i2c_write_byte(0x80);
    if(i2c_get_ack()==0){printf("i2c_read_hum--------------1");}
    i2c_write_byte(0XE5);
    if(i2c_get_ack()==0){printf("i2c_read_hum--------------2");}
    i2c_start();
    i2c_write_byte(0x81);
   hum_high=i2c_read_byte();
    i2c_send_ack();
    hum_low=i2c_read_byte();
    i2c_send_nack();
    i2c_stop();
    hum=(hum_high<<0x8) | hum_low;
    return hum;
}
short i2c_read_tmp(){
    short tmp=0;
    char tmp_high,tmp_low;
    i2c_start();
    i2c_write_byte(0x80);
    if(i2c_get_ack()==0){printf("i2c_read_tmp--------------1");}
    i2c_write_byte(0XE5);
    if(i2c_get_ack()==0){printf("i2c_read_tmp--------------2");}
    i2c_start();
    i2c_write_byte(0x81);
   tmp_high=i2c_read_byte();
    i2c_send_ack();
    tmp_low=i2c_read_byte();
    i2c_send_nack();
    i2c_stop();
    tmp=(tmp_high<<0x8) | tmp_low;
    return tmp;
}

main.c



#include"led.h"

//#include "fan.h"



#include "uart4.h"

#include "key.h"

#include "i2c.h"

extern void printf(const char *fmt, ...);

//封装延时函数

void delay(int ms)

{

    int i,j;

    for(i=0;i<ms;i++)

    {

        for(j=0;j<2000;j++)

        {}



    }

}

int main()

{



    all_led_init();

    /*

    fan_init();

    */

    uart4_init();

    key_init();

    i2c_gpio_init();

    i2c_si7006_init();

    while(1)

    {

        /*

        LED1_ON();

        delay(500);

        LED1_OFF();

        delay(500);

        fan_ON();

        delay(500);

        fan_OFF();

        */

        /*

        char c = getchar();

        if(c == '\r'){

            putchar('\r');

            putchar('\n');

        }

        putchar(c);

        if(c == 'a'){

            LED1_ON();

            LED2_OFF();

            LED3_OFF();

        }else if(c == 'b'){

            LED2_ON();

            LED1_OFF();

            LED3_OFF();

        }else{

            LED3_ON();

            LED1_OFF();

            LED2_OFF();

        }

        */

        //printf("in main function\n\r");

        delay(1000);

        short tmp=i2c_read_tmp();

         unsigned short hum=i2c_read_hum();

         hum=125*hum/65536-6;

         tmp=175.72*tmp/65536-46.85;

         printf("hum=%d  tmp=%d\n",hum,tmp);


    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值