C语言 Cortex-A7核 SPI 实验
1 实验目的
1、数码管显示相同的值0000 1111 2222 .... 9999
2、数码管不同的值1234
2 代码
include/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__
src/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++) { //先发送第一位,再发送高位 //判断 if(dat & 0x01) MOSI_OUTPUT_H(); //向数据线上写入高电平 else MOSI_OUTPUT_L(); //向数据线上写入低电平 //移位 dat >>= 1; //时钟信号从低电平到高电平变化 SCK_OUTPUT_L(); delay_us1(10); SCK_OUTPUT_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 num[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};
int main()
{unsigned char i;SPI_init(); //SPI初始化while(1){
#if 0for(i=0;i<10;i++){SPI_write(0xF0);//先控制 位SPI_write(num[i]);//再控制 段//锁存时钟从低电平到高电平变化NSS_OUTPUT_L();delay_ms(1);NSS_OUTPUT_H();delay_ms(1000);}
#else //123for(i=0;i<4;i++){SPI_write(0x80 >> i);//位SPI_write(num[i+1]);//段//锁存时钟从低电平到高电平变化NSS_OUTPUT_L();delay_ms(1);NSS_OUTPUT_H();delay_ms(1000);}
#endif}return 0;
}