成果
代码
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 { 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 面试题