main.c
#include "spi.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}
//保存0-9编码的数组
int num[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0x3E,0xE0,0xFE,0xF6};
int num2[10] = {0x80,0x40,0x20,0x10,0x80,0x40,0x20,0x10,0x80,0x40};
int main(void)
{
unsigned char i;
SPI_init();
while(1)
{
for(i = 0; i < 10; i++)
{
SPI_write(num2[i]); // 发送数码管的位
SPI_write(num[i]); // 发送数码管的段
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
// 将移位寄存器中的数据锁存到锁存寄存器中
delay_ms(1000);
}
}
return 0;
}
spi.c
#include "spi.h"
void delay_us(unsigned int us)
{
int i,j;
for(i=0; i<us; i++)
{
for(j=0; j<1; j++);
}
}
void SPI_init()
{
//使能GPIOE时钟
RCC->MP_AHB4ENSETR |= (0x1<<4);
//设置MOSI管脚PE14输出
GPIOE->MODER &= (~(0x3<<28));
GPIOE->MODER |= (0x1<<28);
GPIOE->OTYPER &= (~(0x1<<14));
GPIOE->OSPEEDR &= (~(0x3<<28));
GPIOE->PUPDR &= (~(0x3<<28));
//设置MISO管脚PE13输入
GPIOE->MODER &= (~(0x3<<26));
GPIOE->OSPEEDR &= (~(0x3<<26));
GPIOE->PUPDR &= (~(0x3<<26));
//SCK管脚PE12 输出
GPIOE->MODER &= (~(0x3<<24));
GPIOE->MODER |= (0x1<<24);
GPIOE->OTYPER &= (~(0x1<<12));
GPIOE->OSPEEDR &= (~(0x3<<24));
GPIOE->PUPDR &= (~(0x3<<24));
//RCK(NSS)管脚 输出
GPIOE->MODER &= (~(0x3<<22));
GPIOE->MODER |= (0x1<<22);
GPIOE->OTYPER &= (~(0x1<<11));
GPIOE->OSPEEDR &= (~(0x3<<22));
GPIOE->PUPDR &= (~(0x3<<22));
//默认PE12 PE11 输出低电平
SCK_OUTPUT_L();
NSS_OUTPUT_L();
}
void SPI_write(unsigned char dat)
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x1)
{
MOSI_OUTPUT_H();//MOSI线写高
}
else
{
MOSI_OUTPUT_L();
}
dat >>= 1;
//时钟线从低电平到高电平变化时
//MOSI数据线上的数据被写到寄存器中
SCK_OUTPUT_L();
delay_us(10);
SCK_OUTPUT_H();
delay_us(10);
}
}
spi.h
#ifndef __SPI_H_
#define __SPI_H_
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//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 SCK_OUTPUT_H() do{GPIOE->ODR |= (0x1<<12);}while (0)
#define SCK_OUTPUT_L() do{GPIOE->ODR &= (~(0x1<<12));}while (0)
void delay_us(unsigned int us);
void SPI_init();
void SPI_write(unsigned char dat);
#endif
main.c
#include "spi.h"
#include "si7006.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 1800; j++);
}
// 保存0-9编码的数组
int num[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0x3E, 0xE0, 0xFE, 0xF6};
int main(void)
{
unsigned short hum;
short tem;
int a,b,c,d;
// 进行si7006的初始化
si7006_init();
SPI_init();
while (1)
{
// 读取湿度
hum = si7006_read_hum_data(0X40, 0XE5);
// 读取温度
tem = si7006_read_temp_data(0X40, 0XE3);
// 将温度数据和湿度数据按照转换公式进行转换
hum = 125 * hum / 65536 - 6;
tem = 175.72 * tem / 65536 - 46.85;
deley(1000); // 延时打印
// 将获取到的数据打印到串口
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_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
SPI_write(0x40); // 发送数码管的位
SPI_write(num[b]); // 发送数码管的段
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
SPI_write(0x20); // 发送数码管的位
SPI_write(num[c]); // 发送数码管的段
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
SPI_write(0x10); // 发送数码管的位
SPI_write(num[d]); // 发送数码管的段
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
}
}
return 0;
}