利用spi总线实现8位数码管显示:
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->OSPEEDR |= (0x2 << 28);
GPIOE->PUPDR &= (~(0x3 << 28));
// MISO PE13
GPIOE->MODER &= (~(0x3 << 26));
GPIOE->OSPEEDR &= (~(0x3 << 26));
// GPIOE->OSPEEDR |= (0x2 << 26);
GPIOE->PUPDR &= (~(0x3 << 26));
// SCK PE12
GPIOE->MODER &= (~(0x3 << 24));
GPIOE->MODER |= (0x1 << 24);
GPIOE->OTYPER &= (~(0x1 << 12));
GPIOE->OSPEEDR &= (~(0x3 << 24));
// GPIOE->OSPEEDR |= (0x2 << 24);
GPIOE->PUPDR &= (~(0x3 << 24));
// NSS PE11
GPIOE->MODER &= (~(0x3 << 22));
GPIOE->MODER |= (0x1 << 22);
GPIOE->OTYPER &= (~(0x1 << 11));
GPIOE->OSPEEDR &= (~(0x3 << 22));
// GPIOE->OSPEEDR |= (0x2 << 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(); // MOSI线写高
} else {
MOSI_OUTPUT_L(); // MOSI线写低
}
dat >>= 1;
// 时钟线从低电平到高电平的变化时,MOSI数据线上的数据
// 被写到595芯片的移位寄存器中
SCK_OUTPUT_L(); // SCK拉低
delay_us1(10);
SCK_OUTPUT_H(); // SCK拉高
delay_us1(10);
}
//NSS_OUTPUT_L();
//NSS_OUTPUT_H();
}
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(void)
{
SPI_init();
unsigned char i;
unsigned int j = 0;
while (1)
{
for(i = 0; i < 4; i++)
{
if(j==10)
j = 0;
SPI_write(((0x1 << i)<<4)); // 发送数码管的位
SPI_write(num[j]); // 发送数码管的段
j++;
NSS_OUTPUT_L();
delay_ms(1);
NSS_OUTPUT_H(); // 锁存的时钟从低到高的变化
// 将移位寄存器中的数据锁存到锁存寄存器中
delay_ms(100);
}
//delay_ms(1000);
}
//for循环条件
//内容:先发送位,在发送段
//0xF0 num[i]
return 0;
}