IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> GD32F103配置SPI+DMA收发数据 -> 正文阅读

[嵌入式]GD32F103配置SPI+DMA收发数据

??GD32是国产的32位单片机,它和STM32非常非常像,就连以前的库函数都差不多(现在从GD官网下载的库函数换了一种风格)。配置SPI和DMA的方法和STM32差不多。

DMA0各通道请求表??上图是DMA0各通道请求表,SPI0的收发分别用了通道1和通道2,我们就配置SPI0。

配置SPI0(或者说SPI1,GD的命名顺序让人闹心)

#define SPI1_CS_HIGH() (GPIOA->BOR = GPIO_PIN_4)
#define SPI1_CS_LOW()  (GPIOA->BCR = GPIO_PIN_4)
void SPI1Init(void)
{
	GPIO_InitPara GPIO_InitStructure;
	SPI_InitPara SPI_InitStructure;
	
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_SPI0);
	//GD32的外设命名顺序很烦人,它的手册上都是从0开始数的,到了代码里,使能时钟这里是从0数,到后面又是从1数了
	/* SPI1_SCK(PA5), SPI1_MISO(PA6) and SPI1_MOSI(PA7) GPIO pin configuration */
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5 | GPIO_PIN_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	/* SPI1_CS(PA4) GPIO pin configuration */
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	/* chip select invalid*/
	SPI1_CS_HIGH();
	/* SPI1 parameter config */
	SPI_InitStructure.SPI_TransType = SPI_TRANSTYPE_FULLDUPLEX;
	SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;
	SPI_InitStructure.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT;
	SPI_InitStructure.SPI_SCKPL = SPI_SCKPL_LOW;
	SPI_InitStructure.SPI_SCKPH = SPI_SCKPH_1EDGE;
	SPI_InitStructure.SPI_SWNSSEN = SPI_SWNSS_SOFT;
	SPI_InitStructure.SPI_PSC = SPI_PSC_4;
	SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
	SPI_InitStructure.SPI_CRCPOL = 7;
	SPI_Init(SPI1, &SPI_InitStructure);//这里变成的SPI1了,没有SPI0
	/* enable SPI1 */
	SPI_Enable(SPI1, ENABLE);
}

unsigned char SPI1ReadWriteByte(unsigned char byte)
{
	/* loop while data register in not emplty */
	while (RESET == SPI_I2S_GetBitState(SPI1,SPI_FLAG_TBE));
	/* send byte through the SPI0 peripheral */
	SPI1->DTR = byte;
	/* wait to receive a byte */
	while(RESET == SPI_I2S_GetBitState(SPI1,SPI_FLAG_RBNE));
	/* return the byte read from the SPI bus */
	return (SPI1->DTR);
}

配置DMA0

void SPI1DMAInit(void)	//DMA0 (count from 0) Channel3 (count from 1)
{
	DMA_InitPara DMA_InitStructure;
//	NVIC_InitPara NVIC_InitParaStruct;	//没用上中断
	
	rcu_periph_clock_enable(RCU_DMA0);
	//Tx_DMA
	DMA_DeInit(DMA1_CHANNEL3);	
	DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(SPI1->DTR);
	DMA_InitStructure.DMA_MemoryBaseAddr = 0;	//内存地址待定,启动传输时配置
	DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
	DMA_InitStructure.DMA_BufferSize = 0;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
	DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;	//收发通道都配成内存地址递增就行
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;
	DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
	DMA_InitStructure.DMA_Priority = DMA_PRIORITY_MEDIUM;
	DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
	
//	NVIC_InitParaStruct.NVIC_IRQ = DMA1_Channel3_IRQn;
//	NVIC_InitParaStruct.NVIC_IRQPreemptPriority = 0;
//	NVIC_InitParaStruct.NVIC_IRQSubPriority = 2;
//	NVIC_InitParaStruct.NVIC_IRQEnable = ENABLE;
//	NVIC_Init(&NVIC_InitParaStruct);
//	NVIC_EnableIRQ(DMA1_Channel3_IRQn);
	
	DMA_Init(DMA1_CHANNEL3, &DMA_InitStructure);
	DMA_ClearIntBitState(DMA1_INT_TC3);
	//DMA_INTConfig(DMA1_CHANNEL3, DMA_INT_TC, ENABLE);
	
	//Rx_DMA
	DMA_DeInit(DMA1_CHANNEL2);
	DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC;
	DMA_InitStructure.DMA_BufferSize = 0;
	DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
	
//	NVIC_InitParaStruct.NVIC_IRQ = DMA1_Channel2_IRQn;
//	NVIC_InitParaStruct.NVIC_IRQPreemptPriority = 0;
//	NVIC_InitParaStruct.NVIC_IRQSubPriority = 2;
//	NVIC_InitParaStruct.NVIC_IRQEnable = ENABLE;
//	NVIC_Init(&NVIC_InitParaStruct);
//	NVIC_EnableIRQ(DMA1_Channel2_IRQn);
	
	DMA_Init(DMA1_CHANNEL2, &DMA_InitStructure);
	DMA_ClearIntBitState(DMA1_INT_TC2);
	//DMA_INTConfig(DMA1_CHANNEL2, DMA_INT_TC, ENABLE);
}

void SPI1TxDMAEnable(unsigned int mem_addr, unsigned int buf_size)
{
	//tx
	DMA_Enable(DMA1_CHANNEL3, DISABLE);
	while(DMA_GetCmdStatus(DMA1_CHANNEL3));
	DMA_SetCurrDataCounter(DMA1_CHANNEL3, buf_size);	//设置传输数据字节数
	DMA_MemoryTargetConfig(DMA1_CHANNEL3, mem_addr);	//设置内存地址
	SPI_I2S_DMA_Enable(SPI1, SPI_I2S_DMA_TX, ENABLE);
	//rx
	DMA_Enable(DMA1_CHANNEL2, DISABLE);
	while(DMA_GetCmdStatus(DMA1_CHANNEL2));
	DMA_SetCurrDataCounter(DMA1_CHANNEL2, buf_size);
	DMA_MemoryTargetConfig(DMA1_CHANNEL3, mem_addr);	//接收通道的内存地址和发送通道设置成一样的,之前的数据被覆盖前已经通过发送通道发出去了
	SPI_I2S_DMA_Enable(SPI1, SPI_I2S_DMA_RX, ENABLE);
	//enable
	DMA1_CHANNEL2->CTLR |= DMA_CTLR_CHEN;	//DMA Enable
	DMA1_CHANNEL3->CTLR |= DMA_CTLR_CHEN;	//DMA Enable
	while(!DMA_GetIntBitState(DMA1_INT_TC2));
	DMA_ClearIntBitState(DMA1_INT_TC2);
	while(!DMA_GetIntBitState(DMA1_INT_TC3));
	DMA_ClearIntBitState(DMA1_INT_TC3);
}

??上面代码中函数SPI1TxDMAEnable(unsigned int mem_addr, unsigned int buf_size)用来启动一次DMA传输,RX通道和TX通道的内存地址配成同一个就行,因为SPI的数据收发是在一个时钟控制下同时进行,内存的变量被读入的数据覆盖之前已经被发送出去了,不用担心内存数据被覆盖而发生错误。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:38:02  更:2021-08-21 15:39:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 3:29:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码