arm学习stm32之spi总线数码管倒计时,裸机开发,soc

由于时间没有用时间计时器操作,有些误差,后续有空会翻新计时器版本

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 num[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};
int main()
{
	int i,j,k,l,m;
	SPI_init();
	//先发送位
	//在发送段
	while(1)
	{
		/*
		for(i=0;i<10;i++){
			SPI_write(0xF0);//发送位
			SPI_write(num[i]);//发送段
			NSS_OUTPUT_L();
			delay_ms(1);
			NSS_OUTPUT_H();
			delay_ms(1000);
		}*/
		for(i=5;i>=0;i--){
		for(j=9;j>=0;j--){
		for(k=5;k>=0;k--){
		for(l=9;l>=0;l--){
			for(m=200;m>=0;m--){
			//显示分钟十位
			SPI_write(0x80);
			SPI_write(num[i]);
			NSS_OUTPUT_L();
			delay_ms(1);
			NSS_OUTPUT_H();
			//delay_ms(1000);
			//显示分钟个位
				SPI_write(0x40);
				SPI_write(num[j]);
				NSS_OUTPUT_L();
				delay_ms(1);
				NSS_OUTPUT_H();
			//	delay_ms(1000);
				//显示秒钟十位
					SPI_write(0x20);
					SPI_write(num[k]);
					NSS_OUTPUT_L();
					delay_ms(1);
					NSS_OUTPUT_H();
				//	delay_ms(1000);
					//显示秒钟个位		
						SPI_write(0x10);
						SPI_write(num[l]);
						NSS_OUTPUT_L();
						delay_ms(1);
						NSS_OUTPUT_H();
						//delay_ms(1000);
					}
				}
				}
			}
		}
	}
	return 0;
}

spi.c

#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_us1(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)
{
	unsigned char i;
	for(i=0;i<8;i++){
		//先发送低位再发送高位	
		//	判断条件写1写0
		if(dat & 0x1){
			MOSI_OUTPUT_H();
		}else{
			MOSI_OUTPUT_L();
		}
		dat >>=1;
		//	上升沿
		SCK_OUTPUT_L();
		delay_us1(10);
		SCK_OUTPUT_H();
		delay_us1(10);
	}
}

spi.h

#ifndef __SPI_H__
#define __SPI_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
// MOSI对应的引脚输出高低电平的信号
#define  MOSI_OUTPUT_H()	do{GPIOE->ODR |= (0x1 << 14);}while(0)
#define  MOSI_OUTPUT_L()    do{GPIOE->ODR &= (~(0x1 << 14));}while(0)

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

你可能感兴趣的:(arm开发,stm32,spi总线,裸机开发,soc)