当前位置: 首页 > news >正文

10.6日作业

作业题目

ARM-SPI实验

作业内容

一、什么是SPI
1.SPI总线是Motorola首先提出的全双工三线/四线同步串行总线
2.采用主从模式(Master Slave)架构;支持多slave模式应用,一般仅支持单Master,多从机
3.时钟由Master控制,在时钟移位脉
冲下,数据按位传输,高位在前,低位在后(MSB first)
4.SPI接口有2根单向数据线,为全双工
通信,目前应用中的数据速率可达几Mbps的水平
5.SPI总线被广泛地使用在FLASH、ADC、LCD等设备与MCU间,要求通讯速率较高的场合
6.SPI接口共有4根信号线,
分别是:设备选择线(片选线):NSS nsc
时钟线:SCK CLK
串行输出数据线:MOSI
串行输入数据线:MISO
M:master主机 O:output输出 S:slave从机 I:input输入
7.信号线的作用:
• (1)MOSI:主器件数据输出,从器件数据输入
• (2)MISO:主器件数据输入,从器件数据输出
• (3)SCLK :时钟信号,由主器件产生
• (4)/SS:从器件使能信号,由主器件控制(片选)
二、SPI总线的通信协议
在这里插入图片描述
三、SPI总线框图
在这里插入图片描述
四、SPI总线的工作原理
在这里插入图片描述
在这里插入图片描述
五、代码部分
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__

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 "gpio.h"

#include "uart4.h"

#include "command.h"

#include "beep.h"

#include "key-TI.h"

#include "si7006.h"

#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++);

}



void led_init(void)

{

	RCC_MP_AHB4ENSETR |= (0x3 << 4);

	// gpio_init_t init = {GPIO_OUTPUT,GPIO_PP,LOW_SPEED,NOPUPD};

	/*

	gpio_init_t init;

	init.mode = GPIO_OUTPUT;

	init.type = GPIO_PP;

	init.speed = LOW_SPEED;

	init.pupd = NOPUPD;

*/

	gpio_init_t gpio_init = {

		.mode = GPIO_OUTPUT,

		.type = GPIO_PP,

		.speed = LOW_SPEED,

		.pupd = NOPUPD,

	};





	hal_gpio_init(GPIOE, &gpio_init, GPIO_PIN_10);

	hal_gpio_init(GPIOF, &gpio_init, GPIO_PIN_10);

	hal_gpio_init(GPIOE, &gpio_init, GPIO_PIN_8);

}

void led_flash(void)

{

	hal_gpio_write(GPIOE, GPIO_PIN_10, GPIO_SET);

	delay_ms(500);

	hal_gpio_write(GPIOE, GPIO_PIN_10, GPIO_RESET);

	delay_ms(500);

}



int num[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};

int main(void)

{

	unsigned char i;

	SPI_init();

	while(1)

	{

#if 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);

		}

#else 

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

		{

			SPI_write(0x80 >> i);

			SPI_write(num[i+1]);

			NSS_OUTPUT_L();

			delay_ms(1);

			NSS_OUTPUT_H();



		}

#endif 

	}



	return 0;

}

相关文章:

  • Mybatis,动态代理方式的CRUD
  • Linux 进程管理类
  • 魔法方阵(CSP-J模拟赛)
  • 线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段
  • 【axios】二次封装——避免重复发送请求
  • 没有那么难,基于 Echarts + Python Flask 动态实时大屏轻松可以实现
  • 【每日一算法】高精度算法 | 加法 | 减法_模板应用
  • 2022华为杯A题第一问详细思路
  • Qt5.14.2开发Mqtt应用程序
  • 【U3D小游戏】愤怒的小鸟(三)猪的相关
  • 【UEFI实战】LinuxBoot
  • Linux: kernel: 调试:DYNAMIC_DEBUG
  • 开发一个Canvas小游戏 实现一个游戏“引擎”
  • Java Spring MVC框架 II
  • Python注释、Python风格规范
  • 08.Android之View事件问题
  • 2017-08-04 前端日报
  • Angular 4.x 动态创建组件
  • CentOS 7 修改主机名
  • github指令
  • Linux各目录及每个目录的详细介绍
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Next.js之基础概念(二)
  • node-glob通配符
  • python docx文档转html页面
  • Python学习笔记 字符串拼接
  • vue脚手架vue-cli
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 好的网址,关于.net 4.0 ,vs 2010
  • 将 Measurements 和 Units 应用到物理学
  • 精彩代码 vue.js
  • 聚类分析——Kmeans
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 让你的分享飞起来——极光推出社会化分享组件
  • 如何在 Tornado 中实现 Middleware
  • 硬币翻转问题,区间操作
  • 用jquery写贪吃蛇
  • 智能合约开发环境搭建及Hello World合约
  • 阿里云ACE认证之理解CDN技术
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #Lua:Lua调用C++生成的DLL库
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (4)logging(日志模块)
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (补)B+树一些思想
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (四) Graphivz 颜色选择
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET Project Open Day(2011.11.13)
  • .NET 动态调用WebService + WSE + UsernameToken