2023.1.4 作业

该代码实现了一个SPI接口的初始化和数据传输函数,用于STM32MP1xx微控制器与M74HC595芯片通信,以驱动四个8段数码管进行显示。SPI_init()函数配置了GPIO引脚,SPI_write()函数按位发送数据,main.c文件中包含了一个循环,依次显示数字0-9。
摘要由CSDN通过智能技术生成

1、模拟spi时序,控制Soc与M74HC595芯片通信,实现四个8段数码管的显示。

spi.h

#ifndef __SPI_H__
#define __SPI_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"

// MOSI对应的引脚输出高低电平的信号 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芯片的锁存引脚输出高低电平 NSS----->PE11
#define  NSS_OUTPUT_H	    do{GPIOE->ODR |= (0x1 << 11);}while(0)
#define  NSS_OUTPUT_L     do{GPIOE->ODR &= (~(0x1 << 11));}while(0)
	
// 时钟信号对应的引脚输出高低电平 SCK----->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__

spi.c

#include "../include/spi.h"
/* SPI4_NSS 	---->   PE11
 * SPI4_SCK     ---->   PE12
 * SPI4_MOSI    ---->   PE14
 * SPI4_MISO    ---->   PE13
 * */

/* 数码管的编码, 先发送低位,在发送高位
 * A B C D E F G DP
 * 1 1 1 1 1 1 0 0    0xFC   0
 * 0 1 1 0 0 0 0 0    0x60   1
 * 1 1 0 1 1 0 1 0    0xDA   2
 * 1 1 1 1 0 0 1 0    0xF2   3
 * 0 1 1 0 0 1 1 0    0x66   4
 * 1 0 1 1 0 1 1 0    0xB6   5 
 * 1 0 1 1 1 1 1 0    0xBE   6
 * 1 1 1 0 0 0 0 0    0xE0   7
 * 1 1 1 1 1 1 1 0    0xFE   8
 * 1 1 1 1 0 1 1 0    0xF6   9
 * */
void delay_us(unsigned int us)
{
	int i,j;
	for(i = 0; i < us;i++)
		for (j = 0; j < 1;j++);
}

void SPI_init(void)
{
	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));
	// NSS     PE11
	GPIOE->MODER &= (~(0x3 << 22));
	GPIOE->MODER |= (0x1 << 22);
	GPIOE->OTYPER &= (~(0x1 << 11));
	GPIOE->OSPEEDR &= (~(0x3 << 22));
	GPIOE->PUPDR &= (~(0x3 << 22));
	NSS_OUTPUT_L;    // 595芯片的锁存引脚拉低
	SCK_OUTPUT_L;    // SPI的时钟线拉低
}

void SPI_write(unsigned char dat)
{
	//for循环
	//if判断条件,先发送低位
	//if成立MOSI线写高
	//else MOSI线写低
	//移位寄存器时钟从低到高的变化
	for (int i = 0; i < 8;i++){
		if(dat & 0x01){
			MOSI_OUTPUT_H;
		}else{
			MOSI_OUTPUT_L;
		}
		SCK_OUTPUT_H;
		delay_us(10);
		SCK_OUTPUT_L;
		delay_us(10);
		dat >>= 1;
	}
}

main.c

#include "include/spi.h"



extern void printf(const char *fmt, ...);

extern void delay_us(unsigned int us);



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)

{

	SPI_init();

	while(1){

		//for循环条件

		//内容:先发送位,在发送段

		for (int i = 0; i < 4;i++){

			SPI_write(0x80>>i);

			SPI_write(num[i+1]);

			NSS_OUTPUT_H;

			delay_us(10);

			NSS_OUTPUT_L;

			delay_us(10);

		}

	}

	return 0;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值