实现数码管不同位显示不同的数字
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);void delay_us1(unsigned int us);#endif // __SPI_H__
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)
{//1.使能GPIOE时钟RCC->MP_AHB4ENSETR |= 0X10;//2.MOSI管脚PE14 设置输出的属性GPIOE->MODER &=(~(0X3<<28));//设置PE14输出GPIOE->MODER |= (0X1<<28);//设置PE10为推挽输出GPIOE->OTYPER &=(~(0x1<<14));//PE10为低速输出GPIOE->OSPEEDR &= (~(0x3<<28));//设置无上拉下拉GPIOE->PUPDR &= (~(0x3<<28));//3.MISO管脚PE13 设置输入的属性GPIOE->MODER &=(~(0X3<<26));//设置PE14输入//4.SCK管脚PE12 设置输出的属性GPIOE->MODER &=(~(0X3<<24));//设置PE14输出GPIOE->MODER |= (0X1<<24);//设置PE10为推挽输出GPIOE->OTYPER &=(~(0x1<<12));//PE10为低速输出GPIOE->OSPEEDR &= (~(0x3<<24));//设置无上拉下拉GPIOE->PUPDR &= (~(0x3<<24));//5.RCK(NSS)管脚 设置输出的属性GPIOE->MODER &=(~(0X3<<22));//设置PE14输出GPIOE->MODER |= (0X1<<22);//设置PE10为推挽输出GPIOE->OTYPER &=(~(0x1<<11));//PE10为低速输出GPIOE->OSPEEDR &= (~(0x3<<22));//设置无上拉下拉GPIOE->PUPDR &= (~(0x3<<22));//默认PE12和PE11输出低电平,方便产生上升沿NSS_OUTPUT_L();SCK_OUTPUT_L();
}void SPI_write(unsigned char 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(1000);SCK_OUTPUT_H();delay_us1(1000);}}
main.c
#include "spi.h"// 保存0-9编码的数组int num[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};int main(){SPI_init();while (1){int M=0;for (int i = 0; i < 10; i++){SPI_write(0x80>>M); // 控制位M++;if(M>3){M=0;}SPI_write(num[i]); // 控制段// NSS管脚有一个上升沿的输出,将移位寄存器的数据下沉,并行输出NSS_OUTPUT_L();delay_us1(100);NSS_OUTPUT_H();delay_us1(500000);}}return 0;}
运行结果