打印
[STM32]

关于stm32跟51的spi双机通讯

[复制链接]
1602|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
15383646831|  楼主 | 2018-4-19 10:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在学stm32的spi通讯 主机是stm32接收数据  用从机89c51给32发送数据, 但是感觉从机51的spi很迷茫 希望浪费大神们一点时间解救一下  感觉问题出现在从机51的发送数据上
给批评指正
主机


void SPI2_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
        RCC_APB1PeriphClockCmd(        RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB

        GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉

        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位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI2, ENABLE); //使能SPI外设
       
        SPI2_ReadWriteByte(0xff);//启动传输                 


}   
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   
//SPI_BaudRatePrescaler_8   8分频   
//SPI_BaudRatePrescaler_16  16分频  
//SPI_BaudRatePrescaler_256 256分频
  
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
        SPI2->CR1&=0XFFC7;
        SPI2->CR1|=SPI_BaudRatePrescaler;        //设置SPI2速度
        SPI_Cmd(SPI2,ENABLE);

}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                        
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
                {
                retry++;
                if(retry>200)return 0;
                }                          
        SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
                {
                retry++;
                if(retry>200)return 0;
                }                                                              
        return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据                                            
}

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"       
#include "spi.h"

int main(void)
{         
       
        GPIO_ResetBits(GPIOB,GPIO_Pin_12); //拉低片选
        delay_init();                     //延时函数初始化          
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(115200);                 //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
        LCD_Init();                                   //初始化LCD        
  SPI2_Init();
       
  
        POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(30,50,200,16,16,"SPI2_ReadWriteByte(0x00)");       
  
}

89c51从机
#include <reg51.h>

typedef unsigned char u8;
typedef unsigned int u16;

sbit SCLK=P1^0;
sbit MOSI=P1^1;
sbit MISO=P1^2;
sbit SS=P1^3;

u8 i;
u8 temp;

void main()
{         

  temp=0x01;
    while(SS==0)
        {
           for(i=0;i<8;i++)
           {
            
           while(!SCLK)         //等待下降沿
           {
           if(temp&0x80)
             MISO=1;
           else
                  MISO=0;          
           temp=temp>>1;
           }
          while(!SCLK);
           
       
            }

  }
}

相关帖子

沙发
15383646831|  楼主 | 2018-4-19 10:23 | 只看该作者
还有主机对lcd传送的数据上出现了问题,

使用特权

评论回复
板凳
15383646831|  楼主 | 2018-4-19 10:24 | 只看该作者
32 真的感觉学的很水。。。

使用特权

评论回复
地板
15383646831|  楼主 | 2018-4-19 10:26 | 只看该作者
或者大神们可以给我分享一个例程看看 !!!!!!!!!!!!!!!

使用特权

评论回复
5
ningling_21| | 2018-4-19 10:55 | 只看该作者
15383646831 发表于 2018-4-19 10:26
或者大神们可以给我分享一个例程看看 !!!!!!!!!!!!!!!

用野火的例程或原子的例程都可以

使用特权

评论回复
6
m564522634| | 2018-4-20 16:25 | 只看该作者
15383646831 发表于 2018-4-19 10:23
还有主机对lcd传送的数据上出现了问题,

SPI 通信一般不会用到双机通信中去, 双机通信要做也可以,因为SPI 是同步发送数据 的, 从机想给主机发送数据是要 主机给从机 SCK 信号 ,这个就比较麻烦了 所以你要C51发信息给主机 就要主机给SCK 了,当然你要解决主机怎么知道从机给他发信息了。 你可以玩下实际用处不是很大了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

22

帖子

0

粉丝