GPIO模拟spi时序点亮数码管

目录

spi.h

spi.c

main.c

实验效果

spi.h

#ifndef __SPI_H__
#define __SPI_H__

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


//spi初始化
void spi_init();
//spi写入数据
void spi_write(unsigned char data);

#endif

spi.c

#include "spi.h"

extern void delay_us(void);

//spi初始化
void spi_init(){
    //使能GPIOE时钟
    RCC->MP_AHB4ENSETR |= (0x1<<4);

    //PE11配置为输出、推挽输出、无上拉下拉、高速输出
    GPIOE->MODER &= (~(0x3<<22));
    GPIOE->MODER |= (0x01<<22);

    GPIOE->OTYPER &= (~(0x1<<11));

    GPIOE->PUPDR &= (~(0x3<<22));

    GPIOE->OSPEEDR &= (~(0x3<<22));
    //PE12配置为输出、推挽输出、无上拉下拉、高速输出
    GPIOE->MODER &= (~(0x3<<24));
    GPIOE->MODER |= (0x01<<24);

    GPIOE->OTYPER &= (~(0x1<<12));

    GPIOE->PUPDR &= (~(0x3<<24));

    GPIOE->OSPEEDR &= (~(0x3<<24));
    //PE14配置为输出、推挽输出、无上拉下拉、高速输出
    GPIOE->MODER &= (~(0x3<<28));
    GPIOE->MODER |= (0x01<<28);

    GPIOE->OTYPER &= (~(0x1<<14));

    GPIOE->PUPDR &= (~(0x3<<28));

    GPIOE->OSPEEDR &= (~(0x3<<28));
    //PE13配置为输入
    GPIOE->MODER &= (~(0x3<<26));
    
    //sck、rck为低电平
    GPIOE->ODR &= (~(0x1<<12));
    GPIOE->ODR &= (~(0x1<<11));
}

//spi写入数据
void spi_write(unsigned char data){
    for (int i = 0; i < 8; i++)
    {
        //判断发送数据是1或0
        if(data & 0x01){
            GPIOE->ODR |= (0x1<<14);
        }
        else{
            GPIOE->ODR &= (~(0x1<<14));
        }
        //data右移1位
        data>>=1;
        //sck产生一个上升沿
        GPIOE->ODR &= (~(0x1<<12));
        delay_us();
        GPIOE->ODR |= (0x1<<12);
        delay_us();
    }
}

main.c

#include "gpio.h"
#include "led.h"
#include "uart4.h"
#include "keyip.h"
#include "iic.h"
#include "si7006.h"
#include "ap3216c.h"
#include "spi.h"

/*
0:0xFC
1:0x60
2:0xDA
3:0xF2
4:0x66
5:0xB6
6:0xBE
7:0xE0
8:0xFE
9:0xF6
*/

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

int main()
{

	unsigned char led[10] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};
	spi_init();
	while (1)
	{
		int i,j,k;
		for (i = 6; i >= 0; i--)
		{
			for (j = 9; j >= 0; j--)
			{
				for (k = 0; k < 20; k++)
				{
					spi_write(0x80);
					spi_write(led[i]);
					// 数据刷新到锁存寄存器
					GPIOE->ODR &= (~(0x1 << 11));
					delay_us();
					GPIOE->ODR |= (0x1 << 11);
					delay_us();
					spi_write(0x40);
					spi_write(led[j]);
					// 数据刷新到锁存寄存器
					GPIOE->ODR &= (~(0x1 << 11));
					delay_us();
					GPIOE->ODR |= (0x1 << 11);
					delay_us();
				}
			}
		}
		return 0;
	}
}

实验效果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPIO模拟SPI是一种在树莓派或其他单片机中使用通用输入输出引脚来模拟SPI(串行外围设备接口)通信协议的方法。SPI是一种常用的串行通信协议,可以用于与各种外围设备(如传感器、显示屏、存储器等)进行数据交互。 要在树莓派中实现GPIO模拟SPI通信,首先需要通过软件创建SPI协议所需的时序。树莓派的GPIO引脚可以通过编程来实现读写操作,因此可以利用这些引脚来模拟SPI时序。 具体实现步骤如下: 1. 首先,需要设置SPI引脚的模式,并确定引脚的输入输出方向。 2. 然后,可以通过编程实现SPI通信的时序,包括将数据发送给目标设备、接收目标设备返回的数据等。 3. 当需要发送数据时,可以将数据分别写入每个GPIO引脚,根据SPI协议,一般包括时钟线、数据线(MOSI)、数据输出线(MISO)和片选线(CS)。 4. 同样地,当需要接收数据时,可以通过读取GPIO引脚上的电平来获取目标设备返回的数据。 5. 在整个通信过程中,需要根据SPI协议规定的时序进行数据的发送和接收,以确保数据的正确传输。 需要注意的是,使用GPIO模拟SPI通信可能会面临一些性能上的限制,因为GPIO引脚的速度相对较慢。同时,在实际应用中,也要考虑到引脚的数目、通信距离等因素,以确保通信的可靠性和稳定性。 总的来说,通过GPIO模拟SPI通信可以在硬件资源有限的情况下实现与外围设备的串行数据交互,为嵌入式系统的开发提供了一种简单而经济的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值