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