历史上的今天
今天是:2025年01月16日(星期四)
2019年01月16日 | STM32F051 SPI slave mode DMA接收
2019-01-16 来源:eefocus
用STM32F051的SPI从模式接收主机发送的实时数据。
Eclips 环境,gcc编译器,相关源码如下:
#ifdef DEBUG_SPI_EN
#define DEBUG_SPI(...) printf(__VA_ARGS__)
#else
#define DEBUG_SPI(...)
#endif
void SPI1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
// SPI1 port
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_0);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_0);
// SPI1 config
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
SPI_I2S_DeInit(SPI1);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SCLK = 12.0MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, DISABLE);
}
void SPI1_DMA_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
}
void SPI1_DMA_Config(uint8_t *pbuff, uint16_t nbytes)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel2);
DMA_StructInit(&DMA_InitStructure);
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr= SPI1_BASE + 0x0C;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pbuff;
DMA_InitStructure.DMA_BufferSize = nbytes;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // from SPI
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_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
SPI1_DMA_NVIC_Config();
}
void SPI1_Read_Starting(uint8_t *pbuff, uint16_t nbytes)
{
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA1_Channel2->CNDTR = nbytes;
DMA1_Channel2->CPAR = SPI1_BASE + 0x0C;
DMA1_Channel2->CMAR = (uint32_t)pbuff;
DMA_Cmd(DMA1_Channel2, ENABLE);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
SPI_Cmd(SPI1, ENABLE);
}
void SPI1_Read_Stop(void)
{
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE);
SPI_Cmd(SPI1, DISABLE);
}
/*
* SPI1_RX & SPI1_TX DMA Interrupt
*/
void DMA1_Channel2_3_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC2) != RESET)
{
DEBUG_SPI(">>");
; // 接收数据处理,略去...
;
DMA_ClearITPendingBit(DMA1_FLAG_TC2);
}
/*
if(DMA_GetFlagStatus(DMA1_FLAG_TC3) != RESET)
{
DMA_ClearITPendingBit(DMA1_FLAG_TC3);
}*/
}
/*
* 片选中断设置
*/
void SPI1_NSS_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource15);
EXTI_InitStructure.EXTI_Line = EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // _Rising _Falling _Rising_Falling
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0; // Low Medium Hight VeryHigh: 0 - 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line15);
}
void EXTI4_15_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line15) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line15);
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15);
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) == RESET)
{
SPI1_Read_Starting(&dmaBuffPoll[0], FRAME_BYTES); // startup SPI1 Data receive-only
}
}
}
起初,SPI设成“1-line bidirectional data mode selected”模式,接收到的数据全为“0”,找了很久的原因,无果;
改为“Receive-only mode”后,一切正常!
下一篇:stm32 spi从模式配置解答
史海拾趣
|
我们已经开发了PXA310的开发板,还有必要开发三星的6410吗? 随着智能手机和PDA的使用越来越广泛,各大厂家都纷纷推出芯片方案。其中最为脱出还是以Samsung 和Marvell 两家公司。 Marvell自从收购了Intel 的的通信和应用处理器Xscale业务后,非常关注这块业务,并且于2007年12月份发布其新一代的应用处理器— ...… 查看全部问答> |
|
我有5个由中断直接连接的按键,请问如何识别是哪个管脚产生的中断啊? 其中两个键触发的沿是上升沿和下降沿交替触发的,三个按键是下降沿触发的,我把它们放在一个中断服务程序中了,由于其中一个制约其他的发出消息,现在我不知道如何识别是哪个管脚产生的这个沿导致产生的中断,请教各位了。… 查看全部问答> |
|
请问大侠s: 一个编译器中如何才能支持fopen等I/O操作呢?是不是C库中必须要包含相关的C库,我现在使用MDK的IDE,它内部有个自己的文件系统,但是我在SDRAM中调试运行的时候,发现运行fopen函数后,程序就跑飞了。我怀疑是fopen库函 ...… 查看全部问答> |
|
各大LED生产商在上游磊晶技术上不断改进,如利用不同的电极设计控制电流密度,利用ITO薄膜技术令通过LED的电流能平均分布等,使在结构上都尽可能产生最多的。再运用各种不同方法去抽出LED发出的每一粒光子,如生产不同外形的芯片;利用芯片周边有效 ...… 查看全部问答> |
|
用430 产生一个spwm,我用的是规则采样,当载波比设置为129的时候波形正常,一旦超过129就会失真,如果设置成500那正弦波直接变为尖峰。不知道为什么,请教各位大神啊!!!!!!! 下面是我的程序: void Init(){ MyClkInit(); Chang ...… 查看全部问答> |
|
易电源试用心得2 对于易电源模块LMZ10504TZ的带载能力非常出色。它的输入是2.95-5.5V,输出是2.5V.因此可以看出该模块的输入电压范围很大,输出电压稳定。从电力电子知识看可以知道这是一种BUCK电路,即降压 ...… 查看全部问答> |




