完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
其实stm32本身的硬件SPI也很好用,但是还是想用软件来模拟一下PSI的时序。 SPI 是一种高速的,全双工,同步串行的通信总线。SPI通信方式相当于是一个环形结构,由CSN、MISO、MOSI、SCLK四线组成,主要是在SCLK时钟线的驱动下,进行数据转换。 接下来直接上程序配置: 使用32模拟SPI时序的IO口配置,应该注意的是MISO应该选择模拟输入方式GPIO_Mode_IN_FLOATING。 以下是我的初始化部分: /*用于软件模拟SPI IO口宏定义区*/ #define SPI_CS_PORT GPIOB #define SPI_CS_PIN GPIO_Pin_11 #define SPI_CS_LOW (SPI_CS_PORT->BRR |=SPI_CS_PIN) #define SPI_CS_HIGH (SPI_CS_PORT->BSRR |=SPI_CS_PIN) #define SPI_SCK_PORT GPIOA #define SPI_SCK_PIN GPIO_Pin_12 #define SPI_SCK_LOW (SPI_SCK_PORT->BRR |=SPI_SCK_PIN) #define SPI_SCK_HIGH (SPI_SCK_PORT->BSRR|=SPI_SCK_PIN) #define SPI_MISO_PORT GPIOA #define SPI_MISO_PIN GPIO_Pin_8 #define SPI_MISO_LOW (SPI_MISO_PORT->BRR |=SPI_MISO_PIN) #define SPI_MISO_HIGH (SPI_MISO_PORT->BSRR|=SPI_MISO_PIN) #define SPI_MISO_READ (SPI_MISO_PORT->IDR &SPI_MISO_PIN) #define SPI_MOSI_PORT GPIOA #define SPI_MOSI_PIN GPIO_Pin_11 #define SPI_MOSI_LOW (SPI_MOSI_PORT->BRR |=SPI_MOSI_PIN) #define SPI_MOSI_HIGH (SPI_MOSI_PORT->BSRR|=SPI_MOSI_PIN) void SPI_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); //CS GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=SPI_CS_PIN; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(SPI_CS_PORT, &GPIO_InitStruct); //SCK GPIO_InitStruct.GPIO_Pin=SPI_SCK_PIN; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(SPI_SCK_PORT,&GPIO_InitStruct); //MISO GPIO_InitStruct.GPIO_Pin=SPI_MISO_PIN; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(SPI_MISO_PORT,&GPIO_InitStruct); //MOSI GPIO_InitStruct.GPIO_Pin=SPI_MOSI_PIN; GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(SPI_MOSI_PORT,&GPIO_InitStruct); SPI_CS_HIGH; SPI_SCK_LOW; } 模拟SPI时序 u8 SPI_RW(u8 data) { u8 i; SPI_SCK_LOW; //先将时钟线拉低 for(i=0;i<8;i++) { if((data&0x80)==0x80) //从高位发送 { SPI_MOSI_HIGH; } else { SPI_MOSI_LOW; } SPI_SCK_HIGH; //将时钟线拉高,在时钟上升沿,数据发送到从设备 data<<=1; if(SPI_MISO_READ) //读取从设备发射的数据 { data|=0x01; } SPI_SCK_LOW; //在下降沿数据被读取到主机 } return data; //返回读取到的数据 } 写寄存器操作:` u8 SPI_Moni_Write_Reg(u8 Reg,u8 data) { u8 states; SPI_CS_LOW; //先将CSN拉低 states=SPI_RW(Reg); //写入寄存器的地址,即图中的Cn位,并读取状态位 SPI_RW(data); // 要写入的数据 SPI_CS_HIGH; return states; } 读寄存器操作: u8 SPI_Moni_Read_Reg(u8 Reg) { u8 data; SPI_CS_LOW; SPI_RW(Reg); //先写入寄存器的地址 data=SPI_RW(0); //通过写入无效数据0,将从设备上的数据挤出来 SPI_CS_HIGH; return data; } 接下来就是写缓冲区、读缓冲区函数 了: u8 SPI_Moni_Write_Buf(u8 Reg,u8 *Buf,u8 len) { u8 states; SPI_CS_LOW; states=SPI_RW(Reg); while(len>0) { SPI_RW(*Buf); Buf++; len--; } SPI_CS_HIGH; return states; } u8 SPI_Moni_Read_Buf(u8 Reg,u8 *Buf,u8 len) { u8 states; SPI_CS_LOW; states=SPI_RW(Reg); while(len>0) { *Buf=SPI_RW(0); Buf++; len--; } SPI_CS_HIGH; return states; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1786 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1622 浏览 1 评论
1089 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
730 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1941浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
738浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
571浏览 3评论
598浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
560浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 09:07 , Processed in 1.288081 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号