DSP2808与ARM STM32F103的SPI通讯例程及详解
来源:互联网 发布:中国省份数据库 编辑:程序博客网 时间:2024/06/15 18:27
本程序经验证可实现DSP和ARM的SPI通讯。
一、 SPI的通信协议
SPI(Serial Peripheral Interface)是一种串行同步通讯协议,由一个主设备和一个或多个从设备组成,主设备启动一个与从设备的同步通讯,从而完成数据的交换。SPI 接口一般由4根线组成,CS片选信号(有的单片机上也称为NSS),SCLK时钟信号线,MISO数据线(主机输入从机输出),MOSI数据线(主机输出从机输入),CS 决定了唯一的与主设备通信的从设备,如没有CS 信号,则只能存在一个从设备,主设备通过产生移位时钟信号来发起通讯。通讯时主机的数据由MISO输入,由MOSI 输出,输入的数据在时钟的上升或下降沿被采样,输出数据在紧接着的下降或上升沿被发出(具体由SPI的时钟相位和极性的设置而决定)。
串行协议框图
二、 例程
DSP TMS320F2808PZA做主机,ARM STM32F103VCT6做从机实现两芯片的SPI通讯。
1、 ARM从机例程。
ARM使用SPI1且工作于从模式。从机的SPI一直都是处于等待状态,一旦主机有数据发送过来,从机立即进入中断进行接收。接收数据的同时也向主机发送数据。
void SPI_Init_user(void) //SPI1配置函数{ SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* 使能 GPIOA 时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /*SPI1外设时钟开 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /*引脚配置*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出,复用模式的输入输出由程序决定。 GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1 工作方式配置 */ SPI_Cmd(SPI1, DISABLE); //配置前先关闭SPI SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工工作模式。 SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; //设置SPI1为从模式。 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //数据位16位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //空闲时刻为高,DSP那边也设为高。 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //时钟相位,数据在第2个跳边沿被采集 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //CS引脚为软模式,即通过程序控制片选脚。 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //256分频为波特率,因为波特率是由主机提供的。所以在这里设置没有意义。 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//先传高字节,因为DSP只有高字节传送这种方式,所以这里要设置为高字节在前。不然就乱了。 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多项式不设置,默认。 SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); /* 使能 SPI1 */ SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); //接收缓冲区数据非空中断,开启接收中断。}中断优先级配置void NIV(void){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn; //SPI1通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道使能NVIC_Init(&NVIC_InitStructure); }中断服务程序void SPI1_IRQHandler(void) //SPI中断服务程序 {static u16 b=0; OSIntEnter(); //有UCOS操作系统时加上这条 GPIO_SetBits(GPIOE, GPIO_Pin_5); //只是一个指示灯,做测试用 if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_RXNE) == SET) // 接收区数据非空 { SPI_I2S_ClearITPendingBit( SPI1 , SPI_I2S_IT_RXNE ) ; //清标志位 rdata_SPI[b]=SPI_I2S_ReceiveData(SPI1); //接收数据,放在rdata_SPI。 SPI_I2S_SendData(SPI1, sdata[b]); // 发送数据b++; if(b==16)b=0;} OSIntExit(); //有UCOS操作系统时加上这条 }
2、 DSP主机例程。
DSP使用SPIA且工作于主机模式。使用定时发送的方式给从机发数据。
SPIA_GPIO引脚初始化
void InitSpiaGpio(){ EALLOW; GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA) GPIO16设置为异步脚 GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA) GPIO17设置为异步脚 GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA) GPIO18设置为异步脚 GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA) GPIO19设置为异步脚 GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA 配置GPIO16为SPI_SIMO GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA 配置GPIO17为SPI_SOMI GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA 配置GPIO18为SPI_CLK GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA 配置GPIO19为SPI_STE(NSS 或CSS) EDIS;}SPI_FIFO初始化void spi_fifo_init(void){ SpiaRegs.SPIFFTX.all=0xE040; //使能SPIFIFO功能;TXFIFO复位;清除 TXFF INT 中断位;TXFIFO 中 断不使能; SpiaRegs.SPIFFRX.all=0x204f; //重新使能接收 FIFO 操作;清RXFIFO中断标志位;中断不使能。 SpiaRegs.SPIFFCT.all=0x0; //这个寄存器是设置FIFO延时的,不需要用到。}SPI工作方式配置void spi_init(void){ SpiaRegs.SPICCR.all =0x004F; // 复位,下降沿发送,上升沿接收(即时钟极性是:空闲时为高电平), 字长16位。关闭SPI内部LOOP BACK 禁止回送 SpiaRegs.SPICTL.all =0x0006; // 主机模式, 时钟相位为正常相位, SpiaRegs.SPICTL.bit.CLK_PHASE=0; //TALK=1使能主机发送, SPI中断不使能. 时钟相位为:数据在第2个时钟边沿被选择 SpiaRegs.SPIBRR =0x007F; //波特率=195.3KHz 。波特率=LSPCLK/(SPIBRR+1)=25MHz/128=195.3KHz //SpiaRegs.SPIBRR=24; //Baud=25M/(24+1)=1M 波特率太大的话,SCK只有一个脉冲出来SpiaRegs.SPICCR.all =0x00CF; //下降沿发送,上升沿接收(即时钟极性是:空闲时为高电平), 字长16位。准备发送或接收 禁止回送模式SPILBK=0 SpiaRegs.SPIPRI.bit.FREE = 1; //仿真用的}在主程序中定时500ms向从机发送数据,时间可由自己定。即每500ms调用下面函数一次。void SPI_service(){ int16 j,tmp; sdata[0]=0x0c; //数据帖头 sdata[1]=TEMP; //温度采样值发去ARM显示 for ( j=0;j<16;j++ ) { tmp=sdata[j]; SpiaRegs.SPITXBUF=tmp; //发送数据 while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { } //接收FIFO为空时,等待! // 检查返回数据 rdata_SPI[j] = SpiaRegs.SPIRXBUF; if(rdata_SPI[1]==0x0c) //收到正确的帖头 { for(h=0;h<16;h++) { rdata[h]=rdata_SPI[h]; } } } }
0 0
- DSP2808与ARM STM32F103的SPI通讯例程及详解
- STM32F103与STM32F407的SPI调试笔记
- STM32F4-Discovery LCD1602驱动及例程,改编自www.armjishu.com提供的STM32F103例程
- kinetis的SPI例程
- at91sam7x256与ads1256/ads1255的SPI通讯
- stm32 spi的测试例程
- STM32F103的CAN 通信之通讯协议
- io口spi模拟主从机通讯例程
- 2410 spi 与 DSP vc33 serial 的通讯:
- LM3S1138与Mega32,Tiny13间的SPI通讯
- 基于AM335X与FPGA的SPI通讯设计
- ARM的SPI总结
- 详解ARM的优势及与单片机的区别
- 基于CC2640的SPI通讯
- STM32F103 SDIO Sdcard驱动以及例程的问题
- ARM与射频芯片TRF796x的SPI通信研究
- ARM与射频芯片TRF796x的SPI通信研究
- SPI详解及SPI接口flash举例
- 山东省第七届ACM省赛 Triple Nim
- 删除数据
- Android 根据文件Uri找文件路径 和根据路径找文件Uri
- 往mysql中插入 自增id不连续(曾经的坑)
- Kth Smallest Element in a BST
- DSP2808与ARM STM32F103的SPI通讯例程及详解
- PowerDesigner16.5快速入门显示,注释comment配置方法,以及创建sql文件过程中需要注意的一些问题
- Unknown module(s) in QT: multimedia
- CCF NOI1015 星期几
- 几种决策树学习算法比较
- Leetcode 290. Word Pattern
- oracle存储过程中的while loop循环示例
- 刷新当前目录下所有文件的shell脚本
- 435. Non-overlapping Intervals