初学STM32,非常不好意思,我问的问题可能有些2和有些多,我把网上我搜集到的信息也都写出来了,希望可以一起探讨一下,。。。另外再次感谢热心帮助我的热心网友,我的分数只有这个多可以奖励了,,,,不吝笑纳。。。 网上看了一下,似乎GPIO模拟SPI比GPIO模拟I2C简单一些, 大部分I2C有不少函数封装他的时序,注释都是自带的,没改过,有几个问题想讨论一下 1. SPI一般就两个函数貌似,一个init,一个CPOL和CHPA组合出来的四种时序之一,写出ReadWrite函数,写出来了就可以直接用的样子,请问是这样吗 2. 我还想请问一下请问一下,为什么下面MOSI的脚要用模拟输入? 3. 我还想请问一下,下面的SPIx_FLASH_SendByte中有一句 { GPIO_SetBits(GPIOC, GPIO_Pin_7); // //SO=1 } 为什么每次循环都要改变,根据他的初始化,这个是片选的,片选的脚每次都要根据数据改变吗?不是SDO根据数据改变吗? 我的思路是这样的,一根MOSI是设置输出,一根MISO设置输入,还有CS和时钟, 1)时钟根据CPOL和CHPA来配置,分别配置为空闲和采样的边沿 2)MOSI每输出一个位,就从MISO接收一个位,配合时钟搞 3)MOSI的时候CS(就是SS)=0,MISO的时候CS(就是SS)=1 4)循环8次以后,发送完也接收完了,就OK了。。 5)也就是一共两个函数, 一个init,配置输入输出什么的,还有一个是读写同步的一个ReadWrite函数。 5.大致看一下下面的代码的话? 可以照着搞一搞吗? void SPI_FLASH_Init1(void)//io初始化配置 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);//初始化A和C的时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_9;//CS片选 CLK时钟,都是输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;//GPIOC_PIN8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //MOSI用了模拟输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//GPIOA_PIN8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//MISO GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } //关键在读取函数 //包括读取和发送 u8 SPIx_FLASH_SendByte(u8 byte) { uint8_t i; u8 Temp=0x00;//临时变量 unsigned char SDI; //输入进来的char for (i = 0; i < 8; i++) { GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;//先将时钟拉高 if (byte&0x80) //看看最高位是否是1 { GPIO_SetBits(GPIOC, GPIO_Pin_7); // //SO=1 } else { GPIO_ResetBits(GPIOC, GPIO_Pin_7);// //SO=0 } byte <<= 1; GPIO_ResetBits(GPIOC, GPIO_Pin_9);// //sclk = 1; 拉低时钟 SDI = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8);//判断si是否有输入 Temp<<=1; if(SDI) //读到1时 { Temp++; //置1 即向右移动一位同时加1 因上边有<<=1 } GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;// 拉高时钟 } return Temp; //返回读到miso输入的值 } |
首先一点,SPIx_FLASH_SendByte()函数并不包含CS引脚的控制。
SO是数据输出引脚。
如果只看输出,函数为
SendByte(byte)
{
for(i=0;i<8;i++){
if (byte & 0x80) SO = 1;
else SO = 0;
SCLK = 0;
SCLK = 1;
byte <<= 1;
}
}
其中(byte & 0x80)是取当前的最高bit,要看到后面的移位操作byte <<= 1;
正好借楼和楼主的帖子问一下,
你这个byte是不理会receivce的数据,而其实是有数据的吧?
另外麻烦请问一下,SPI是以位为单位全双工的还是字节为单位双工的