华润微8051系列通用MCU教程(3)---CS88F003之SPI使用

一:SPI简介

SPI ( Serial Peripheral lnterface,串行外围设备接口)通讯协议,是摩托罗拉公司提出的一种同步串行接口技术,是一种高速、全双工、同步通信总线,在芯片中只占用四根管脚用来控制及数据传输。SPI相比IIC和UART来说传输速度更快,但是由于协议本身缺少相应的应答和校验操作,在数据的可靠性上有一定缺陷!

1.1:SPI物理线路说明;

标准的SPI包括四根线,分别是CS(片选线),SCK(同步时钟线),MOSI(主机输出从机输入线),MISO(主机输入从机输出线),在通信时一般将主机和从机对应线连接起来就好,如下图所示:
在这里插入图片描述

1.2:SPI传输模式说明;

在说传输模式前,有必要先简单说一下SPI中的时钟极性(CPOL)和时钟相位(CPHA)。时钟极性可以理解成SPI时钟线(SCK)在空闲时的电平状态,例如CPOL=0,那么在SPI空闲时时钟线(SCK)就是低电平,当CPOL=1时,那么在SPI空闲时时钟线就为高电平;时钟相位(CPHA)可以理解成SPI采集数据的时刻,CPHA=0时代表数据在第一个时钟沿采样,CPHA=1时代表数据在第二个时钟沿采样,例如当CPOL=0,CPHA=0时,数据的变化和采样如下图(绿线处变化,橙线处采样)所示:

在这里插入图片描述

模式0 CPOL=0,CPHA=0—>SCK空闲电平为低电平,数据在第一个时钟沿采样;
模式1 CPOL=0,CPHA=1—>SCK空闲电平为低电平,数据在第二个时钟沿采样;
模式2 CPOL=1,CPHA=0—>SCK空闲电平为高电平,数据在第一个时钟沿采样;
模式3 CPOL=1,CPHA=1—>SCK空闲电平为高电平,数据在第二个时钟沿采样;

二:CS88F003 SPI模块简要介绍和使用;

2.1:CS88F003 SPI介绍;

cs88f003总共包含一个spi模块,支持主从模式,并且支持可编程的时钟频率。由于在使用中很多情况都只使用到单纯的发送和接收,所以本教程教程也只简单的介绍SPI 发送、SPI接收,别的功能其实也大差不差本文就不再赘述!

2.2:CS88F003 SPI主模式中断检测发送数据;

实验目的: 在主函数中检测SPI是否在发送数据,如果上一个数据已发送完(或刚准备发送第一个数据),则继续发送数据0x0f,最终通过逻辑分析仪可以抓取主机SPI的MOSI信号线一直在发送0x0f;
实验代码:

/*******************************************main.c***********************************************/
void main(void)
{
	Sys_Clk_Set_IRCH(SYS_CLK_8M); //芯片默认校准为16M,分频后系统主频8M
	SysClk_Delay(50);
	WDT_OFF(); 

	/*1:第一步开启引脚复用功能,例如PT15-CS,PT10-SCK,PT00-MOSI,PT01-MISO*/
	PT0_MUX1 |= (0x02|0x01);//0x01;
	PT1_MUX1 |= (0x20|0x01);//0x01;
	/*2:第二步打开SPI时钟*/
	SPI_SPE |= 0x02;
	/*3:第三步SPI控制寄存器复位-官方例程是写了这个步骤*/
	SPI_CR0 = 0x00;
	SPI_CR1 = 0x00;
	/*4:第四步设置SPI的通信速率-例如将频率设置为1M*/
	SPI_CR0 |= (0x01<<5);
	/*5:第五步设置SPI主从模式,例如将设置SPI为主机模式*/
	SPI_CR0 |= 0x04;
	/*6:第六步设置SPI工作模式,例如设置为模式0 CPOL=0,CPHA=0*/
	SPI_CR0 &= ~(0x03);
	/*7:第七步开启主模式下的CS输出*/
	SPI_CR1 |= 0x40;
	/*8:第八步选择SPI中断输出口,例如选择INT0输出*/
	IRQ_SEL0 |= 0x40;
	/*9:第九步使能SPI相关中断,例如开启SPI发送中断*/
	SPI_CR1 |= 0x02;
	/*10:第十步开启全局中断和INT0*/
	IE |= 0x81;
	/*11:第十一步使能SPI*/
	SPI_SPE |= 0x01;
	//中断相关函数请查看interrupt.c......
	while(1)
	{
		/*等待SPI发送完成*/
		if(spi_flag)
		{
			/*标志位置0,准备发送数据*/
			spi_flag = 0;
			SPI_DR = 0x0f;
		}
	}
}
/*******************************************interrupt.c***********************************************/
void IRQ_0() interrupt 0 
{
	/*判断SPI是否发送完成*/
	if(SPI_SR & 0x02)
	{
		/*标志位置1*/
		spi_flag = 1;
	}
}

实验结果: 逻辑分析仪抓取数据如下图所示:

在这里插入图片描述

2.3:CS88F003 从模式中断接收数据;

实验目的: 当从机SPI接收到5个数据后,在中断中将spi_flag标志位置1,并且在轮询系统中通过uart1将收到的5个字节发送出去。此实验需要注意主机端和从机端SPI模式(CPOL和CPHA)要配置一致!
实验代码:

/*******************************************main.c***********************************************/
/*uart1配置函数*/
void uart1_send_init(void)
{
	PT1_MUX0 |= 0x40;
	UART1_CLKS = 0x00;
	/*设置波特率115200*/
	UART1_CLKDIVH = 0x00;
	UART1_CLKDIVL = 0x45;
	/*数据格式为10位帧格式*/
	UART1_CTRL &= ~(0x06);
	/*使能uart1*/
	UART1_CTRL |= 0x01;
}
void main(void)
{
	Uint_8U i = 0;
	Sys_Clk_Set_IRCH(SYS_CLK_8M); //芯片默认校准为16M,分频后系统主频8M
	SysClk_Delay(50);
	WDT_OFF(); 
	/*1:第一步开启引脚服用功能,例如PT15-CS,PT10-SCK,PT00-MOSI,PT01-MISO*/
	PT0_MUX1 |= (0x02|0x01);//0x01;
	PT1_MUX1 |= (0x20|0x01);//0x01;
	/*2:第二步打开SPI时钟*/
	SPI_SPE |= 0x02;
	/*3:第三步SPI控制寄存器复位*/
	SPI_CR0 = 0x00;
	SPI_CR1 = 0x00;
	/*4:第四步设置SPI的通信速率,例如设置成1M*/
	SPI_CR0 |= (0x01<<5);
	/*5:第五步设置SPI为从机模式*/
	SPI_CR0 &= ~(0x04);
	/*6:第六步设置SPI的工作模式,例如CPOL=0,CPHA=0*/
	SPI_CR0 &= ~(0x03);
	/*7:第七步选择SPI的中断输出口,例如选择INT0*/
	IRQ_SEL0 |= 0x40;
	/*8:第八步开启SPI接收中断*/
	SPI_CR1 |= 0x01;
	/*9:第九步使能全局中断和INT0*/
	IE |= 0x81;
	/*10:第十步使能SPI*/
	SPI_SPE |= 0x01;
	//具体操作请查看interrupt.c......
	/*UART模块配置*/
	uart1_send_init();
	while(1)
	{
		/*等待SPI接收完成*/
		if(spi_flag)
		{
			/*标志位置0,串口准备发送spi接收到的数据数据*/
			spi_flag = 0;
			for(i = 0; i<5; i++)
			{
				/*将要发送的数据存入发送数据缓存区*/
				UART1_TXD = receive_data[i];
				/*等待数据发送完成*/
				while(UART1_STATE & 0x40);//注意,这里只有检测TBSY1位才能确保数据发送完成,千万不要尝试TC1位!
				/*清除发送完成标志位*/
				UART1_IRQCLR |= 0x40;//官方demo写了,所以才加,实际测试不加也没事。
			}
		}
	}
}
/*******************************************interrupt.c***********************************************/
void IRQ_0() interrupt 0 
{
	/*判断SPI是否接收完成*/
	if(SPI_SR & 0x01)
	{
		/*读取寄存器数据,同时也清标志位*/
		receive_data[rece_cnt++] = SPI_DR;
		/*当收到五个字节时*/
		if(rece_cnt == 5)
		{
			/*复位相应的标志位*/
			spi_flag = 1;
			rece_cnt = 0;
		}
	}
}

实验结果: 逻辑分析仪抓取数据如下图所示:
从逻辑分析仪抓取的数据来看,串口发出的数据集和SPI收到的数据一致,证明从机接收实验成功!
在这里插入图片描述

三:CS88F003 SPI模块使用注意事项;

①:如果是三线模式发送(cs,sck,mosi),在实际测试时你可能会发现miso没开启复用功能也会有波形,这时候最好的方法就是把miso引脚设置为输出模式默认低电平。
②:有些时候主机甚至都不用三线模式,只用双线(sck,mosi),这个其实也只需要把NSS引脚复用给关了就行了。
③:如果用死等的方式,检测数据是否发完成用BSY和TXE标志都可以。
④:这个龟卵东西定义变量要特别注意,反正如果要在函数内部定义数组,最好用xdata修饰给弄到XRAM中去,不然万一出了问题(开了中断就有可能出问题😂)那真的是找到你心碎😥!
⑤:其实官方例程是在中断里发送数据的,因为给SPI_DR寄存器写数据就可以清中断标志,但是我个人不太习惯,所以此例程相当于没清中断标志,但是单芯片单功能实测没问题。

*本例程仅为个人使用记录,具体问题还请参考原厂文档和demo!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值