分享STM32寄存器版的SPI主从机简易程序

2019-08-16 23:01发布

[mw_shl_code=c,true] SPI的C文件: #include "spi.h" u8 SPI1_TX_BUF[SPI1_TX_LEN]={0X55,0X09,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0XEE}; //发送数据数组 u8 SPI1_RX_BUF[SPI1_RX_LEN]; //接收缓冲,最大SPI1_RE_LEN个字节.末字节为换行符 u16 SPI1_RX_STA=0; u16 SPI1_TX_STA=0; u8 RX_Over=0; u8 tc_flag=1; ///************************SPI1发送函数***************************************/// void SPI1_WriteByte(u8 TxData) { u8 retry = 0; while((SPI1->SR & 1<<1) == 0) //等待发送缓存器为空,为0则此时发送缓存器非空,不能发送数据 { retry++; if(retry > 0XFE) return; } SPI1->DR = TxData;//发送一个8位数据 } ///************************SPI1接收函数***************************************/// u8 SPI1_ReadByte(void) { u8 retry = 0; while((SPI1->SR & 1<<0) == 0) //等待接收缓存器为非空,为0则此时接收缓存器为空,没有接到数据 { retry++; if(retry > 0XFE) return 0; } return SPI1->DR;//发送一个8位数据 } /////************************SPI1中断服务子函数设置(接收、发送、忙标志中断)*******************************/// /******************************SPI1从机中断子函数**********************************************************/ void SPI1_IRQHandler(void) { u8 res; if(SPI1->SR & (1<<0))//读数据寄存器非空,即此时数据已接收,可读出 { res = SPI1_ReadByte(); if(RX_Over ==0) { if(res == 0XEE) { RX_Over = 1; } else { if(res == 0x55) { SPI1_RX_STA = 0; } SPI1_RX_BUF[SPI1_RX_STA & 0X3FFF] = res; SPI1_RX_STA++; if(SPI1_RX_STA > (SPI1_RX_LEN - 1)) { SPI1_RX_STA = 0;//超出最大字节数,此时要不接收错误,要不就是字节数设置不够大 } } } } }[/mw_shl_code]
[mw_shl_code=c,true]SPI的主程序 #include "sys.h" #include "usart.h" #include "delay.h" #include "spi.h" //////////**********************************SPI通信驱动实验程序*****************************////////////// ///**************************从机接收*************************///////////// int main(void) { u8 num; u8 len; u8 dushu; u8 num_len; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 usart1_init(72,9600);//串口波特率设置为9600 SPI1_Init_Slave(); printf("本次接收的数据为: ");//插入换行 while(1) { if(RX_Over) { len = SPI1_RX_STA & 0X3FFF;//得到此次接收完成后的数据长度,即接收多少个字节 num_len = SPI1_RX_BUF[1]+2; if((num_len == len) && (SPI1_RX_BUF[0] == 0X55)) { for(num=2;num<len;num++) { dushu = SPI1_RX_BUF[num]; printf("%x ",dushu);//插入换行 } SPI1_WriteByte(0XFF); } else { SPI1_WriteByte(0X55); } printf(" ");//插入换行 RX_Over = 0; SPI1_RX_STA = 0; } } } ///////************************主机发送**************//////////////////// int main(void) { u8 num; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 SPI1_Init_Master(); while(1) { SPI1_WriteByte(0XAA); if(tc_flag) { for(num=0;num<12;num++) { SPI1_WriteByte(SPI1_TX_BUF[num]); } tc_flag = 0; } if(SPI1_TX_STA) { while((SPI1->SR & 1<<0) == 0); while((SPI1->SR & 1<<1) == 0); while((SPI1->SR & 1<<7) == 1); SPI1->CR1 &= ~(1<<6); } } }[/mw_shl_code]
[mw_shl_code=c,true] [mw_shl_code=c,true]SPI的H文件: #ifndef __TIME_H #define __TIME_H #include "sys.h" #include "stdio.h" #define SPI1_RX_LEN 200 //定义SPI1最大接收字节数200 #define SPI1_TX_LEN 200 //定义SPI2最大发送字节数200 extern u8 SPI1_TX_BUF[SPI1_TX_LEN]; extern u8 SPI1_RX_BUF[SPI1_RX_LEN]; //接收缓冲,最大SPI1_RE_LEN个字节.末字节为换行符 extern u16 SPI1_RX_STA; extern u16 SPI1_TX_STA; extern u8 RX_Over; extern u8 tc_flag; //接收状态标记,位15是接收完成标志,位14为接到0X0D标志,位13~0接收到的有效数据个数=SPI1_RX_LEN (SPI2_RX_LEN)(SPI3_RX_LEN) //自定义接收完成的标准是接收到回车符,即0X0D和0X0A这2个字节 void SPI1_SetSpeed(u8 SpeedSet);//SPI1通信速度设置,取值范围为0X00~0X07 void SPI1_WriteByte(u8 TxData);//SPI1发送函数 u8 SPI1_ReadByte(void);//SPI1接收函数 void SPI1_Init_Master(void);//主机模式设置初始化化 void SPI1_Init_Slave(void);//从机模式设置初始化化 #endif [/mw_shl_code]

[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
明书
2019-08-17 15:47
[mw_shl_code=cpp,true]///************************SPI1主从机初始化********************************************************///

void SPI1_Init_Master(void)
{
  RCC->APB2ENR |= 1<<2;
        RCC->APB2ENR |= 1<<12;
        GPIOA->CRL &= 0X0000FFFF;
        GPIOA->CRL |= 0XBBB00000;
  GPIOA->ODR |= 7<<5;
        RCC->APB2RSTR |= 1<<12;
        RCC->APB2RSTR &= ~(1<<12);
        SPI1->CR1 |= 0<<10;
        SPI1->CR1 |= 1<<9;
        SPI1->CR1 |= 1<<8;
        SPI1->CR1 |= 1<<2;
        SPI1->CR1 |= 1<<11;
        SPI1->CR1 |= 1<<1;
        SPI1->CR1 |= 1<<0;
        SPI1->CR1 |= 7<<3;
        SPI1->CR1 |= 0<<7;
        SPI1->CR2 |= 1<<6;
        MY_NVIC_Init(1,1,SPI1_IRQn,2);
        SPI1->CR1 |= 1<<6;
       
}

void SPI1_Init_Slave(void)
{
  RCC->APB2ENR |= 1<<2;
        RCC->APB2ENR |= 1<<12;
        GPIOA->CRL &= 0X0000FFFF;
        GPIOA->CRL |= 0XBBB00000;
  GPIOA->ODR |= 7<<5;
        RCC->APB2RSTR |= 1<<12;
        RCC->APB2RSTR &= ~(1<<12);
        SPI1->CR1 |= 0<<10;
        SPI1->CR1 |= 1<<9;
        SPI1->CR1 |= 0<<8;
        SPI1->CR1 |= 0<<2;
        SPI1->CR1 |= 1<<11;
        SPI1->CR1 |= 1<<1;
        SPI1->CR1 |= 1<<0;
        SPI1->CR1 |= 7<<3;
        SPI1->CR1 |= 0<<7;
        SPI1->CR2 |= 1<<6;
        MY_NVIC_Init(1,1,SPI1_IRQn,2);
        SPI1->CR1 |= 1<<6;
}[/mw_shl_code]

一周热门 更多>