头文件 spi.h
#ifndef __SPI_H__
#define __SPI_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
/*
SPI4_NSS ----- PE11
SPI4_SCK ----- PE12
SPI4_MISO ----- PE13
SPI4_MOSI ----- PE14
*/
// 对应595芯片的锁存引脚输出高低电平
#define NSS_H do{GPIOE->BSRR |= (0x1 << 11);}while(0)
#define NSS_L do{GPIOE->BRR |= (0x1 << 11);}while(0)
// 时钟信号对应的引脚输出高低电平
#define SCK_H do{GPIOE->BSRR |= (0x1 << 12);}while(0)
#define SCK_L do{GPIOE->BRR |= (0x1 << 12);}while(0)
// MOSI对应的引脚输出高低电平的信号
#define MOSI_H do{GPIOE->BSRR |= (0x1 << 14);}while(0)
#define MOSI_L do{GPIOE->BRR |= (0x1 << 14);}while(0)
//SPI初始化
void spi_init();
//发送一个字节
void spi_write(unsigned char data);
#endif
功能函数 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)
{
/**********RCC使能GPIOE组时钟*********/
RCC->MP_AHB4ENSETR |= (0x1 << 4);
/***********GPIO章节配置**************/
// MODER OTYPER OSPEEDR PUPDR
// SPI4_NSS PE11 01 0 00 00
// SPI4_SCK PE12 01 0 00 00
// SPI4_MISO PE13 00 0 00 00
// SPI4_MOSI PE14 01 0 00 00
// MODER[29:22] = 0x45
// OTYPER[14:11] = 0x0
// OSPEEDR[29:22]= 0x00
// PUPDR[29:22] = 0x00
GPIOE->MODER &= (~(0xff<<22));
GPIOE->MODER |= (0x45<<22);
GPIOE->OTYPER &= (~(0xf<<11));
GPIOE->OSPEEDR &= (~(0xff<<22));
GPIOE->PUPDR &= (~(0xff<<22));
NSS_L; // 595芯片的锁存引脚拉低
SCK_L; // SPI的时钟线拉低
}
void spi_write(unsigned char data)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
if(data & 0x01)
{
MOSI_H; // MOSI线写高
} else {
MOSI_L; // MOSI线写低
}
data >>= 1;
// 时钟线有上升沿时MOSI数据线上的数据被写到595芯片的移位寄存器中
SCK_L;
delay_us1(10);
SCK_H;
delay_us1(10);
}
}
主函数 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++);
}
int main(void)
{
/*
数码管的编码
[0-9]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
*/
int num[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
int i = 0;
//spi初始化
spi_init();
while(1)
{
for(i = 0; i < 10; i++)
{
// 发送数码管的位
spi_write(0xf0);
// 发送数码管的段
spi_write(num[i]);
// 锁存的时钟有上升沿时,移位寄存器中的数据被存到锁存寄存器中
NSS_L;
delay_ms(1);
NSS_H;
delay_ms(1000);
}
}
return 0;
}