成果
代码
main .c====================
#include "sqi.h"
#include "si7006.h"
unsigned int num[10] = {0xFC, 0x60, 0xDA,0xF2,0x66,0xB6,0xBE,0XE0,0xFE,0xF6};
//unsigned int wei[5]={0x10,0x20,0x40,0x80,0xF0};
unsigned short hum;
short tem;
extern void printf(const char *fmt, ...);
int main()
{
int a,b,c,d;
key1_it_config();
si7006_init();
SPI_init();
/*
int i,j;
while(1){
for(i=0;i<10;i++)
{
for(j=0;j<5;j++)
{
SPI_write(wei[j]);
SPI_write(num[i]);
NSS_OUTPUT_L();
delay(20);
NSS_OUTPUT_H();
delay(100);
}
if(j==5)
{
j=0;
}
}
}*/
while (1)
{
hum=si7006_read_hum_data(0x40,0xE5);
tem=si7006_read_temp_data(0x40,0xE5);
hum=125*hum/65536-6;
tem=175.72*tem/65536-46.85;
printf("hum=%d\n",hum);
printf("tem=%d\n",tem);
//获取数据的各个数
a=hum/10;
b=hum%10;
c=tem/10;
d=tem%10;
for(int i=0;i<10000;i++)
{
SPI_write(0x80);
SPI_write(num[a]);
NSS_OUTPUT_L();
delay(1);
NSS_OUTPUT_H();
SPI_write(0x40);
SPI_write(num[b]);
NSS_OUTPUT_L();
delay(1);
NSS_OUTPUT_H();
SPI_write(0x20);
SPI_write(num[c]);
NSS_OUTPUT_L();
delay(1);
NSS_OUTPUT_H();
SPI_write(0x10);
SPI_write(num[d]);
NSS_OUTPUT_L();
delay(1);
NSS_OUTPUT_H();
delay(2000);
}
}
}
iic.c=============================
#include"iic.h"
#include"sqi.h"
void i2c_init(void)//i2c初始化
{
RCC->MP_AHB4ENSETR|=(0x1<<5);
GPIOF->MODER &=(~(0xF<<28));
GPIOF->MODER |=(0x5<<28);
GPIOF->OTYPER &=(~(0x3<<14));
GPIOF->OSPEEDR|=(0xF<<28);
GPIOF->PUPDR &=(~(0xF<<28));
//空闲拉高
I2C_SDA_H;
I2C_SCL_H;
}
void i2c_start(void)//起始信号发送
{
SET_SDA_OUT;
//空闲拉高
I2C_SCL_H;
I2C_SDA_H;
//形成下降沿
delay(20);
I2C_SDA_L;
delay(20);
I2C_SCL_L;
}
void i2c_stop(void)//终止信号发送
{
SET_SDA_OUT;
I2C_SCL_L;
delay(20);
I2C_SDA_L;
delay(20);
I2C_SCL_H;
delay(20);
I2C_SDA_H;
}
void i2c_write_byte(unsigned char data)//写入一个字节
{
SET_SDA_OUT;
unsigned int i;
for(i=0;i<8;i++)
{
I2C_SCL_L;
delay(20);
if(data&0x80)
{
I2C_SDA_H;
}else
{
I2C_SDA_L;
}
delay(20);
I2C_SCL_H;
delay(20);
delay(20);
data=data<<1;
}
}
unsigned char i2c_read_byte(unsigned char ack)//读取一个字节
{
unsigned int i;
unsigned char dat;
SET_SDA_IN;
for ( i = 0; i < 8; i++)
{
I2C_SCL_L;
delay(20);
delay(20);
I2C_SCL_H;
delay(20);
dat=dat<<1;
if (I2C_SDA_READ)
{
dat|=1;
}else{
dat &=(~0x1);
}
delay(20);
}
if(ack)
{
i2c_nack();
}else{
i2c_ack();
}
return dat;
}
unsigned char i2c_wait_ack(void)//等待应答信号
{
I2C_SCL_L;
I2C_SDA_H;
delay(20);
SET_SDA_IN;
delay(20);
delay(20);
I2C_SCL_H;
if (I2C_SDA_READ)
{
return 1;
}
I2C_SCL_L;
return 0;
}
void i2c_ack(void)//发送应答信号
{
SET_SDA_OUT;
I2C_SCL_L;
delay(20);
I2C_SDA_L;
delay(20);
I2C_SCL_H;
delay(20);
delay(20);
I2C_SCL_L;
}
void i2c_nack(void)//发送信号信号
{
SET_SDA_OUT;
I2C_SCL_L;
delay(20);
I2C_SDA_H;
delay(20);
I2C_SCL_H;
delay(20);
delay(20);
I2C_SCL_L;
}
si7006.c=======================================================================
#include "sqi.h"
#include "si7006.h"
#include "iic.h"
void si7006_init(void)
{
i2c_init();
i2c_start();
i2c_write_byte(0x40<<1|0);
i2c_wait_ack();
i2c_write_byte(0xE6);
i2c_wait_ack();
i2c_write_byte(0x3A);
i2c_wait_ack();
i2c_stop();
}
unsigned short si7006_read_hum_data(unsigned char slave_addr,unsigned char cmd_code )
{
unsigned short dat;
unsigned char dat_h,dat_l;
i2c_start();
i2c_write_byte(slave_addr<<1|0);
i2c_wait_ack();
i2c_write_byte(cmd_code);
i2c_wait_ack();
i2c_start();
i2c_write_byte(slave_addr<<1|1);
i2c_wait_ack();
delay(100);
dat_h=i2c_read_byte(0);
dat_l=i2c_read_byte(1);
i2c_stop();
dat=(dat_h<<8)|dat_l;
return dat;
}
short si7006_read_temp_data(unsigned char slave_addr,unsigned char cmd_code)
{
unsigned short dat;
unsigned char dat_h,dat_l;
i2c_start();
i2c_write_byte(slave_addr<<1|0);
i2c_wait_ack();
i2c_write_byte(cmd_code);
i2c_wait_ack();
i2c_start();
i2c_write_byte(slave_addr<<1|1);
i2c_wait_ack();
delay(100);
dat_h=i2c_read_byte(0);
dat_l=i2c_read_byte(1);
i2c_stop();
dat=(dat_h<<8)|dat_l;
return dat;
}
spi.c=================================================
#include "sqi.h"
void delay(unsigned int ms)
{
int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<100;j++);
}
}
//初始化
void SPI_init(void)
{
//设置时钟使能
RCC->MP_AHB4ENSETR |= (0x1<<4);
//设置输出
//pe12 sck 输出
GPIOE->MODER &= (~(0x03<<24));
GPIOE->MODER |= (0x01<<24);
GPIOE->OTYPER &=(~(0x3<<24));
GPIOE->PUPDR &=(~(0x3<<24));
//pe13 miso 输入
GPIOE->MODER &= (~(0x03<<26));
GPIOE->MODER |= (0x00<<26);
GPIOE->OTYPER &=(~(0x3<<26));
GPIOE->PUPDR &=(~(0x3<<26));
//pe14 mosi 输出
GPIOE->MODER &= (~(0x03<<28));
GPIOE->MODER |= (0x01<<28);
GPIOE->OTYPER &=(~(0x3<<28));
GPIOE->PUPDR &=(~(0x3<<28));
//pe11 nss 输出
GPIOE->MODER &= (~(0x03<<22));
GPIOE->MODER |=(0x01<<22);
GPIOE->OTYPER &=(~(0x3<<28));
GPIOE->PUPDR &=(~(0x3<<28));
//pe12 pe11输出低电平
SOCK_OUTPUT_L();
NSS_OUTPUT_L();
}
//spi发送数据
void SPI_write(unsigned char dat)
{
unsigned char i;
for ( i = 0; i < 8; i++)
{
if(dat&0x01)
{
//MOSI高位
MOSI_OUTPUT_H();
}else{
//MOSI低位
MOSI_OUTPUT_L();
}
dat>>=1;
//时钟线先初始低
//初始化为低有数据输入时为高
SOCK_OUTPUT_L();
delay(200);
SOCK_OUTPUT_H();
delay(200);
}
}
========================iic.h
#ifndef __IIC_H__
#define __IIC_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#define SET_SDA_OUT do{GPIOF->MODER &= (~(0x3<<30));GPIOF->MODER |=(0x1<<30);} while (0);
#define SET_SDA_IN do{GPIOF->MODER &= (~(0x3<<30));}while(0);
#define I2C_SCL_H do{GPIOF->BSRR |= (0x1 << 14);} while (0);
#define I2C_SCL_L do{GPIOF->BRR |= (0x1 << 14);} while (0);
#define I2C_SDA_H do{GPIOF->BSRR |= (0x1 << 15);} while (0);
#define I2C_SDA_L do{GPIOF->BRR |= (0x1 << 15);} while (0);
#define I2C_SDA_READ (GPIOF->IDR &(0x1 << 15))
void i2c_init(void);//i2c初始化
void i2c_start(void);//起始信号发送
void i2c_stop(void);//终止信号发送
void i2c_write_byte(unsigned char data);//写入一个字节
unsigned char i2c_read_byte(unsigned char ack);//读取一个字节
unsigned char i2c_wait_ack(void);//等待应答信号
void i2c_ack(void);//发送应答信号
void i2c_nack(void);//发送信号信号
#endif
si70006.h===============================
#ifndef __SI7006_H
#define __SI7006_H
#include "iic.h"
#define SI7006_SLAVE 0x40
void si7006_init(void);
unsigned short si7006_read_hum_data(unsigned char slave_addr, unsigned char cmd_code);
short si7006_read_temp_data(unsigned char slave_addr, unsigned char cmd_code);
#endif
spi.h======================================
#ifndef __SQI_HEAD__
#define __SQI_HEAD__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//delay时钟函数
void delay(unsigned int ms);
//MOSI对应的引脚输出高低电平的信号PE14
#define MOSI_OUTPUT_H() do{GPIOE->ODR |= (0x1<<14);}while(0)
#define MOSI_OUTPUT_L() do{GPIOE->ODR &= (~(0x1<<14));}while(0)
//PE11锁存引脚输出高低电平
#define NSS_OUTPUT_H() do{GPIOE->ODR |= (0x1<<11);}while(0)
#define NSS_OUTPUT_L() do{GPIOE->ODR &= (~(0x1<<11));}while(0)
//PE12时钟信号输出高低电平
#define SOCK_OUTPUT_H() do{GPIOE->ODR |= (0x1<<12);}while(0)
#define SOCK_OUTPUT_L() do{GPIOE->ODR &= (~(0x1<<12));}while(0)
//初始化
void SPI_init(void);
//spi发送数据
void SPI_write(unsigned char dat);
#endif
面试题