历史上的今天
今天是:2024年10月17日(星期四)
2019年10月17日 | STM32 3个硬件SPI的使用
2019-10-17 来源:eefocus
硬件平台:STM32F103
SPI1初始化过程
static OS_EVENT *spi1_sem_event;
static void SPI1SemInit(void)
{
spi1_sem_event = OSSemCreate(1);
}
extern void SPI1SemGet(void)
{
uint8_t err;
OSSemPend(spi1_sem_event, 0, &err);
}
extern void SPI1SemPut(void)
{
OSSemPost(spi1_sem_event);
}
static void Spi1_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIO clocks */
/*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,
SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO
and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */
/*!< SPI_FLASH_SPI Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/*!< AFIO Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/*!< Configure SPI_FLASH_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin = PIN_SPI1_SCLK;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(PORT_SPI1_SCLK, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI pins: MISO */
GPIO_InitStructure.GPIO_Pin = PIN_SPI1_MISO;
GPIO_Init(PORT_SPI1_MISO, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI pins: MOSI */
GPIO_InitStructure.GPIO_Pin = PIN_SPI1_MOSI;
GPIO_Init(PORT_SPI1_MOSI, &GPIO_InitStructure);
/* SPI1 configuration */
// W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.
// Data on the DO and DIO pins are clocked out on the falling edge of CLK.
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位帧结构
#if 0
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
#else
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第1个时钟沿
#endif
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//定义波特率预分频的值:波特率预分频值为2
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
SPI1SemInit();
}
extern void SPI1_SetSpeed(u8 SpeedSet)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//如果速度设置输入0,则低速模式,非0则高速模式
if(SpeedSet == 1)
{
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
}
else
{
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
}
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
}
extern void spi1WriteData(Uchar *buf,Uint len)
{
for (; len ; len--,buf++)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, *buf);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
}
}
extern u8 SPI1_Swap_DataMSB(u8 byte)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, byte); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
SPI2初始化过程
static OS_EVENT *spi2_sem_event;
static void SPI2SemInit(void)
{
spi2_sem_event = OSSemCreate(1);
}
extern void SPI2SemGet(void)
{
uint8_t err;
OSSemPend(spi2_sem_event, 0, &err);
}
extern void SPI2SemPut(void)
{
OSSemPost(spi2_sem_event);
}
extern void Spi2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/*!< AFIO Periph clock enable */
//RCC_APB2PeriphClockCmd(RCC_APB1Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = PIN_SPI2_SCLK;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(PORT_SPI2_SCLK, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_SPI2_MISO;
GPIO_Init(PORT_SPI2_MISO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_SPI2_MOSI;
GPIO_Init(PORT_SPI2_MOSI, &GPIO_InitStructure);
/* SPI2 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
#if 1
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
#else
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第1个时钟沿
#endif
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* Enable SPI2 */
SPI_Cmd(SPI2, ENABLE);
SPI2SemInit();
}
/*******************************************************************************
* Function Name : SPI_SetSpeed
* Description : SPI设置速度为高速
* Input : u8 SpeedSet
* 如果速度设置输入0,则低速模式,非0则高速模式
* SPI_SPEED_HIGH 1
* SPI_SPEED_LOW 0
* Output : None
* Return : None
*******************************************************************************/
void SPI2_SetSpeed(u8 SpeedSet)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
//如果速度设置输入0,则低速模式,非0则高速模式
if(SpeedSet == 1)
{
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
}
else
{
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
}
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
}
extern void spi2WriteData(Uchar *buf,Uint len)
{
for (; len ; len--,buf++)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, *buf);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI2);
}
}
extern u8 SPI2_Swap_DataMSB(u8 byte)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI2, byte);
/* Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI2);
}
SPI3初始化过程
static OS_EVENT *spi3_sem_event;
static void SPI3SemInit(void)
{
spi3_sem_event = OSSemCreate(1);
}
extern void SPI3SemGet(void)
{
uint8_t err;
OSSemPend(spi3_sem_event, 0, &err);
}
extern void SPI3SemPut(void)
{
OSSemPost(spi3_sem_event);
}
static void Spi3_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIO clocks */
下一篇:msp430输出PWM波
史海拾趣
|
视频监控一直是安防技术应用的热点之一,以其直观、方便、信息内容丰富而被广泛应用于军队、银行、海关、机场、高速公路、商场、医院、学校、机关、社会小区、家庭等各种场合。视频监控系统的智能化水平和集成化发展速度,也直接反映了不同阶段电子 ...… 查看全部问答> |
|
有人知道ADV7170/7171可以用VGA连接到电脑显示器上显示吗 我现在在做一个板子,输出的DA用的ADV7170,准备输出RGB信号通过VGA连接到电脑显示器上显示,同步信号通过FPGA产生 但是我了解到这个芯片输出的RGB好像是欧洲SCART的标准,就是隔行的,但是我知道电脑上的VGA都是逐行的信号吧,那这么做兼容吗? ...… 查看全部问答> |
|
我在网上投递了他们公司的嵌入式开发工程师,今天他们打电话给我说要先培训四个月,然后才能上班,并且让我交5000元的培训费,这个公司我咋感觉是骗子公司呢!~… 查看全部问答> |
|
初学LM3S9B96,现遇到问题: 1.用DK-LM3S9B96开发板自带的IDCI下载程序,报错不能下载成功,错误为“Could not find an Cortex-M device”,见贴图; 2.用JLINK下载 ...… 查看全部问答> |




