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 main(void)
{unsigned char i;SPI_init();while(1){for(i = 0; i < 10; i++){SPI_write(0xC0); // 發送數碼管的位 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(){RCC->MP_AHB4ENSETR|=(0x1<<4);//設置PE11為輸出、推挽輸出、無上拉下拉、高速輸出GPIOE->MODER&=(~(0x3<<22));GPIOE->MODER|=(0x1<<22);GPIOE->OTYPER&=(~(0x1<<11));//推挽輸出GPIOE->PUPDR&=(~(0x3<<22));//無上拉下拉GPIOE->OSPEEDR&=(~(0x3<<22));GPIOE->OSPEEDR|=(0x2<<22);//高速輸出//設置PE12為輸出、推挽輸出、無上拉下拉、高速輸出GPIOE->MODER&=(~(0x3<<24));GPIOE->MODER|=(0x1<<24);GPIOE->OTYPER&=(~(0x1<<12));//推挽輸出GPIOE->PUPDR&=(~(0x3<<24));//無上拉下拉GPIOE->OSPEEDR&=(~(0x3<<24));GPIOE->OSPEEDR|=(0x2<<24);//高速輸出//設置PE14為輸出、推挽輸出、無上拉下拉、高速輸出GPIOE->MODER&=(~(0x3<<28));GPIOE->MODER|=(0x1<<28);GPIOE->OTYPER&=(~(0x1<<14));//推挽輸出GPIOE->PUPDR&=(~(0x3<<28));//無上拉下拉GPIOE->OSPEEDR&=(~(0x3<<28));GPIOE->OSPEEDR|=(0x2<<28);//高速輸出//設置PE13為輸入GPIOE->MODER&=(~(0x3<<26));GPIOE->OSPEEDR &= (~(0x3 << 26));//低速GPIOE->PUPDR &= (~(0x3 << 26));//無上拉下拉//設置PE11 PE12默認輸出低電平GPIOE->ODR&=(~(0x1<<11));GPIOE->ODR&=(~(0x1<<12));NSS_OUTPUT_L(); // 595芯片的鎖存引腳拉低SCK_OUTPUT_L(); // SPI的時鐘線拉低}//封裝主機發送一個字節的函數//先發低位再發高位void SPI_write(unsigned char dat){unsigned int i;for(i=0;i<8;i++){if(dat & 0X01)//條件滿足說明最低位為1{//PE14輸出高電平MOSI_OUTPUT_H();}else{//PE14輸出低電平MOSI_OUTPUT_L();}dat>>=1;//SCK錘子吹一下//PE12輸出低電平SCK_OUTPUT_L();//延時delay_us1(10);//PE12輸出高電平SCK_OUTPUT_H();//延時delay_us1(10);}}
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)/** 函數功能: SPI初始化函數,推挽輸出,高速,禁止上拉和下拉* 函數參數:無* 函數返回值:無
*/
void SPI_init(void);
/** 函數功能:SPI發送數據的函數* 函數參數:dat : 要發送的數據* 函數返回值:無*
*/
void SPI_write(unsigned char dat);#endif // __SPI_H__