嵌入式学习笔记——SPI通信

这篇具有很好参考价值的文章主要介绍了嵌入式学习笔记——SPI通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

之前已经介绍了STM32的ADC、DMA、EXTI、TIME、NVIC、USART以及普通IO模式,此系列笔者还打算写最后三个大的内容,分别是SPI通信、IIC通信以及看门狗,后面就看大家的需求了,需要什么可以留在评论区,本文首先来介绍SPI的有关知识。

SPI总线概述

嵌入式学习笔记——SPI通信
在通信协议分类的介绍中,提到过SPI,它是一种同步 串行 全双工(也可半双工)通信协议,是最常用的板级通信总线。为什么要加总线作为它的定语呢,原因就是这个协议可以实现一主多从的通信,多个从机和主机通过SPI所需的信号线连接在一起,就拿之前的串口通信来说,串口通信是一主一从的通信方式,主机TX接从机的RX,主机的RX接从机的TX,除了共地以外还需要两个通信线;而SPI通信除了共地以外需要四个信号线进行传输,根据它同步串行全双工的特点,可以分析出它必然具有同步时钟线,以及两个串行数据线来实现全双工通信,至于第四个信号线,是用来判断具体与哪个从机进行通信的片选线。

名称 功能
MOSI 主输出从输入
MISO 主输入从输出
SCLK 同步时钟线
CS 片选线

SPI通信拓扑图

上面提到过,SPI是一种通信总线,这也意味着在一组信号线上可能存在多个从机,那么具体的连接方式拓扑图是怎么样的呢
1.一主一从
嵌入式学习笔记——SPI通信
嵌入式学习笔记——SPI通信
嵌入式学习笔记——SPI通信

注意上图中的MOSI和MOSI分别用了DO和DI来表示,这里需要了解一下生产厂商常用的别称,如下所示:
MISO:SIMO、DOUT、DO、SDO或SO(在主机端);

MOSI:SOMI、DIN、DI、SDI或SI(在主机端);

CS:CE、NSS、CE或SSEL;

SCLK也可以是SCK;
2.一主多从:
如下图所示,就是一个主机与多个主机连接的一种方式,主机与各个从机直接共同连接在SCLK、MOSI、MISO上,除此之外,每个从机还单独有一个SS片选与主机连接,通信时,主机通过拉低对应从机的SS来选择通信对象。
嵌入式学习笔记——SPI通信
除此之外还有一个菊花链的拓扑连接方式,这个大家可以去下面两篇博客中查看,关于SPI的详细介绍也可以查看这两篇大佬的分析,很透彻。

  1. SPI协议详解(图文并茂+超详细)http://t.csdn.cn/qaS7h
  2. 一文搞懂SPI通信协议http://t.csdn.cn/gTKQq

STM32的SPI通信

关于STM32的SPI通信,也有两种方案,这个在串口通信的时候我们也提到过,
方案一就是使用STM32集成好的SPI控制器,与之前使用USART一样,按照自己需求配置好对应的寄存器以及通信模式后就可以直接通过SPI控制器来实现收发,不需要编程实现底层的具体发送方式;
方案二使用IO口模拟SPI的时序,参照SPI通信的时序图,操作GPIO口实现数据的收发,模拟SPI的好处在于不必拘束于固定的管脚,随便一组管脚都可以,只是需要自己编写底层的发送函数,实现01010之类的发送。本文笔者会将两种方式都介绍一下。
首先,还是参照之前的模式,先介绍使用控制器实现的过程。

SPI的特性

首先还是来过一下STM32的SPI的特性,
第一,基于三条线的全双工同步传输,也就是常说的四线SPI,这里的三条线是不包括NSS片选线的;注意,还有一种三线SPI,这里的三线是缺少MOSI或者是MISO其中的一根,双方通过一个数据线进行数据交换,同一时间只能主发从收或者主收从发,这种三线SPI是一种半双工模式,有些类似后面会介绍的IIC的通信方式;
第二,STM32 SPI的数据帧可以是八位或者是16位数据,也就是说SPI控制器可以一次性发送16位数据或者8位数据,而我们之前的USART是只能发送8位或者9位数据;
第三,SPI控制器具有主从模式可以设置,也就是说,STM32上集成的SPI既可以做主机也可以作为从机,在使用过程中需要我们进行配置;
第四,SPI的最大通信频率是40MHZ,而fPCLK是84MHZ(由所挂接的时钟线决定),所以最大的通信速率是fPCLK/2,40MHZ的传输速率已经比IIC和USART快很多了。而且SPI控制器还可以使用快速模式的通信方式,将两个数据线同时作为传输,一般用不上,做个了解即可。
第五,SPI控制器有可编程的时钟极性与时钟相位,关于时钟极性与时钟相位,它们两个分别有两个状态,时钟极性有0与1两个状态,决定时钟是高有效还是低有效;而时钟相位决定的是第一个时钟边沿有效还是第二个时钟边沿有效,它们两两组合,构成了SPI的四种模式,
时钟极性CPOL
当时钟极性为0的时候,时钟线空闲状态是低电平状态
当时钟极性为1的时候,时钟线空闲状态是高电平状态
时钟相位CPHA
当时钟相位为0的时候,数据在第一个跳变沿被采样(数据采集)
当时钟相位为1的时候,数据在第二个跳变沿被采样
嵌入式学习笔记——SPI通信

模式 CPOL(时钟极性) CPHA(时钟相位) 数据收发
模式0 0 0 空闲时时钟线为低电平,第一个时钟边沿采集数据
模式1 0 1 空闲时时钟线为低电平,第二个时钟边沿采集数据
模式2 1 0 空闲时时钟线为高电平,第一个时钟边沿采集数据
模式3 1 1 空闲时时钟线为高电平,第二个时钟边沿采集数据

常用的是模式3与模式0,而且一般来说支持模式0的器件也支持模式3的通信方式(上升沿写入数据,下降沿读取数据),支持模式1的也支持模式2的通信方式(下降沿读取数据,上升沿写入数据)。
第六,SPI控制器也有对应的状态位可以产生发送完成和接收完成的标志,而且其传输是高位先发还是低位先发都可以进行编程控制。
嵌入式学习笔记——SPI通信

SPI控制器的框图

在了解了SPI控制器的相关特性后,接下来就是它的框图介绍了,其整体框图如下图所示,不难发现,这个框图的整体不是很复杂,我们来稍作拆分介绍一下。
嵌入式学习笔记——SPI通信

引脚

首先是左边的四个GPIO口,它们各自的功能如下图所示:
嵌入式学习笔记——SPI通信
这里注意的NSS片选,我们在使用过程过程中一般禁止此处的NSS,用内部的软件管理来屏蔽这个NSS,用另外一个GPIO来专门操作控制从机,在需要通信时拉低对应的管脚即可。
嵌入式学习笔记——SPI通信

数据收发过程

当使用四线SPI实现收发时,主机数据发送过程如下图中绿色线的流程,首先由MCU将数据写入发送缓冲区,然后再将数据由发送缓冲区并行转移到移位寄存器,根据LSB的设置,看是低位先发还是高位先发,然后再由移位寄存器一位一位的将数据发送到MOSI管脚上
主机数据接收过程,如下图红色线所示,由MISO输入数据,然后进入移位寄存器,接收完毕后经过移位寄存器并行转移到接收缓冲区,然后CPU在接收缓冲区中读取数据。
注:

  1. 下图中蓝色框里面还有两个箭头,一个是从MOSI指向MISO的,另一个是从MISO指向MOSI的,而且看起来是受到主控制逻辑的管理的,这里的两个箭头有两个作用:(1)使用三线SPI时,会舍弃一个数据传输脚,使用MOSI或者MISO中的任意一个,此时这一个数据脚既要发送又要接收,就需要使用到蓝色框内的箭头;(2)使用更快的传输模式时,会使用两个数据脚同时由主机向从机或者由从机向主机写数据,这个时候也需要使用到蓝色框内的箭头。
  2. 橙色框的NSS片选本来是SPI控制器内部集成的片选脚,但是我们实际使用过程一般不用,所以在配置过程中会使用软件管理来屏蔽掉它,让它作为一个普通的GPIO口;而实际的片选脚会根据硬件连接的管脚进行配置。
    嵌入式学习笔记——SPI通信
    类似下图,假设此时使用三线SPI的半双工模式,只有MOSI一个脚,此时数据数据输入时就需要使用到上图蓝色框内的箭头,变成下图橙色线的流程。而输出方式不变,同样的,只留下MISO亦是如此。
    嵌入式学习笔记——SPI通信

时钟以及控制部分

首先来看时钟部分,作为主机使用时,STM32的SPI控制器需要提供Sclk时钟信号,其产生方式就是下图的波特率发生器,对于这个波特率发生器在框图中可以看出留给我们操作的只有CR1寄存器的BR[2:0]共三位,按照前面的介绍以及以前的经验,这三位肯定是用来空时分频系数的,也就是决定通信速率的,在特性那里我们提到了,SPI的最大通信速率是40Mhz,而MCU的晶振频率大于40MHZ,也就是说,此处的分频估计最少也是一个2分频。
嵌入式学习笔记——SPI通信
然后是主控制逻辑,主控制逻辑部分就是关于模式,单个数据线还是两个数据线,主模式还是从机模式、是否只读这些进行选择。具体的在编程手册查看寄存器SPI_CR1寄存器介绍。
最后是通信控制,通信控制部分首先是最右边橙色框内有一个二选一数据选择器,其中一路输入来自上面提到得NSS,另外的一路输入来自SSI,而控制脚是SSM。当SSM置一时,系统会选择SSI,也就是内部从器件选择,从而屏蔽控制器绑定的指定CS GPIO。
嵌入式学习笔记——SPI通信
然后通讯控制还有输出上方蓝色框的各种标志位,发送完成以及接收完成这些,主要用于中断或者DMA关于这个详细的在SPI_CR2寄存器的介绍。这里仅需要知道有这个东西即可。

SPI寄存器简介

1.SPI 控制寄存器 1 (SPI_CR1)(不用于 I2S 模式)
写法:SPIX->CR1
位 0 CPHA:时钟相位 (Clock phase)
位1 CPOL:时钟极性 (Clock polarity)
位 2 MSTR:主模式选择 (Master selection) 选择主模式
位 5:3 BR[2:0]:波特率控制 (Baud rate control) 选2分频
位 6 SPE:SPI 使能 (SPI enable) 放在最后
位 7 LSBFIRST:帧格式 (Frame format) 一般选择高位先发
位8 SSI: 内部从器件选择
位 9 SSM:软件从器件管理 (Software slave management)
位9:8 设置软件管理。什么是软件管理?
NSS引脚属于硬件SPI 片选引脚。把NSS引脚设置为软件管理之后,这个引脚相当于当作普通IO口使用。为什么要把它设置成普通IO口使用。因为当SPI总线外接多个从机时,是通过片选引脚进行选择。把NSS引脚设置为软件管理之后,片选引脚就可以接任意一个IO口都可以,这就方便很多了。
把位9 和 位8 都 设置为1,就是把NSS设置为软件管理。

位 10 RXONLY:只接收 (Receive only) 全双工
嵌入式学习笔记——SPI通信
位 11 DFF:数据帧格式 数据位
位 15 BIDIMODE:双向通信数据模式使能 (Bidirectional data mode enable)
选择3线制SPI 还是4线制的SPI 结合硬件
2.SPI 控制寄存器 2 (SPI_CR2)
写法:SPIx->CR2
主要是中断使能和DMA使能

3.SPI 状态寄存器 (SPI_SR)
写法:SPIx->SR
位 0 RXNE:接收缓冲区非空 (Receive buffer not empty)
位 1 TXE:发送缓冲区为空 (Transmit buffer empty)

4.SPI 数据寄存器 (SPI_DR)
写法:SPIx->DR
发送数据SPI1->DR=data
接收数据data = SPI1->DR
如果是8位数据位,则数据寄存器的低8位为有效位
如果使用16为数据为,则整个DR为有效位

SPI初始化代码流程

根据上面的介绍即可总结出SPI控制器的初始化流程
伪代码:

SPI初始化
{
  /*IO口控制器配置*/
	//端口时钟使能
	//端口模式配置
	//具体复用功能配置
 	//输出类型配置
    //输出速度配置
	/*SPI1控制器配置*/
	//SPI1模块时钟使能
	//CR1
	//双向单向 全双工
	//8位数据帧
	//全双工
	//软件从器件管理//
	//主机模式
	//先发高位
	//4分频    
	//主配置
	//0.0模式
	//CR2
	//MOT模式,一般都选择摩托罗拉的模式,而不选择TI的模式
	//CFGR
	//SPI模式  选择为SPI模式,而非I2S
	//SPI使能
}

SPI数据收发函数
{
  //等待发送

  发送数据
 
  //等待接收
  接收数据
}

SPI初始化代码

/*******************************************
*函数名    :spi1_init
*函数功能  :SPI1初始化配置
*函数参数  :无
*函数返回值:无
*函数描述  :
SCK------PB3   //复用输出 
MISO-----PB4   //复用输出
MOSI-----PB5   //复用输出
*********************************************/
void Spi1_Init(void)
{
	/*IO口控制器配置*/
	//端口时钟使能
	RCC->AHB1ENR |= (1<<1);   //B组时钟使能
	//端口模式配置
	GPIOB->MODER &= ~((3<<6)|(3<<8)|(3<<10));
	GPIOB->MODER |= ((2<<6) |(2<<8)| (2<<10));
	//具体复用功能配置
	GPIOB->AFR[0] &= ~((15<<12)|  (15<<16) |  (15<<20));
	GPIOB->AFR[0] |= ((5<<12)|  (5<<16)|(5<<20));
  //输出类型配置
	GPIOB->OTYPER &= ~((1<<3) | (1<<4) | (1<<5));
  //输出速度配置
	GPIOB->OSPEEDR &= ~((3<<6)| (3<<8) | (3<<10));
	GPIOB->OSPEEDR |= ((2<<6)| (2<<8) | (2<<10));   //50M
	
	/*SPI1控制器配置*/
	//SPI1模块时钟使能
	RCC->APB2ENR |= (1<<12);//SPI1时钟使能
	//CR1
	SPI1->CR1 &= ~(1<<15);    //双线单向
//	SPI1->CR1 |= (1<<15);    //单线双向
	SPI1->CR1 &= ~(1<<11);    //8位数据帧
	SPI1->CR1 &= ~(1<<10);    //全双工
	SPI1->CR1 |= (1<<9);      //软件从器件管理//
	SPI1->CR1 |= (1<<8);      //主机模式
	SPI1->CR1 &= ~(1<<7);     //先发高位
	SPI1->CR1 |= (1<<3);      //4分频    
	SPI1->CR1 |= (1<<2);      //主机模式
	SPI1->CR1 &= ~(3<<0);     //清零(0.0模式)模式0
	SPI1->CR1 |= (3<<0);     //1.1模式模式3
	//CR2
	SPI1->CR2 &= ~(1<<4);     //MOT模式,一般都选择摩托罗拉的模式,而不选择TI的模式
	//CFGR
	SPI1->I2SCFGR &= ~(1<<11);  //选择为SPI模式,而非I2S
	
	//SPI使能
	SPI1->CR1 |= (1<<6);
}


/*******************************************
*函数名    :Spi_Send_Data
*函数功能  :SPI1传输一个字节函数
*函数参数  :u8 data
*函数返回值:u8
*函数描述  :
			发送数据时候只需要关注参数
            接收数据的时候,关注返回值,
								参数随便传一个数值
*********************************************/
u8 Spi_Send_Data(u8 data)
{
	u8 val;
	
	/*发送*/
	//等待之前的数据发送完成
	while(!(SPI1->SR & (1<<1)));
	//将要发送的数据赋值给DR
	SPI1->DR = data;

	/*接收*/
	//等待有数据就接收
	while(!(SPI1->SR & (1<<0)));
	//将DR数据赋值给变量
	val = SPI1->DR;
	
	return val;
}

SPI使用IO模拟的代码思路

找到对应的硬件设备接口
LCD_SPI2_MOSI   ---- 发送数据  PB15
LCD_SPI2_SCLK                 PB13
LCD_SPI2_MISO--------并不是屏幕上面没有这根线,而是没有使用到所以没有接
//注意使用的是IO口模拟来实现的功能,所以GPIO口需要配置为推挽输出。
SPI的初始化
{
  //打开时钟   PB
  //配置IO控制器
  //PB13   PB15通用推挽输出
}

SPI数据收发函数
{
  u8 buff;
  时钟线拉低
  数据线输出拉高
  
  for(循环八次)
  {
     //如何发送
时钟线拉低;   //控制发送,下降沿发送
     If(data & 0x80>>i)
     {
       数据线输出拉高
     }
     Else
     {
        数据输出拉低
}
 时钟线拉高;   //接收    上升沿读取 
}
}

由于笔者使用的屏幕不需要给主机反馈数据,所以这里少配置了一个MISO的管脚,且这里的GPIO初始化使用了GPIO的库函数来实现。


/*******************************************
*函数名    :Spi_Gpio_Init
*函数功能  :GPIO模拟SPI的初始化配置
*函数参数  :无
*函数返回值:无
*函数描述  :将GPIO配置为通用推挽输出,模拟产生SPI的时序
*********************************************/
void Spi_Gpio_Init(void)
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	
	//IO控制器
	GPIO_InitTypeDef gpio_InitTypeDef; //定义了一个结构体变量
	
	gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_OUT;           //通用输出模式
	gpio_InitTypeDef.GPIO_OType = GPIO_OType_PP;          //推挽输出
	gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;  //一起使用的前提条件 必须是同一个端口
	gpio_InitTypeDef.GPIO_PuPd = GPIO_PuPd_NOPULL;        //无上下拉
	gpio_InitTypeDef.GPIO_Speed = GPIO_Medium_Speed;      //中速
	
	GPIO_Init(GPIOB,&gpio_InitTypeDef);
	

}

/*******************************************
*函数名    :LCD_GSend_Byte
*函数功能  :使用模拟SPI发送一个八位的数据到LCD
*函数参数  :无
*函数返回值:无
*函数描述  :模式0或者模式3
*********************************************/
void LCD_GSend_Byte(u8 data)
{
	u8 i;
	
	//空闲状态
	LCD_SCL_L;
	LCD_MOSI_H;

	//具体的发送过程
	for(i=0;i<8;i++)
	{
		LCD_SCL_L;   //发送数据
		if(data & (0x80>>i))
		{
			LCD_MOSI_H;  //发送数据1
		}
		else
		{
			LCD_MOSI_L;
		}
		LCD_SCL_H;   //拉高接收数据
	}
	//开始读取返回数据
}

总结

关于SPI的控制器实现以及GPIO,模拟实现的介绍就记录到这里,具体的实际使用,笔者抽空再单开一片,应该是LCD的显示或者是对W25Q64烧录GB2312的字库。想要那个大家可以私信或者留在评论区。然后文中如有不足欢迎批评指正。

M4系列目录

1.嵌入式学习笔记——概述
2.嵌入式学习笔记——基于Cortex-M的单片机介绍
3.嵌入式学习笔记——STM32单片机开发前的准备
4.嵌入式学习笔记——STM32硬件基础知识
5.嵌入式学习笔记——认识STM32的 GPIO口
6.嵌入式学习笔记——使用寄存器编程操作GPIO
7.嵌入式学习笔记——寄存器实现控制LED小灯
8.嵌入式学习笔记——使用寄存器编程实现按键输入功能
9.嵌入式学习笔记——STM32的USART通信概述
10.嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
11.嵌入式学习笔记——STM32的USART收发字符串及串口中断
12.嵌入式学习笔记——STM32的中断控制体系
13.嵌入式学习笔记——STM32寄存器编程实现外部中断
14.嵌入式学习笔记——STM32的时钟树
15.嵌入式学习笔记——SysTick(系统滴答)
16.嵌入式学习笔记——M4的基本定时器
17.嵌入式学习笔记——通用定时器
18.嵌入式学习笔记——PWM与输入捕获(上)
19.嵌入式学习笔记——PWM与输入捕获(下)
20.嵌入式学习笔记——ADC模数转换器
21.嵌入式学习笔记——DMA
22.嵌入式学习笔记——SPI通信
23.嵌入式学习笔记——SPI通信的应用
24嵌入式学习笔记——IIC通信文章来源地址https://www.toymoban.com/news/detail-408063.html

到了这里,关于嵌入式学习笔记——SPI通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32串口通信详解(嵌入式学习)

    时钟信号在电子领域中是指用于同步和定时电路操作的周期性信号。它在数字系统和通信系统中起着至关重要的作用,用于协调各个组件之间的数据传输和操作。 时钟信号有以下几个重要的方面: 频率:时钟信号的频率是指单位时间内信号周期的数量。它通常以赫兹(Hz)为

    2024年02月09日
    浏览(59)
  • 【嵌入式学习笔记】嵌入式入门2——中断(外部中断)

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断 作用1: 实时控制在确定时间内对相应事件作出响应 ——定时器中断 作用2: 故障处理检测到故障,需要第一时间处理 ——外部中断 作用3: 数据传输不确定数据何时会来 ——串口中断

    2024年02月08日
    浏览(67)
  • 【嵌入式学习-STM32F103-USART串口通信】

    4-1 基本流程 4-2 整体代码 4-2-1 main.c 4-2-2 Serial.c 4-2-3 Serial.h 5-1 查询 5-2 中断 5-3 整体代码 5-3-1 main.c 5-3-2 Serial.c 5-3-3 Serial.h 6-1 使用状态机接收数据包的思路 6-2 串口收发HEX数据包 6-2-1 main.c 6-2-2 Serial.c 6-2-3 Serial.h 6-3串口收发文本数据包 6-3-1 main.c 6-3-2 Serial.c 6-3-3 Serial.h 全双工:打

    2024年02月15日
    浏览(53)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(75)
  • 嵌入式学习笔记汇总

    本文整理STM32、STM8和uCOS-III的所有文章链接。 源码:mySTM32-learn STM32学习笔记(1)——LED和蜂鸣器 STM32学习笔记(2)——按键输入实验 STM32学习笔记(3)——时钟系统 STM32学习笔记(4)——NVIC中断优先级管理和外部中断EXTI STM32学习笔记(5)——系统定时器SysTick STM32学习笔

    2023年04月20日
    浏览(54)
  • 【嵌入式学习】网络通信基础-项目篇:简单UDP聊天室

    源码已在GitHub开源:0clock/LearnEmbed-projects/chat 客户端功能: 上线发送登录的用户名[yes] 发送消息和接收消息[yes] quit退出 服务器端功能: 统计用户上线信息,放入链表中[yes] 接收用户信息并给其他用户发送消息[yes] 服务器也支持给所有用户群发消息[yes] 接收下线提醒

    2024年01月25日
    浏览(44)
  • 价值 1k 嵌入式面试题-单片机 main 函数之前都做了啥?

            请说下单片机(Arm)在运行到 main() 函数前,都做了哪些工作? 系统初始化工作,太泛泛 硬件初始化,比较不具体         这道题应该从两方面回答,一个是比较表面的硬件的初始化(价值 200),另一个比较深层次的 C 环境的初始化,这也是加分比较多的一点(价

    2024年02月14日
    浏览(35)
  • 【嵌入式】Thumb指令集(学习笔记)

    ARM开发工具完全支持Thumb指令,应用程序可以灵活的将ARM和Thumb子程序混合编程以便在例程的基础上提高性能或代码密度。在编写Thumb指令时,先要用伪指令CODE16声明(ADS的编译环境下),而且在ARM指令中要使用BX指令跳转到Thumb指令,以切换处理器状态。 Thumb指令集编码如下:

    2023年04月22日
    浏览(40)
  • 嵌入式学习笔记——SysTick(系统滴答)

    上一篇中,介绍了关于STM32F407的时钟系统,在了解了系统的时钟后,最重要的内容就是搞定定时器的操作,本文从最基本的定时器,也是内核里面自带的一个定时器——SysTick(系统滴答)来进行介绍。旨在搞清楚什么是系统滴答,系统滴答有什么用,系统滴答怎么用。 SysTick这

    2024年01月21日
    浏览(36)
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    最近在做直流电机的毕设中,由于需要采集转速,电流,电压,温度等参数,常规的采集容易受到干扰,所以特意复习了一下关于数字滤波有关的知识,并作出相应的整理。 本文对数字滤波进行简单介绍,讲解七种常用的滤波算法并用C语言实现,并比较其优缺点 。由于篇幅

    2023年04月22日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包