
f407vet6的, 需要其他我的封装类文件,如果有问题,请大家指证。 使用: SPI spi(SPI1);硬件模式 或者 SPI spi(new PORT(GPIOA,9)......)软件模式 spi.W(0xff) 写 spi.R() 读 ============spi.h #ifndef __MYSPI__ #define __MYSPI__ #include <base.h> class SPI { public: SPI(); SPI(PORT *MOSI,PORT *MISO,PORT *SDCK,u8 mode=0,u16 sp=0); SPI(SPI_TypeDef* spino,u8 mode=0,u16 sp=SPI_BaudRatePrescaler_2,u8 remap=0); void setMode(u8); void setSpeed(u16); u8 W(u8=0xff); u8 R(); u16 speed; SPI_InitTypeDef spiStruct; private : void InitSoft(PORT*,PORT*,PORT*,u16,u8); void InitHard(SPI_TypeDef*,u8,u8,u8 remap); u8 SRW(u8=0xff); u8 HRW(u8=0xff); u8 Mode; bool isSoft; SPI_TypeDef* spi; PORT *MOSI,*MISO,*SDCK; uint32_t rccspi; uint8_t afspi; void Init(); }; #endif =========spi.cpp #include "spi.h" #include "myfun.h" SPI::SPI(){} SPI::SPI(PORT *MOSI,PORT *MISO,PORT *SDCK,u8 mode,u16 sp) { InitSoft(MOSI,MISO,SDCK,sp,mode); } SPI::SPI(SPI_TypeDef* spino,u8 mode,u16 sp,u8 remap) { InitHard(spino,sp,mode,remap); } void SPI::InitSoft(PORT *_MOSI,PORT *_MISO,PORT *_sdck,u16 sp,u8 mode){ isSoft=true; Mode=mode; speed=sp; MOSI=_MOSI,MISO=_MISO,SDCK=_sdck; //MISO->setMode(GPIO_Mode_IN_FLOATING); MISO->setMode(GPIO_Mode_IN); MOSI->setMode(GPIO_Mode_OUT); SDCK->setMode(GPIO_Mode_OUT); (mode & 0x2)? SDCK->High():SDCK->Low(); } void SPI::InitHard(SPI_TypeDef* spino,u8 sp,u8 mode,u8 remap) { isSoft=false; Mode=mode; speed=sp; spi=spino; if (spi==SPI1) { afspi=GPIO_AF_SPI1; rccspi=RCC_APB2Periph_SPI1; if (remap==0) { MOSI=new PORT(GPIOA,7,GPIO_Mode_AF); MISO=new PORT(GPIOA,6,GPIO_Mode_AF); SDCK=new PORT(GPIOA,5,GPIO_Mode_AF); } else { MOSI=new PORT(GPIOB,5,GPIO_Mode_AF); MISO=new PORT(GPIOB,4,GPIO_Mode_AF); SDCK=new PORT(GPIOB,3,GPIO_Mode_AF); } } if (spi==SPI2) { afspi=GPIO_AF_SPI2; rccspi=RCC_APB1Periph_SPI2; if (remap==0) { MOSI=new PORT(GPIOB,15,GPIO_Mode_AF); MISO=new PORT(GPIOB,14,GPIO_Mode_AF); SDCK=new PORT(GPIOB,10,GPIO_Mode_AF); } if (remap==1) { MOSI=new PORT(GPIOC,3,GPIO_Mode_AF); MISO=new PORT(GPIOC,2,GPIO_Mode_AF); SDCK=new PORT(GPIOB,13,GPIO_Mode_AF); } if (remap==2) { MOSI=new PORT(GPIOI,3,GPIO_Mode_AF); MISO=new PORT(GPIOI,2,GPIO_Mode_AF); SDCK=new PORT(GPIOD,3,GPIO_Mode_AF); } } if (spi==SPI3) { afspi=GPIO_AF_SPI3; rccspi=RCC_APB1Periph_SPI3; if (remap==0) { MOSI=new PORT(GPIOB,5,GPIO_Mode_AF); MISO=new PORT(GPIOB,4,GPIO_Mode_AF); SDCK=new PORT(GPIOB,3,GPIO_Mode_AF); } if (remap==1) { MOSI=new PORT(GPIOC,12,GPIO_Mode_AF); MISO=new PORT(GPIOC,11,GPIO_Mode_AF); SDCK=new PORT(GPIOC,10,GPIO_Mode_AF); } } if (spi==SPI4) { afspi=GPIO_AF_SPI4; rccspi=RCC_APB2Periph_SPI4; if (remap==0) { MOSI=new PORT(GPIOE,6,GPIO_Mode_AF); MISO=new PORT(GPIOE,7,GPIO_Mode_AF); SDCK=new PORT(GPIOE,2,GPIO_Mode_AF); } if (remap==1) { MOSI=new PORT(GPIOE,14,GPIO_Mode_AF); MISO=new PORT(GPIOE,13,GPIO_Mode_AF); SDCK=new PORT(GPIOE,12,GPIO_Mode_AF); } } if (spi==SPI5) { afspi=GPIO_AF_SPI5; rccspi=RCC_APB2Periph_SPI5; if (remap==0) { MOSI=new PORT(GPIOF,9,GPIO_Mode_AF); MISO=new PORT(GPIOF,8,GPIO_Mode_AF); SDCK=new PORT(GPIOF,7,GPIO_Mode_AF); } if (remap==1) { MOSI=new PORT(GPIOF,11,GPIO_Mode_AF); MISO=new PORT(GPIOH,7,GPIO_Mode_AF); SDCK=new PORT(GPIOH,6,GPIO_Mode_AF); } } if (spi==SPI6) { afspi=GPIO_AF_SPI6; rccspi=RCC_APB2Periph_SPI6; MOSI=new PORT(GPIOG,14,GPIO_Mode_AF); MISO=new PORT(GPIOG,12,GPIO_Mode_AF); SDCK=new PORT(GPIOG,13,GPIO_Mode_AF); } Init(); } void SPI::Init() { SPI_InitTypeDef SPI_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<SDCK->PortNo, ENABLE);//使能GPIOA时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<MOSI->PortNo, ENABLE);//使能GPIOA时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA<<MISO->PortNo, ENABLE);//使能GPIOA时钟 if (spi==SPI2 || spi==SPI3) { RCC_APB1PeriphClockCmd(rccspi, ENABLE);//使能SPI23时钟 } else { RCC_APB2PeriphClockCmd(rccspi, ENABLE);//使能SPI1时钟 } GPIO_PinAFConfig(SDCK->GPIO,GPIO_PinSource0 +(SDCK->PinNo/2),afspi); //PB3复用为 SPI1 GPIO_PinAFConfig(MOSI->GPIO,GPIO_PinSource0+(MOSI->PinNo/2),afspi); //PB4复用为 SPI1 GPIO_PinAFConfig(MISO->GPIO,GPIO_PinSource0+(MISO->PinNo/2),afspi); //PB5复用为 SPI1 //这里只针对SPI口初始化 //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1 //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL =Mode &0x2;// SPI_CPOL_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA =Mode &0x1 ;// SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler =speed;// SPI_BaudRatePrescaler_4; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(spi, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(spi, ENABLE); //使能SPI外设 } u8 SPI::W(u8 d) { return isSoft?SRW(d):HRW(d); } u8 SPI::R() { return isSoft?SRW():HRW(); } u8 SPI::HRW(u8 d) { u8 retry=0; while (SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位 { retry++; if(retry>200)return 0; } SPI_I2S_SendData(spi, d); //通过外设SPIx发送一个数据 retry=0; while (SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位 { retry++; if(retry>200)return 0; } return SPI_I2S_ReceiveData(spi); //返回通过SPIx最近接收的数据 } void SPI::setMode(u8 mode) { if (isSoft) Mode=mode; else { u16 r=spi->CR1 & 0xfffc; spi->CR1=r | mode; } } void SPI::setSpeed(u16 sp) { if (isSoft) { speed=sp; }else{ spi->CR1 &=0xffc7; spi->CR1 |=sp; SPI_Cmd(spi,ENABLE); } } u8 SPI::SRW(u8 d) { u8 i=8; u8 r=0; switch(Mode) { case 0: //CPOL=0 ,CPHA=0 while(i--) { r<<=1; if (MISO->Read()) r++; (d & 0x80)? MOSI->High():MOSI->Low(); SDCK->High(); delay_nop(speed); d<<=1; SDCK->Low(); delay_nop(speed); } break;; case 2://CPOL=1,CPHA=0 while(i--) { r<<=1; if (MISO->Read()) r++; (d & 0x80) ?MOSI->High():MOSI->Low(); SDCK->Low(); d<<=1; SDCK->High(); } break; case 1: //CPOL=0,CPHA=1 while(i--) { SDCK->High(); r<<=1; if (MISO->Read()) r++; (d & 0x80) ?MOSI->High():MOSI->Low(); SDCK->Low(); d<<=1; } break; case 3: //CPOL=1,CPHA=1 while(i--) { r<<=1; (d & 0x80)?MOSI->High():MOSI->Low(); delay_nop(speed); SDCK->Low(); delay_nop(speed); SDCK->High(); if (MISO->Read()) r++; d<<=1; } break; } return r; } |
学习了,用类和对象操作 |
你的SPI名称空间怎么不发出来啊 |
我是复制的代码,没有设置名称空间。 |