OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4727|回复: 8

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

[复制链接]

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
发表于 2015-7-30 09:57:16 | 显示全部楼层 |阅读模式
[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("本次接收的数据为:\n");//插入换行 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\n",dushu);//插入换行 } SPI1_WriteByte(0XFF); } else { SPI1_WriteByte(0X55); } printf("\r\n");//插入换行 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]
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165394
金钱
165394
注册时间
2010-12-1
在线时间
2112 小时
发表于 2015-7-30 20:46:13 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
 楼主| 发表于 2015-7-31 14:23:49 | 显示全部楼层
数组{0X55,0X09,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0XEE}定义是0X55为数据存取开始字节,0XEE为数据传输结束字节,0X55之后的0X09是代表我需要读取使用的数据为9个,实际需要的数据为0X01~0X09这九个数据字节
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
回复 支持 反对

使用道具 举报

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
 楼主| 发表于 2015-7-31 14:38:30 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
谢谢原子哥,自己也是刚学习STM32,学有所得就分享给大家,也希望自己在以后学习过程中能得到各位的知识指导及分享资料
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
回复 支持 反对

使用道具 举报

2

主题

394

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2106
金钱
2106
注册时间
2012-5-8
在线时间
314 小时
发表于 2016-2-19 10:26:16 | 显示全部楼层
能否共享个工程?! SPI1_Init_Slave函数怎么实现?
回复 支持 反对

使用道具 举报

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
 楼主| 发表于 2016-2-19 10:56:37 | 显示全部楼层
[img]C:\Users\FLST-YYP\Desktop\1C:\Users\FLST-YYP\Desktop\2[/img]
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
回复 支持 反对

使用道具 举报

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
 楼主| 发表于 2016-2-19 11:02:57 | 显示全部楼层
[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]
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
回复 支持 反对

使用道具 举报

7

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2015-5-17
在线时间
11 小时
 楼主| 发表于 2016-2-19 11:04:23 | 显示全部楼层
因为我要上传代码时,备注全变成乱码了,所以只能给你这些没备注的代码。个人建议,你可以看看正点原子的寄存器版的书,你看完之后就知道怎么设置初始化了
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
回复 支持 反对

使用道具 举报

4

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2012-7-20
在线时间
15 小时
发表于 2017-7-19 08:26:16 | 显示全部楼层
MARK,谢谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-5 14:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表