【STC15库函数上手笔记】9、硬件SPI

目录

  • 硬件知识
  • 库函数
    • spi.c
    • spi.h
  • 测试
    • main.c
    • 实验现象

STC实验箱4
IAP15W4K58S4
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬件知识

       摘自《STC15系列单片机器件手册
       STC15系列单片机还提供另一种高速串行通信接口——SPI接口。SPI是一种全双工、高速、同步的通信总线,有两种操作模式:主模式和从模式。在主模式中支持高达3Mbps的速率(工作频率为12MHz时,如果CPU主频采用20MHz到36MHz,则可更高,从模式时速度无法太快,SYSclk/4以内较好),还具有传输完成标志和写冲突标志保护。
       下表总结了STC15系列单片机内部集成了SPI功能的单片机型号:
在这里插入图片描述
       上表中√表示对应的系列有相应的功能。
在这里插入图片描述
       STC15W系列与STC15F/L系列具有不同的SPI时钟频率,其中,STC15W系列单片机的SPI时钟频率选择如下表所列:在这里插入图片描述
       表中,CPU_CLK是CPU时钟。
       STC15F/L系列单片机的SPI时钟频率选择如下表所列:
在这里插入图片描述
       表中,CPU_CLK是CPU时钟。

库函数

SPI的库函数仅在官方例程中发现,未与其他库函数放在一起,请谨慎使用。

spi.c


/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* --- QQ:  800003751 ----------------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/#include	"spi.h"u8	SPI_TxRxMode;	//
u8	SPI_TxWrite;
u8	SPI_TxRead;
u8	SPI_RxCnt;
u8 	SPI_RxTimerOut;
u8 	SPI_BUF_type SPI_RxBuffer[SPI_BUF_LENTH];
u8 	SPI_BUF_type SPI_TxBuffer[SPI_BUF_LENTH];
bit 	B_SPI_TxBusy = 0;
bit 	B_SPI_RxOk;//========================================================================
// 函数: void	SPI_Init(SPI_InitTypeDef *SPIx)
// 描述: SPI初始化程序.
// 参数: SPIx: 结构参数,请参考spi.h里的定义.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void	SPI_Init(SPI_InitTypeDef *SPIx)
{if(SPIx->SPI_SSIG == ENABLE)			SPCTL &= ~(1<<7);	//enable SS, conform Master or Slave by SS pin.else									SPCTL |=  (1<<7);	//disable SS, conform Master or Slave by SPI_Modeif(SPIx->SPI_Module == ENABLE)			SPCTL |=  (1<<6);	//SPI enableelse									SPCTL &= ~(1<<6);	//SPI disableif(SPIx->SPI_FirstBit == SPI_LSB)		SPCTL |= ~(1<<5);	//LSB firstelse									SPCTL &= ~(1<<5);	//MSB firstif(SPIx->SPI_Mode == SPI_Mode_Slave)	SPCTL &= ~(1<<4);	//slaveelse									SPCTL |=  (1<<4);	//masterif(SPIx->SPI_CPOL == SPI_CPOL_High)		SPCTL |=  (1<<3);	//SCLK Idle High, Low Active.else									SPCTL &= ~(1<<3);	//SCLK Idle Low, High Active.if(SPIx->SPI_CPHA == SPI_CPHA_2Edge)	SPCTL |=  (1<<2);	//sample at the second edgeelse									SPCTL &= ~(1<<2);	//sample at the first  edgeif(SPIx->SPI_Interrupt == ENABLE)		IE2 |=  (1<<1);else									IE2 &= ~(1<<1);SPCTL = (SPCTL & ~3) | (SPIx->SPI_Speed & 3);					//set speedAUXR1 = (AUXR1 & ~(3<<2)) | SPIx->SPI_IoUse;	
}//========================================================================
// 函数: void	SPI_SetMode(u8 mode)
// 描述: SPI设置主从模式函数.
// 参数: mode: 指定模式, 取值 SPI_Mode_Master 或 SPI_Mode_Slave.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void	SPI_SetMode(u8 mode)
{SPI_TxRxMode = mode;if(mode == SPI_Mode_Slave)	SPCTL &= ~(1<<4);	//slaveelse						SPCTL |=  (1<<4);	//master
}//========================================================================
// 函数: void SPI_WriteToTxBuf(u8 dat)
// 描述: SPI装载发送缓冲函数.
// 参数: dat: 要发送的值.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void	SPI_WriteToTxBuf(u8 dat)	//写入发送缓冲,指针+1
{SPI_TxBuffer[SPI_TxWrite] = dat;if(++SPI_TxWrite >= SPI_BUF_LENTH)	SPI_TxWrite = 0;
}//========================================================================
// 函数: void	SPI_TrigTx(void)
// 描述: SPI触发发送函数, 将SPI模式设置为发送模式并将发送缓冲的数据发出.
// 参数: dat: 要发送的值.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void	SPI_TrigTx(void)
{u8	i;if(SPI_TxRead == SPI_TxWrite)	{B_SPI_TxBusy = 0;return;}B_SPI_TxBusy = 1;SPI_SetMode(SPI_Mode_Master);SPI_SS = 0;i = SPI_TxBuffer[SPI_TxRead];if(++SPI_TxRead >= SPI_BUF_LENTH)	SPI_TxRead = 0;SPDAT = i;
}//========================================================================
// 函数: void SPI_Transivion (void) interrupt SPI_VECTOR
// 描述: SPI中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void SPI_Transivion (void) interrupt SPI_VECTOR
{if(SPI_TxRxMode == SPI_Mode_Slave){//	if(!B_SPI_RxOk){if(SPI_RxCnt >= SPI_BUF_LENTH)		SPI_RxCnt = 0;SPI_RxBuffer[SPI_RxCnt++] = SPDAT;SPI_RxTimerOut = 5;}}if(SPI_TxRxMode == SPI_Mode_Master){if(SPI_TxRead != SPI_TxWrite){SPDAT = SPI_TxBuffer[SPI_TxRead];if(++SPI_TxRead >= SPI_BUF_LENTH)		SPI_TxRead = 0;}else{SPI_TxRxMode = SPI_Mode_Slave;SPCTL &= ~(1<<4);	//slaveSPI_SS = 1;B_SPI_TxBusy = 0;}}SPSTAT = SPIF + WCOL;	//清0 SPIF和WCOL标志
}

spi.h


/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* --- QQ:  800003751 ----------------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/#ifndef	__SPI_H
#define	__SPI_H#include	"config.h"#define	SPI_BUF_LENTH	32
#define	SPI_BUF_type	idata#define	SPI_Mode_Master		1
#define	SPI_Mode_Slave		0
#define	SPI_CPOL_High		1
#define	SPI_CPOL_Low		0
#define	SPI_CPHA_1Edge		1
#define	SPI_CPHA_2Edge		0
#define	SPI_Speed_4			0
#define	SPI_Speed_16		1
#define	SPI_Speed_64		2
#define	SPI_Speed_128		3
#define	SPI_MSB				0
#define	SPI_LSB				1
#define	SPI_P12_P13_P14_P15	(0<<2)
#define	SPI_P24_P23_P22_P21	(1<<2)
#define	SPI_P54_P40_P41_P43	(2<<2)typedef struct
{u8	SPI_Module;		//ENABLE,DISABLEu8	SPI_SSIG;		//ENABLE, DISABLEu8	SPI_FirstBit;	//SPI_MSB, SPI_LSBu8	SPI_Mode;		//SPI_Mode_Master, SPI_Mode_Slaveu8	SPI_CPOL;		//SPI_CPOL_High,   SPI_CPOL_Lowu8	SPI_CPHA;		//SPI_CPHA_1Edge,  SPI_CPHA_2Edgeu8	SPI_Interrupt;		//ENABLE,DISABLEu8	SPI_Speed;		//SPI_Speed_4,      SPI_Speed_16,SPI_Speed_64,SPI_Speed_128u8	SPI_IoUse;		//SPI_P12_P13_P14_P15, SPI_P24_P23_P22_P21, SPI_P54_P40_P41_P43
} SPI_InitTypeDef;extern	u8	SPI_TxRxMode;
extern	u8	SPI_TxWrite;
extern	u8	SPI_TxRead;
extern	u8	SPI_RxCnt;
extern	u8 	SPI_RxTimerOut;
extern	u8 	SPI_BUF_type SPI_RxBuffer[SPI_BUF_LENTH];
extern	u8 	SPI_BUF_type SPI_TxBuffer[SPI_BUF_LENTH];
extern	u8  *SPI_pTxBuffer;
extern	bit 	B_SPI_RxOk;
extern	bit 	B_SPI_TxBusy;void	SPI_Init(SPI_InitTypeDef *SPIx);
void	SPI_SetMode(u8 mode);
void	SPI_WriteToTxBuf(u8 dat);
void	SPI_TrigTx(void);#endif

测试

OLED驱动程序见SPI驱动0.96/1.3寸 OLED屏幕,易修改为DMA控制

main.c

#include "./Drivers/config.h"
#include "./Drivers/delay.h"#include "./Drivers/GPIO.h"
#include "./Drivers/spi.h"
#include "./SPI_OLED/oled.h"void GPIO_config(void)
{GPIO_InitTypeDef GPIO_InitStructure;					//结构定义GPIO_InitStructure.Mode = GPIO_OUT_PP;					//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin  = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);				//初始化为推挽输出GPIO_InitStructure.Mode = GPIO_OUT_OD;					//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_InitStructure.Pin  = GPIO_Pin_2;					//指定要初始化的IO, 或操作GPIO_Inilize(GPIO_P2,&GPIO_InitStructure);				
}void	SPI_config(void)
{SPI_InitTypeDef		SPI_InitStructure;SPI_InitStructure.SPI_Module    = ENABLE;              //SPI启动    ENABLE, DISABLESPI_InitStructure.SPI_SSIG      = DISABLE;			  //片选位     ENABLE, DISABLESPI_InitStructure.SPI_FirstBit  = SPI_MSB;			  //移位方向   SPI_MSB, SPI_LSBSPI_InitStructure.SPI_Mode      = SPI_Mode_Master;	  //主从选择   SPI_Mode_Master, SPI_Mode_SlaveSPI_InitStructure.SPI_CPOL      = SPI_CPOL_High;      //时钟相位   SPI_CPOL_High,   SPI_CPOL_LowSPI_InitStructure.SPI_CPHA      = SPI_CPHA_2Edge;	  //数据边沿   SPI_CPHA_1Edge,  SPI_CPHA_2EdgeSPI_InitStructure.SPI_Interrupt = ENABLE;			  //中断允许   ENABLE,DISABLESPI_InitStructure.SPI_Speed     = SPI_Speed_128;		  //SPI速度    SPI_Speed_4, SPI_Speed_16, SPI_Speed_64, SPI_Speed_128SPI_InitStructure.SPI_IoUse     = SPI_P24_P23_P22_P21; //IO口切换   SPI_P12_P13_P14_P15, SPI_P24_P23_P22_P21, SPI_P54_P40_P41_P43SPI_Init(&SPI_InitStructure);SPI_TxRxMode = SPI_Mode_Master;
}void main(void)
{uint8_t i;GPIO_config();SPI_config();EA = 1;OLED_Init();OLED_Clear();OLED_Display_On();	     OLED_ShowString(0, 0, "STC15W4K58  OLED", 16, 0);OLED_ShowString(0, 2, "   2022-01-10", 6, 0);OLED_ShowString(0, 3, "    SPI Test", 6, 0);for(i = 0; i < 7; ++i)OLED_ShowChinese(8 + 16 * i, 6, i, 1);OLED_Refresh_Gram();while(1){}
}

修改OLED_WR_Byte函数
在这里插入图片描述

/**
* @brief 向SSD1306写入一个字节
* @param dat:要写入的数据/命令 cmd:数据/命令标志 0,表示命令;1,表示数据;
* @retval None
*/
void OLED_WR_Byte(uint8_t dat, uint8_t cmd)
{OLED_CS_L();if (cmd)OLED_DC_H();elseOLED_DC_L();SPI_TxRead = 0;SPI_TxWrite = 0;SPI_WriteToTxBuf(dat);SPI_TrigTx();while(B_SPI_TxBusy);OLED_DC_H();OLED_CS_H();
}

实验现象

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中介者模式分析、结构图及基本代码

&#xfeff;&#xfeff;定义&#xff1a;用一个中介对象来封装一系列的对象交互。中介者使各对象不须要显式地相互引用。从而使其耦合松散&#xff0c;并且能够独立地改变它们之间的交互。适用地方&#xff1a;中介者模式一般应用于一组对象以定义良好可是复杂的方式进行通信…

WordPress 数据库结构及表字段作用解析

对于WordPress的开发可以说子凡已经是如痴如醉了&#xff0c;通过 WordPress 本身的开放性接口可以做到很多的事情&#xff0c;但是有些时候我们可能更喜欢直接查询数据库来实现某些 WordPress 没有提供的函数来实现目的&#xff0c;所以这时候我们就需要对WordPress 数据库的结…

硬件负载均衡设备介绍

最常用是F5 与citrix netscaler 负载均衡分全局负载均衡和本地负载均衡。 地负载均衡是指对本地的服务器群做负载均衡&#xff0c;全局负载均衡是指对分别放置在不同的地理位置、有不同网络结构的服务器群间作负载均衡。 循环DNS 就是每次解析域名时指向IP loop list 里的下一个…

【STC15库函数上手笔记】10、EEPROM

目录硬件知识基本介绍软件知识EEPROM多字节读函数EEPROM多字节写函数EEPROM扇区擦除函数函数测试main.c实验现象STC实验箱4 IAP15W4K58S4 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬件知识 基本介绍 摘自《STC15系列单片机器件手册》 STC…

Android中shape中的属性大全

<shape><!-- 实心 --><solid android:color"#ff9d77"/><!-- 渐变 --><gradientandroid:startColor"#ff8c00"android:endColor"#FFFFFF"android:angle"270" /><!-- 描边 --><strokeandroid:wid…

Mysql 插入中文错误:Incorrect string value: '...' for column 'xx' at row 1

datasource url后面加上useUnicodetrue&characterEncodingutf-8alter table w default character set utf8; alter table w change score score varchar(50) character utf8; 转载于:https://www.cnblogs.com/orziii/p/7372339.html

修改WordPress中上传附件2M大小限制的方法

https://blog.csdn.net/u010486124/article/details/38348327?utm_sourceblogxgwz7 post_max_size512M upload_max_filesize512M

ASP.NET会员注册登录模块(MD5加密,Parameters防止SQL注入,判断是否注册)

MD5加密,Parameters防止SQL注入:protected void btnLog_Click(object sender, EventArgs e){//获取验证码string code txtCode.Text;//判断用户输入的验证码是否正确if (Request.Cookies["CheckCode"].Value code){//创建数据库连接SqlConnection con new SqlConn…

【51单片机快速入门指南】4.6:I2C 与 PCF8563实时时钟日历芯片

目录硬知识概述特性功能描述报警功能模式定时器模式CLKOUT输出复位低电压检测器和时钟监视器低电压检测器和时钟监视器寄存器结构寄存器概述BCD编码格式寄存器概述Control/Status 1 寄存器&#xff08;内存地址00H&#xff09;Control/Status 2 寄存器&#xff08;内存地址01H&…

(转) Spring读书笔记-----Spring的Bean之配置依赖

前一篇博客介绍了Spring中的Bean的基本概念和作用域&#xff08;Spring读书笔记-----Spring的Bean之Bean的基本概念 &#xff09;,现在介绍Spring Bean的基本配置。 从开始我们知道Java应用中各组件的相互调用的实质可以归纳为依赖关系。根据注入方式的不同&#xff0c;Bean的依…

Luogu P1031 均分纸牌(贪心)

P1031 均分纸牌 题目描述 有 N 堆纸牌&#xff0c;编号分别为 1&#xff0c;2&#xff0c;…, N。每堆上有若干张&#xff0c;但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌&#xff0c;然后移动。 移牌规则为&#xff1a;在编号为 1 堆上取的纸牌&#xff0c;只能移到…

利用MySQL语句批量替换指定wordpress文章中的图片路径

天花了很多时间将SAE服务器中的图片下载到本地&#xff0c;然后删掉&#xff0c;但是有一个问题就是&#xff0c;所有文章中的图片路径还是以前的&#xff0c;没有根据域名来。导致下午某些时间段图片都是无法显示的&#xff0c;后来想到用MySQL直接批量替换&#xff0c;执行才…

Head First summary

学习面向对象好几年了&#xff0c;但一直没有深刻的理解面向对象&#xff0c;直到最近开始做自动化测试平台开发过程中&#xff0c;才发现面向对象的魅力。因而决定好好把设计模式学习下。首先先了解下设计模式相关的定义以及主意事项&#xff1a; 1.  什么是设计模式&#x…

【51单片机快速入门指南】6.4:DHT11、DHT22单总线温湿度传感器

目录硬知识DHT11DHT22通信协议读取步骤数据解读DHT11DHT22示例程序DHT11_22.cDHT11_22.h测试程序main.c实验现象DHT11DHT22STC89C52 Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《温湿…

获取编辑器两种方法

编辑器&#xff0c;是地图数据进行编辑的主要工具&#xff0c;这个Editor其实当一个新的地图开始时就创建了。事实上&#xff0c;其他ArcMap扩展对象也是在创建地图时产生的。 为了获得这个Editor&#xff0c;可以使用FindExtensionByCLSID 或者FindExtensionByName接口。 priv…

Redis持久化的简单介绍

Redis的强大功能很大程度上是由于其将所有数据都存储在内存中&#xff0c;为了使Redis在重启后仍能保证数据不丢失&#xff0c;需要将数据从内存中以某种形式持久化到硬盘中。 Redis支持两种方式的持久化&#xff0c;一种是RDB方式&#xff0c;一种是AOF方式。其中&#xff0c;…

图片响应式

img-responsive 编辑 本词条缺少概述图&#xff0c;补充相关内容使词条更完整&#xff0c;还能快速升级&#xff0c;赶紧来编辑吧&#xff01; img-responsive是图片响应式的意思&#xff0c;在Bootstrap框架中&#xff0c;有一个.img-responsive的CSS样式。应用这个样式以后…

【电路补习笔记】1、电阻的参数与选型

目录参数精度温度系数功率贴片电阻色环电阻传感器电阻老师的主页&#xff1a;唐老师讲电赛 视频地址&#xff1a;唐老师讲电赛之唐老师讲电子器件&#xff08;1&#xff09;电阻参数与选型 电阻按封装分为直插、贴片与印刷电阻&#xff08;有些电阻直接印刷在PCB上&#xff09;…

redis本地安装

redis在本地的安装及使用1、首先下载redis安装包&#xff0c;下载地址如下 http://pecl.php.net/package/redis/2.2.7/windows输入phpinfo()查看php版本进行相应的下载&#xff0c;注意版本2、下载完成后将php_redis.dll放到ext下&#xff0c;在php.ini中添加extensionphp_re…

Xcode模拟器和真机生成的日志查看(ios必知必会)

在进行实际代码开发的过程中&#xff0c;我们会生成一些plist文件&#xff0c;但是如何在调试过程中查看这些plist文件是否被成功生成以及生成的内容是否正确&#xff1f; 如果查看模拟器生成的日志和真机生成的日志到底如何查看&#xff1f; DEMO 首先生成一个plist文件 NSArr…