您现在的位置是:主页 > news > 免费学生网页制作/快速优化seo软件

免费学生网页制作/快速优化seo软件

admin2025/5/4 20:06:45news

简介免费学生网页制作,快速优化seo软件,网络加速器海外,怎么利用招聘网站做薪酬调查NUC970的SPI寄存器足够简单,但是没有DMA支持有点遗憾,现在SPI也算高速设备了,一个4线的SPI FLASH都支持100MHz时钟,400Mbit的速度了,靠中断肯定是不行的,目前NUC970所支持的几种存储器里面,估计…

免费学生网页制作,快速优化seo软件,网络加速器海外,怎么利用招聘网站做薪酬调查NUC970的SPI寄存器足够简单,但是没有DMA支持有点遗憾,现在SPI也算高速设备了,一个4线的SPI FLASH都支持100MHz时钟,400Mbit的速度了,靠中断肯定是不行的,目前NUC970所支持的几种存储器里面,估计…

NUC970的SPI寄存器足够简单,但是没有DMA支持有点遗憾,现在SPI也算高速设备了,一个4线的SPI FLASH都支持100MHz时钟,400Mbit的速度了,靠中断肯定是不行的,目前NUC970所支持的几种存储器里面,估计只能靠TF或者eMMC了,毕竟有DAM支持,nand flash现在用的少,占用IO也多,速度也就那样,块还出奇的大,还要自己做写均衡,坏块管理,eMMC都是BGA封装,目前有个这种的SD NAND 使用的SDIO接口的大容量flash,兼容SD卡驱动,可以实现QFN-8封装的1-2G大容量存储。

 

//足够简单的SPI寄存器


//SPI========================================================================================================
#define SPI0_BASE               (0xB8006200)      //寄存器基址
#define SPI1_BASE               (0xB8006300)      //寄存器基址typedef struct
{vu32 CNTRL;vu32 DIVIDER;vu32 SSR;u32 Reserved1;vu32 DATA[4];
}SPI_TypeDef;#define SPI0                       ((SPI_TypeDef *) SPI0_BASE)
#define SPI1                       ((SPI_TypeDef *) SPI1_BASE)

其中可以支持突发4次传输,理论上可以实现一次传输16字节,但是没啥意义呀,在时钟为18MHz的时候,通讯128bit占用时间为7uS,7us中断一次CPU也不划算,还不如直接阻塞,直接阻塞时使用8bit发送与一次发送16个8bit阻塞时间几乎没区别,如果时钟速度更高,这个时间会更短,就更不能用中断了(太频繁,会降低系统实时性),还不如用可剥夺的实时OS直接阻塞,这就是没有DMA的缺点,有DMA时至少读取512直接都不用一次中断,而且效率更高。

//SPI.c

/************************************************************************************************************** 文件名:			SPI.c* 功能:			NUC970 SPI驱动* 作者:			cp1300@139.com* 创建时间:		2020-09-01* 最后修改时间:	2020-09-01* 详细:			定时器支持
*************************************************************************************************************/
#include "nuc970_system.h"
#include "spi.h"//SPI基址	
static const u32 scg_SPIx_Base[SPI_ChMax] = {SPI0_BASE, SPI1_BASE};
//SPI时钟使能	
static const SYS_DEV_CLOCK scg_SPIx_DeviceClockEnable[SPI_ChMax] 	= {DEV_SPI0, DEV_SPI1};
//外设复位	
static const SYS_DEV_RESET scg_SPIx_DeviceReset[SPI_ChMax] = {	DEV_RESET_SPI0, 	DEV_RESET_SPI1};	
//IO复用功能
static const GPIO_AF_Type scg_SPIx_AF_GPIO[SPI_ChMax][3] = 
{{GPIO_PB7_SPI0_CLK, 	GPIO_PB8_SPI0_DATA0,	GPIO_PB9_SPI0_DATA1}, {GPIO_PI6_SPI1_CLK, 	GPIO_PI7_SPI1_DATA0,	GPIO_PI8_SPI1_DATA1}, 
};/*************************************************************************************************************************
*函数        	:	bool SPIx_Init(SPI_CH_Type ch, const SPI_CONFIG *pConfig)
*功能        	:	SPI初始化
*参数        	:	ch:定时器通道号;pConfig:配置
*返回        	:	TRUE:初始化成功;FALSE:初始化失败;
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
bool SPIx_Init(SPI_CH_Type ch, const SPI_CONFIG *pConfig)
{if(ch > (SPI_ChMax - 1)) return FALSE;							//端口号超出范围SYS_DeviceClockEnable(scg_SPIx_DeviceClockEnable[ch], TRUE);	//使能时钟SYS_DeviceReset(scg_SPIx_DeviceReset[ch]);						//复位外设SPIx_Config(ch, pConfig);										//SPI配置//IO初始化SYS_GPIOx_SetAF(scg_SPIx_AF_GPIO[ch][0]); 						//CLK 复用功能设置SYS_GPIOx_SetAF(scg_SPIx_AF_GPIO[ch][1]); 						//MOSI 复用功能设置SYS_GPIOx_SetAF(scg_SPIx_AF_GPIO[ch][2]); 						//MISO 复用功能设置return TRUE;
}/*************************************************************************************************************************
*函数        	:	void SPIx_SetIOMode(SPI_CH_Type ch, SPI_IO_MODE mode)
*功能        	:	设置IO模式
*参数        	:	ch:SPI道号;mode:模式
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
void SPIx_SetIOMode(SPI_CH_Type ch, SPI_IO_MODE mode)
{u32 RegTemp;SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址RegTemp = SPIx->CNTRL;RegTemp &= ~(BIT22|BIT21|BIT0);							//清除之前配置,不要写入BIT0switch(mode){case SPI_DUAL_IO_MODE:	//双IO模式{RegTemp |= BIT22;}break;case SPI_QUAD_IO_MODE:	//四IO模式{RegTemp |= BIT21;}break;default:break;			//单IO模式}SPIx->CNTRL = RegTemp;
}/*************************************************************************************************************************
*函数        	:	void SPIx_SetMultiIOOut(SPI_CH_Type ch, bool isOutput)
*功能        	:	设置多IO模式(双IO或四IO模式)下IO方向
*参数        	:	ch:SPI道号;isOutput:TRUE:输出方向;FALSE:输入方向
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
void SPIx_SetMultiIODirection(SPI_CH_Type ch, bool isOutput)
{SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址if(isOutput)													//输出模式{SPIx->CNTRL |= BIT20;}else{SPIx->CNTRL &= ~BIT20;}
}/*************************************************************************************************************************
*函数        	:	void SPIx_SetTranBitLeng(SPI_CH_Type ch, u8 BitLen)
*功能        	:	设置单次传输bit长度
*参数        	:	ch:SPI道号;BitLen:bit长度1-32bit
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
void SPIx_SetTranBitLeng(SPI_CH_Type ch, u8 BitLen)
{SPI_TypeDef *SPIx;u32 temp;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址temp = BitLen;if(temp < 1) temp = 1;if(temp > 32) temp = 32;SPIx->CNTRL &= ~(0x1F<<3);SPIx->CNTRL |= temp << 3;
}/*************************************************************************************************************************
*函数        	:	void SPIx_SetOneTranCount(SPI_CH_Type ch, u8 Count)
*功能        	:	设置单次收发次数
*参数        	:	ch:SPI道号;Count:1-4次
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	可以连续多次传输
*************************************************************************************************************************/
void SPIx_SetOneTranCount(SPI_CH_Type ch, u8 Count)
{SPI_TypeDef *SPIx;u32 temp;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址temp = Count;if(temp < 1) temp = 1;if(temp > 4) temp = 4;temp -= 1;SPIx->CNTRL &= ~(0x3<<8);if(temp > 1){SPIx->CNTRL |= temp << 8;}
}/*************************************************************************************************************************
*函数        	:	void SPIx_Config(SPI_CH_Type ch,const SPI_CONFIG *pConfig)
*功能        	:	SPI配置
*参数        	:	ch:SPI道号;pConfig:配置
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	会回复到单IO模式,并且单次只传输一次,不会使用自动片选
*************************************************************************************************************************/
void SPIx_Config(SPI_CH_Type ch, const SPI_CONFIG *pConfig)
{u32 RegTemp;u32 temp1;SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址//CNTRLRegTemp = 0;if(pConfig->isClkIdleHigh)										//时钟空闲高电平使能{RegTemp |= BIT31;}temp1 = pConfig->TranSleepCycle;if(temp1 < 2) temp1 = 2;if(temp1 > 17) temp1 = 17;temp1 -= 2;RegTemp |= temp1 << 12;											//发送空闲周期,连续发送时中间空闲几个时钟周期if(pConfig->isLSB)												//低位在前{RegTemp |= BIT10;}temp1 = pConfig->TranBitLeng;if(temp1 < 1) temp1 = 1;if(temp1 > 32) temp1 = 32;//temp1 -= 1;RegTemp |= temp1 << 3;if(pConfig->isTranNegEdge)										//发送数据下降沿有效{RegTemp |= BIT2;}if(pConfig->isReceNegEdge)										//接收数据下降沿有效{RegTemp |= BIT1;}SPIx->CNTRL = RegTemp;//DIVIDERRegTemp = 0;temp1 = pConfig->ClockDivider;if(temp1 < 2) temp1 = 2;if(temp1 > 131072)temp1 = 131072;temp1 = (temp1+1)/2;RegTemp = temp1 - 1;SPIx->DIVIDER = RegTemp;SPIx->SSR = 0;													//关闭自动片选
}/*************************************************************************************************************************
*函数        	:	void SPIx_SetSpeed(SPI_CH_Type ch, u32 ClockDivider)
*功能        	:	SPI设置时钟速度
*参数        	:	ch:SPI道号;ClockDivider:分频系数2-131072
*返回        	:	无
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
void SPIx_SetSpeed(SPI_CH_Type ch, u32 ClockDivider)
{SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址if(ClockDivider < 2) ClockDivider = 2;if(ClockDivider > 131072)ClockDivider = 131072;ClockDivider = (ClockDivider+1)/2;ClockDivider = ClockDivider - 1;SPIx->DIVIDER = ClockDivider;
}/*************************************************************************************************************************
*函数        	:	u8 SPIx_ReadWriteByte(SPI_CH_Type ch,u8 TxData)
*功能        	:	SPI读写一字节
*参数        	:	ch:SPI道号;TxData:要发送的数据
*返回        	:	读取的一字节
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	
*************************************************************************************************************************/
u8 SPIx_ReadWriteByte(SPI_CH_Type ch,u8 TxData)
{SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return 0;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址SPIx->DATA[0] = TxData;SPIx->CNTRL |= BIT0;											//开始发送数据nop;nop;nop;nop;while(SPIx->CNTRL & BIT0);										//等待发送完成return SPIx->DATA[0] & 0xFF;										//返回读取到的数据
}/*************************************************************************************************************************
*函数        	:	u32 SPIx_ReadWriteData(SPI_CH_Type ch,u32 TxData)
*功能        	:	SPI读写一次数据
*参数        	:	ch:SPI道号;TxData:要发送的数据
*返回        	:	读取的数据
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-09-01
*最后修改时间	:	2020-09-01
*说明        	:	数据长度由通讯bit长度决定
*************************************************************************************************************************/
u32 SPIx_ReadWriteData(SPI_CH_Type ch,u32 TxData)
{SPI_TypeDef *SPIx;if(ch > (SPI_ChMax - 1)) return 0;								//端口号超出范围SPIx = (SPI_TypeDef *) scg_SPIx_Base[ch];						//获取设备基址SPIx->DATA[0] = TxData;while(SPIx->CNTRL & BIT0);										//等待发送完成return SPIx->DATA[0];											//返回读取到的数据
}

//SPI.h

/************************************************************************************************************** 文件名:			SPI.h* 功能:			NUC970 SPI驱动* 作者:			cp1300@139.com* 创建时间:		2020-09-01* 最后修改时间:	2020-09-01* 详细:			定时器支持
*************************************************************************************************************/
#ifndef _SPI_H_  
#define _SPI_H_
#include "nuc970_system.h"//SPI通道选择
typedef enum
{SPI_CH0	=		0,				//SPI0SPI_CH1	=		1,				//SPI1
}SPI_CH_Type;
#define SPI_ChMax		2			//SPI数量//IO模式
typedef enum
{SPI_ONE_IO_MODE		=	0,		//单IO模式SPI_DUAL_IO_MODE	=	1,		//双IO模式SPI_QUAD_IO_MODE	=	2,		//四IO模式
}SPI_IO_MODE;//SPI配置,默认为单IO模式
typedef struct
{bool isClkIdleHigh;				//时钟空闲高电平使能bool isLSB;						//是否低位在前bool isTranNegEdge;				//发送数据下降沿有效bool isReceNegEdge;				//接收数据下降沿有效u8 TranSleepCycle;				//发送空闲周期,连续发送时中间空闲几个时钟周期,设置范围2-17u8 TranBitLeng;					//传输数据bit长度1-32位u32 ClockDivider;				//时钟分频最小2分频,只能是偶数2-131072
}SPI_CONFIG;//API
bool SPIx_Init(SPI_CH_Type ch, const SPI_CONFIG *pConfig);		//SPI初始化
void SPIx_SetSpeed(SPI_CH_Type ch, u32 ClockDivider);			//SPI设置时钟速度
void SPIx_Config(SPI_CH_Type ch, const SPI_CONFIG *pConfig);	//SPI配置
u8 SPIx_ReadWriteByte(SPI_CH_Type ch,u8 TxData);				//SPI读写一字节//不常用API
void SPIx_SetIOMode(SPI_CH_Type ch, SPI_IO_MODE mode);			//设置IO模式
void SPIx_SetMultiIODirection(SPI_CH_Type ch, bool isOutput);	//设置多IO模式(双IO或四IO模式)下IO方向
void SPIx_SetTranBitLeng(SPI_CH_Type ch, u8 BitLen);			//设置单次传输bit长度
void SPIx_SetOneTranCount(SPI_CH_Type ch, u8 Count);			//设置单次收发次数
u32 SPIx_ReadWriteData(SPI_CH_Type ch,u32 TxData);				//SPI读写一次数据#endif //_SPI_H_

//测试

/
//W25X64 FLASH支持						
//SPI接口设置
#define SPI_FLASH_CS					PBout(6)			//W25X16片选
#define W25X16_SPI_CH					SPI_CH0
//W26X16 硬件接口初始化
void __inline W25X16_HardwaveInit(void)		
{const SPI_CONFIG mConfig = {FALSE, FALSE,  FALSE, TRUE, 0, 8, 4};SPIx_Init(W25X16_SPI_CH, &mConfig);SYS_GPIOx_SetAF(GPIO_PB6_IO);SYS_GPIOx_OneInit(GPIOB, 6, OUT_PP, GPIO_IN_NONE);	//初始化一个IOSPI_FLASH_CS = 1;
}/***********************W25X16相关接口************************/
//W25XXX SPI通信接口
u8 BI_W25_SPI_ReadWrtieByte(u8 data)
{return SPIx_ReadWriteByte(W25X16_SPI_CH, data);
}//W25XXX SPI片选控制接口
void BI_W25_SPI_SetCS(u8 CS_Level)
{SPI_FLASH_CS = CS_Level;
}//W25XXX 信号量申请
void BI_W25_MutexPen(void)
{//INT8U err;//OSMutexPend(g_SysGlobal.w25x16_semp, 0, &err);		//申请W25X16信号量
}//W25XXX 信号量释放
void BI_W25_MutexPost(void)
{//OSMutexPost(g_SysGlobal.w25x16_semp);				//释放W25X16信号量
}//初始化W25Q128W25X16_HardwaveInit();						//初始化W25X16底层硬件SPI接口W25X16_OSMutexCreate();						//W25X16信号量初始化-需要在任务中进行初始化while(1){g_SysGlobal.FlashId = W25XXX_Init(&g_SysGlobal.W25X16_Handle, BI_W25_SPI_ReadWrtieByte,			//W25XXX SPI通信接口NULL,//BI_W25_BulkRead,				//SPI批量读取接口NULL,//BI_W25_BulkWrite,			//SPI批量写入接口BI_W25_SPI_SetCS,					//W25XXX SPI片选控制接口Sleep,								//系统ms延时BI_W25_MutexPen,					//W25XXX 信号量申请BI_W25_MutexPost					//W25XXX 信号量释放);uart_printf("FlashId:%d\r\n",g_SysGlobal.FlashId);if(g_SysGlobal.FlashId != FLASH_NULL) break;Sleep(500);}

完整的工程链接:https://download.csdn.net/download/cp1300/12797399