STM32 软件模拟SPI时序驱动NRF24L01

发布者:创新驿站最新更新时间:2017-09-23 来源: eefocus关键字:STM32  软件模拟  SPI时序  NRF24L01 手机看文章 扫描二维码
随时随地手机看文章
其实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;
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

模拟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;         //返回读取到的数据}1234567891011121314151617181920212223242526272829

写寄存器操作:` 
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;
}


关键字:STM32  软件模拟  SPI时序  NRF24L01 引用地址:STM32 软件模拟SPI时序驱动NRF24L01

上一篇:STM32中使用MMA7660重力加速度传感器
下一篇:ARM9 2440硬件SPI驱动程序-NRF24L01

推荐阅读最新更新时间:2024-03-16 15:38

STM32时钟系统与时钟启动顺序详解
概念基础: STM32时钟系统基本一致,不同系列之间有细微差别。此文档主要针对STM32F446的时钟系统进行介绍。 1. 时钟树概述 为何不是采用一个系统时钟?如51 因为STM32本身非常复杂,外设非常多,但是并非所有外设都需要系统时钟这么高的频率,比如看门狗和RTC只需要几十K的时钟即可。同一个电路,时钟越快,功耗越大,同时抗电磁干扰能力也会越弱,所以对于较为复杂的MCU一般采用多时钟源的方法来解决这些问题。 主要时钟源: 5个最主要的时钟源: 高速时钟源:HSI、HSE、PLL 低速时钟源:LSI、LSE 其中PLL实际又分为3个时钟源:主PLL、I2S部分专用PLLI2S、SAI部分专用PLLASI。 详解: L
[单片机]
<font color='red'>STM32</font>时钟系统与时钟启动顺序详解
ST低价32位MCU:传承STM32基因 发展自己的生态系统
日前,意法半导体发布了它最新的STM32F030基于Cortex-M0内核的超值系列微控制器,以0.32美元的批量订货价格引发热议。意法半导体表示:“与同类竞争产品不同的是,STM32F030虽然只有8位微控制器的价格,但在性能和特性上并没有受到任何影响。它保持了原有的内核速度和丰富的外设,传承了STM32F0家族的优异基因。”STM32F030将面向工业控制、消费电子和家用电器三大目标应用。 低价来源于规模经济 打造宽产品线平台 在新品的交流中,意法半导体大中华与亚太区微控制器市场及应用总监James Wiart提供了这样的数据:从2009到2012年,ST在MCU市场的份额翻了一番,年增长率达到市场平均的三倍。其中
[单片机]
STM32 中断优先级以及全局允许和禁止
请问例程上为什么要把串口中断优先级设置在NVIC中断分组2 NVIC: M3内核允许8bit做优先级分组设置,而STM32只有4bit可以设置。 AIRCR寄存器的4个位的分组方式如下: 第0组:所有4位用于指定响应优先级 第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级 第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级 第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级 第4组:所有4位用于指定抢占式优先级 例:定义为第二组,抢占式优先级2bit,响应式优先级2bit,2bit共可有4种状态,也就是总共能设置4*4=16个中断优先级。 定义为第三组
[单片机]
STM32学习笔记----keil工程的建立
1、keil编译的三个按键的功能 A、第一个按钮:Translate 就是翻译当下修改过的文件,说明白点就是检查下有没有语法错误,并不会去链接库文件,也不会生成可执行文件。 B、第二个按钮:Build 就是编译当下修改过的文件,它包含了语法检查,链 接动态库文件,生成可执行文件。 C、第三个按钮:Rebuild 重新编译整个工程,跟 Build 这个按钮实现的功能 是一样的,但有所不同的是它编译的是整个工程的所有文件,耗时巨大。 综上:当我们编辑好我们的程序之后,只需要用第二个 Build 按钮就可以, 即方便又省时。第一个跟第三个按钮用的比较少 2 、core_cm3.c 跟启动文件一样都是底层文件,都是由 ARM 公司提供的,
[单片机]
[STM32学习笔记]I/O的数字输出输入
STM32输入与输出的工作方式 _____________________________________________________________________________ 输入 输入浮空 输入上拉 输入下拉 模拟输入 输出 开漏输出 推挽式输出 推挽式复用功能 开漏复用功能 比较难以理解的是什么叫开漏输出,什么叫推挽式输出了。 开漏输出:CPU输出1时,I/O状态由外部上拉或下拉决定。 CPU输出0时,I/O状态为0。 推挽式输出: CPU输出1时,I/O状态为1。 CPU输出0时,I/O状态为0。 开漏复用功能: 跟开漏输出相似,I/O状态由复用功能决定。 推挽式复用功能:跟
[单片机]
[<font color='red'>STM32</font>学习笔记]I/O的数字输出输入
34.内存管理
一。内存管理简介 1. 为什么要用内存管理 例如如何在LCD上实现SD卡文件浏览 如果有内存管理可以用的内存的时候去申请内存,用完之后释放掉给别的地方用。不必事先定义一个很大的数组占用很多内存。 2. 什么是内存管理 3. 内存管理简介 二。硬件连接 三。源码讲解和例程测试
[单片机]
34.内存管理
stm32的freeRTOS上进行微秒级延时
因为时间片的原因freeRTOS自身貌似无法进行微秒级的延时,实测通过以下函数可以进行微秒级的消息 dwt_stm32_delay.h #ifndef DWT_STM32_DELAY_H #define DWT_STM32_DELAY_H #ifdef __cplusplus extern C { #endif #include stm32f4xx_hal.h /** * @brief Initializes DWT_Cycle_Count for DWT_Delay_us function * @return Error DWT counter * 1: DWT counter Error *
[单片机]
STM32 EXTI外部中断
外部中断引脚配置初始化:以PA0为例说明 1、外设端口时钟打开 RCC- APB2ENR|=1 2; //使能PORTA时钟 2、端口设置为输入 GPIOA- CRL&=0XFFFFFFF0;//PA0设置成输入 GPIOA- CRL|=0X00000008; 3、端口选择上拉/下拉方式 GPIOA- ODR&=0xFFFFFFFE; //A0默认下拉 4、中断触发方式选择 Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发 5、嵌套向量中断控制(抢占优先级,响应优先级,组) MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved