中级会员
 
- 积分
- 235
- 金钱
- 235
- 注册时间
- 2018-12-9
- 在线时间
- 94 小时
|
1金钱
本帖最后由 szddd 于 2019-8-6 14:49 编辑
大家好,在用H743调SPI1口,借鉴了正点原子的"实验36 无线通信实验"例程,里面用的是SPI2口,将里面的寄存器改成SPI1后,SPI口死活不工作,查了快2天,实在是没招了,有谁能帮我看下,我的程序那有问题吗?
//以下是SPI模块的初始化代码,配置成主机模式
//SPI口初始化
//这里针是对SPI2的初始化
void SPI1_Init(void)
{
u32 tempreg=0;
RCC->AHB4ENR|=1<<0; //使能PORTA时钟
RCC->APB2LPENR|=1<<12; //SPI1时钟使能
// PA4:NSS PA5:SCL PA6:MISO PA7:MOSI
GPIO_Set(GPIOA,PIN4,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_MID,GPIO_PUPD_PU); //输出功能,上拉输出
GPIO_Set(GPIOA,PIN5|PIN6|PIN7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_MID,GPIO_PUPD_PU);//复用功能,上拉输出
GPIO_AF_Set(GPIOA,5,5); //PA5,AF5 注意:第3个参数是引脚功能定义,需要查找芯片数据手册看是功能几
GPIO_AF_Set(GPIOA,6,5); //PA6,AF5 注意:第3个参数是引脚功能定义,需要查找芯片数据手册看是功能几
GPIO_AF_Set(GPIOA,7,5); //PA7,AF5 注意:第3个参数是引脚功能定义,需要查找芯片数据手册看是功能几
//配置SPI的时钟源
RCC->D2CCIP1R&=~(7<<12); //SPI123SEL[2:0]=0,清除原来的设置
RCC->D2CCIP1R|=0<<12; //SPI123SEL[2:0]=1,选择pll1_q_ck作为SPI1/2/3的时钟源,一般为200Mhz
//即:spi_ker_ck=200Mhz
//这里只针对SPI口初始化
RCC->APB2RSTR|=1<<12; //复位SPI1
RCC->APB2RSTR&=~(1<<12); //停止复位SPI1
SPI1->CR1|=1<<12; //SSI=1,设置内部SS信号为高电平
SPI1->CFG1=7<<28; //MBR[2:0]=7,设置spi_ker_ck为256分频.
SPI1->CFG1|=7<<0; //DSIZE[4:0]=7,设置SPI帧格式为8位,即字节传输
tempreg=(u32)1<<31; //AFCNTR=1,SPI保持对IO口的控制
tempreg|=0<<29; //SSOE=0,禁止硬件NSS输出
tempreg|=1<<26; //SSM=1,软件管理NSS脚
tempreg|=1<<25; //CPOL=1,空闲状态下,SCK为高电平
tempreg|=1<<24; //CPHA=1,数据采样从第2个时间边沿开始
tempreg|=0<<23; //LSBFRST=0,MSB先传输
tempreg|=1<<22; //MASTER=1,主机模式
tempreg|=0<<19; //SP[2:0]=0,摩托罗拉格式
tempreg|=0<<17; //COMM[1:0]=0,全双工通信
SPI1->CFG2=tempreg; //设置CFG2寄存器
SPI1->I2SCFGR&=~(1<<0); //选择SPI模式 0:SPI模式 1:I2S/PCM 模式
SPI1->CR1|=1<<0; //SPE=1,使能SPI2
SPI1->CR1|=1<<9; //CSTART=1,启动传输
SPI1_SetSpeed(1);
SPI1_ReadWriteByte(0xff); //启动传输
}
//SPI2速度设置函数
//SpeedSet:0~7
//SPI速度=spi_ker_ck/2^(SpeedSet+1)
//spi_ker_ck我们选择来自pll1_q_ck,为200Mhz
void SPI1_SetSpeed(u8 SpeedSet)
{
SpeedSet&=0X07; //限制范围
SPI1->CR1&=~(1<<0); //SPE=0,SPI设备失能
SPI1->CFG1&=~(7<<28); //MBR[2:0]=0,清除原来的分频设置
SPI1->CFG1|=(u32)SpeedSet<<28; //MBR[2:0]=SpeedSet,设置SPI2速度
SPI1->CR1|=1<<0; //SPE=1,SPI设备使能
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 RxData=0;
while((SPI1->SR&1<<1)==0); //等待发送区空
*(vu8 *)&SPI1->TXDR=TxData; //发送一个byte,以传输长度访问TXDR寄存器
while((SPI1->SR&1<<0)==0); //等待接收完一个byte
RxData=*(vu8 *)&SPI1->RXDR; //接收一个byte,以传输长度访问RXDR寄存器
SPI1->IFCR|=3<<3; //EOTC和TXTFC置1,清除EOT和TXTFC位
return RxData; //返回收到的数据
}
|
|