【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…

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

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

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

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

【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 硬知识 摘自《温湿…

【电路补习笔记】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…

【Net】测试网络、查看IP

http://www.speedtest.cn/ 转载于:https://www.cnblogs.com/flydkPocketMagic/p/7380400.html

【电路补习笔记】2、电容的参数与选型

目录分类无极性电容有极性电容电解电容钽电容参数精度温度系数材质耐压温度范围ESRESL电容并联高频特性焊盘&#xff08;PAD&#xff09;和旁路电容的放置老师的主页&#xff1a;唐老师讲电赛 视频地址&#xff1a;唐老师讲电赛之唐老师讲电子器件&#xff08;1&#xff09;电容…

1005:I Think I Need a Houseboat-poj

1005:I Think I Need a Houseboat 总时间限制: 1000ms内存限制: 65536kB描述Fred Mapper is considering purchasing some land in Louisiana to build his house on. In the process of investigating the land, he learned that the state of Louisiana is actually shrinkin…

【电路补习笔记】3、电感的参数与选型

目录分类电感的模型参数精度直流电阻&#xff08;DCR&#xff09;通流能力&#xff08;Irms&#xff09;自谐振频率&#xff08;SRF&#xff09;饱和电流&#xff08;Isat&#xff09;标号老师的主页&#xff1a;唐老师讲电赛 视频地址&#xff1a;唐老师讲电赛之唐老师讲电子器…

八排序算法

概述 排序有内部排序和外部排序。内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据非常大&#xff0c;一次不能容纳所有的排序记录。在排序过程中须要訪问外存。 我们这里说说八大排序就是内部排序。 当n较大。则应採用时间复杂度为O(nlog2n)的排序方法…

【电路补习笔记】4、二极管的参数与选型

目录常用二极管二极管的结构与特性结构参数最大整流电流IFI_FIF​最大反向工作电压URU_RUR​反向电流IRI_RIR​最高工作频率fMf_MfM​应用常见应用单相整流电路单相半波整流电路单相桥式整流电路稳压管稳压管的伏安特性参数稳压值UZU_ZUZ​稳定电流IZI_ZIZ​额定功耗PZP_ZPZ​动…

@font-face 使用过程

格式&#xff1a; TureTpe(.ttf)格式&#xff1a; .ttf字体是Windows和Mac的最常见的字体&#xff0c;是一种RAW格式&#xff0c;因此他不为网站优化,支持这种字体的浏览器有【IE9,Firefox3.5,Chrome4,Safari3,Opera10,iOS Mobile Safari4.2】 OpenType(.otf)格式&#xff1a;…

【电路补习笔记】5、三极管的参数与选型

目录常用的三极管型号结构作用放大三极管的三种放大组态的比较共射极放大电路单管共射放大电路&#xff08;受温度影响大&#xff09;的动态特性单管共射分压偏置放大电路的动态特性共集电极放大电路使用共基极放大电路多级放大电路多级放大电路的耦合多级放大电路的动态分析开…

FFT 专题讲解

FFT是什么&#xff1f; FFT是快速傅里叶变换(fast Fourier transform)的简称。在ACM领域主要是用来快速求解多项式乘法的算法&#xff0c; 在信号领域也有很大用途 基础知识 卷积 举个例子&#xff0c;给你两个向量 \(a (a_0, a_1, a_2), b(b_0, b_1, b_2)\) a和b的卷积就是$ (…

PureMvc学习笔记

2019独角兽企业重金招聘Python工程师标准>>> PureMvc学习笔记&#xff1a; Mediator ->对应View层&#xff0c;内部绑定View对象&#xff0c;由 Mediator 对象来操作具体的视图组件。&#xff08;它的作用还包括&#xff1a;添加事件监听器&#xff0c;发送或接收…

【电路补习笔记】6、MOS管的参数与选型

目录符号寄生二极管&#xff08;体二极管&#xff09;的方向连接方法作用导通问题NMOSPMOS开关作用隔离作用引脚分辨常见型号NMOS的参数VDSS最大漏-源电压VGS最大栅源电压ID-连续漏电流VGS&#xff08;th&#xff09;RDS&#xff08;on&#xff09;导通电阻Ciss&#xff1a;输入…