效果图
main.c
#include "spi.h"
#include "si7006.h"
#include "key_int.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++);
}
}
int num[10] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6};
int main(void)
{
key1_it_config();
while (1)
{
unsigned char i;
SPI_init();
while (1)
{for (i = 0; i < 10; i++)
{
if (i % 4 == 0)
{
SPI_write(0x80);
SPI_write(num[i]);
}
else if (i % 4 == 1)
{
SPI_write(0x40);
SPI_write(num[i]);
}
else if (i % 4 == 2)
{
SPI_write(0x20);
SPI_write(num[i]);
}
else if (i % 4 == 3)
{
SPI_write(0x10);
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_us1(unsigned int us)
{
int i,j;
for(i=0;i<us;i++)
{
for(j=0;j<1;j++);
}
}
void SPI_init(void)
{
//设置GPIOE时钟使能
RCC->MP_AHB4ENSETR |=(0X1<<4);
//MOSI管脚PE14 设置输出属性
GPIOE->MODER &=(~(0X3<<28));
GPIOE->MODER |=(0X1<<28);
//MISO管脚PE13 设置输入属性
GPIOE->MODER &=(~(0X3<<26));
//GPIOE->MODER |=(0X1<<26);
//SCK管脚PE12 设置输出属性
GPIOE->MODER &=(~(0X3<<24));
GPIOE->MODER |=(0X1<<24);
//RCK(NSS)管脚PE11 设置输出属性
GPIOE->MODER &=(~(0X3<<22));
GPIOE->MODER |=(0X1<<22);
//默认PE12和PE11输出低电平,方便产生上升沿
NSS_OUTPUT_L();
SCK_OUTPUT_L();
}
void SPI_write(unsigned int dat)
{
unsigned int i;
for(i=0;i<8;i++)
{
if(dat&0x01)
{
//输出高电平
MOSI_OUTPUT_H();
}
else
{
//输出低电平
MOSI_OUTPUT_L();
}
dat >>= 1;
//产生上升沿
SCK_OUTPUT_L();
delay_us1(10);
SCK_OUTPUT_H();
delay_us1(10);
}
}
do_irq.c
#include "key_int.h"
#include "spi.h"
#include "si7006.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void)
{
int num[10] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6};
unsigned short hum;
short tem;
//进行si7006的初始化
si7006_init();
//读取湿度
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(1); //延时打印
SPI_init();
int irqnu = (GICC->IAR & 0x3ff);
switch (irqnu)
{
case 99: //KEY1
while (1)
{
//将获取到的数据打印到串口
printf("hum:%d\n", hum);
printf("tem:%d\n", tem);
SPI_write(0x80); //发送数码管的位
SPI_write(num[hum / 10]);
delay_ms(1);
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H();
delay_ms(1);
SPI_write(0x40);
SPI_write(num[hum % 10]);
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H();
delay_ms(1);
SPI_write(0x20);
SPI_write(num[tem / 10]);
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H();
delay_ms(1);
SPI_write(0x10);
SPI_write(num[tem % 10]);
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H();
delay_ms(1);
}
break;
}
GICC->EOIR = irqnu;
}
key_int.c
#include "key_int.h"
void key1_it_config()
{
//设置GPIOF时钟使能
RCC->MP_AHB4ENSETR |= (0X1 << 5);
//设置PF9管脚输入
GPIOF->MODER &= (~(0X3 << 18));
//设置PF9作为EXTI9事件输入
EXTI->EXTICR3 &= (~(0X1F << 8));
EXTI->EXTICR3 |= (0X5 << 8);
//设置下降沿使能检测EXTI9事件
EXTI->FTSR1 |= (0X1 << 9);
//设置EXIT9事件不屏蔽
EXTI->C1IMR1 |= (0X1 << 9);
//GICD使能EXIT9(99号)中断
GICD->ISENABLER[3] = (0X1 << 3);
//GICD设置99号中断的优先级
GICD->IPRIORITYR[24] &= (~(0X1F << 27));
//选择CPU0处理当前中断
GICD->ITARGETSR[24] |= (0X1 << 24);
//全局使能组0中断被转发到GICC
GICD->CTRL |= (0X1);
//设置终端的优先级掩码
GICC->PMR |= (0X1F << 3);
//允许组0中断被CPU处理
GICC->CTRL |= (0X1);
}
spi.h
#ifndef __SPI_H__
#define __SPI_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//MOSI对应的引脚输出高低电平的信号PE14
#define MOSI_OUTPUT_H() do{GPIOE->ODR |= (0x1<<14);}while(0)
#define MOSI_OUTPUT_L() do{GPIOE->ODR &= (~(0x1<<14));}while(0)
//对应595芯片的锁存引脚输出高低电平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 SPI_init(void);
void SPI_write(unsigned int dat);
void delay_ms(int ms);
#endif
key_int.h
#ifndef __KEY_INT_H__
#define __KEY_INT_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_gic.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_exti.h"
#include "spi.h"
void key1_it_config();
#endif