历史上的今天
返回首页

历史上的今天

今天是:2024年08月25日(星期日)

正在发生

2021年08月25日 | 基于LPC1788的SSP1引脚的正确使用方法及注意事项

2021-08-25 来源:elecfans

在学习过程中,发现一点容易被忽视而又很严重的问题---那就是关于SSP1的引脚使用P0[7]-P0[8]-P0[9]时,是W型IO配置。寄存器的第7位很容易被我们设置为0--但是手册上是要求必须为1,否则不能正常工作,这里我走了一点弯路。

基于LPC1788的SSP1引脚的正确使用方法及注意事项

#include“ssp_lpc1788.h”

#define SPI_FLASH_PageSize 256 //页大小

#define SPI_FLASH_PerWritePageSize 256 //写页大小

/*----------------初始化SSP0-------------*/

void SSP0_Init(unsigned long sysClk, unsigned spiClk)

{

volatile uint32_t dummy;

dummy = dummy;

LPC_IOCON-》P2_22 =0x22; // SSP0_SCK

LPC_IOCON-》P2_26 =0x22; // SSP0_MISO

LPC_IOCON-》P2_27 =0x22; // SSP0_MOSI

LPC_IOCON-》P2_23=0x30; //SSP1_CS-直接普通上拉IO

LPC_GPIO2-》DIR “= (1UL 《《 23); //输出

LPC_GPIO2-》SET|=(1《《23);//置一

LPC_SC-》PCONP |= (1UL 《《 21); //SSP0 时钟开启

LPC_SSP0-》CR0 = 0x0007; // 8Bit, CPOL=0, CPHA=0

LPC_SSP0-》CR1 = 0x0002; // SSP0-使能-主模式

LPC_SSP0-》CPSR = sysClk/spiClk; //时钟预分频寄存器

while( LPC_SSP0-》SR & ( 1 《《 4 ) ); //忙

while( LPC_SSP0-》SR & ( 1 《《 2 ) ) //接收FIFO不为空

{

dummy = LPC_SSP0-》DR; //假读取去清空FIFO

}

}

/*-------------SSP0-发送数据-----------------*/

void SSP0_WriteByte(unsigned char data)

{

uint8_t Dummy;

LPC_SSP0-》DR = data; //载入要发送的数据

while (LPC_SSP0-》SR & (1 《《 4)){}//等待发送完成

Dummy=LPC_SSP0-》DR; //假读取去清空FIFO

}

/*-------------SSP0-接收数据-----------------*/

uint8_t SSP0_RegisterByte(void)

{

LPC_SSP0-》DR = 0xFF; //无效指令

while (LPC_SSP0-》SR & (1 《《 4)){}//忙等待

return (LPC_SSP0-》DR); //接收数据

}

/*-----------------------------------SSP1--------------------------*/

/*----------------初始化SSP1-------------*/

void SSP1_Init(unsigned long sysClk, unsigned spiClk)

{

volaTIle uint32_t dummy;

LPC_IOCON-》P0_7 =0xA2; // SSP1_SCK

LPC_IOCON-》P0_8 =0xA2; // SSP1_MISO

LPC_IOCON-》P0_9 =0xA2; // SSP1_MOSI

LPC_IOCON-》P0_6=0x30; //SSP1_CS-普通上拉IO

LPC_GPIO0-》DIR |= (1UL 《《 6); //输出

LPC_GPIO0-》SET|=(1《《6);//置一

LPC_SC-》PCONP |= (1UL 《《 10); //SSP1 时钟开启

LPC_SSP1-》CR0 = 0x0007; // 8Bit, CPOL=0, CPHA=0

LPC_SSP1-》CR1 = 0x0002; // SSP1-使能-主模式

LPC_SSP1-》CPSR = sysClk/spiClk; //时钟预分频寄存器

while( LPC_SSP1-》SR & ( 1 《《 4 ) ); //忙

while( LPC_SSP1-》SR & ( 1 《《 2 ) ) //接收FIFO不为空

{

dummy = LPC_SSP1-》DR; //假读取去清空FIFO

}

}

/*-------------SSP1-发送数据-----------------*/

void SSP1_WriteByte(unsigned char data)

{

uint8_t Dummy;

LPC_SSP1-》DR = data; //载入要发送的数据

while (LPC_SSP1-》SR & (1 《《 4)){} //等待发送完成

Dummy=LPC_SSP1-》DR; //假读取去清空FIFO

}

/*-------------SSP1-接收数据-----------------*/

uint8_t SSP1_RegisterByte(void)

{

LPC_SSP1-》DR = 0xFF; //无效指令

while (LPC_SSP1-》SR & (1 《《 4)){} //忙等待

return (LPC_SSP1-》DR); //接收数据

}

/*---------------------W25Q16---------------*/

//---------写使能---

void SSP_FLASH_WriteEnable(void)

{

FLASH_CS_LOW();

SSP0_WriteByte(0x06);

FLASH_CS_HIGH();

}

//--------等待写完成--

void SSP_FLASH_WaitForWriteEnd(void)

{

uint16_t i=2000;

uint8_t FLASH_Status = 0;

FLASH_CS_LOW();

SSP0_WriteByte(0x05);

do

{

FLASH_Status = SSP0_RegisterByte();

i--;

}

while (((FLASH_Status & 0x01) == 1)||(i==0));

FLASH_CS_HIGH();

}

/*----关于擦除---在写入数据之前必须保证被写入的位值是0xff---这就是擦除的作用*/

//-------------扇区擦除----------

void SSP_FLASH_SectorErase(uint32_t SectorAddr)

{

SSP_FLASH_WriteEnable();//写使能

SSP_FLASH_WaitForWriteEnd();//忙状态

FLASH_CS_LOW();//CS=0

SSP0_WriteByte(0x20);//0x20

SSP0_WriteByte((SectorAddr & 0xFF0000) 》》 16);//擦除扇区起始地址

SSP0_WriteByte((SectorAddr & 0xFF00) 》》 8);

SSP0_WriteByte(SectorAddr & 0xFF);

FLASH_CS_HIGH();//CS=1

SSP_FLASH_WaitForWriteEnd();//忙状态--等待擦除完成

}

//-----------块擦除-------

void SSP_FLASH_BlockErase(uint32_t BlockAddr)

{

BlockAddr*=65536;//0x010000

SSP_FLASH_WriteEnable();//写使能

SSP_FLASH_WaitForWriteEnd();

FLASH_CS_LOW();

SSP0_WriteByte(0xD8);//0xD8

SSP0_WriteByte((BlockAddr & 0xFF0000) 》》 16);//擦除块起始地址

SSP0_WriteByte((BlockAddr & 0xFF00) 》》 8);

SSP0_WriteByte(BlockAddr & 0xFF);

FLASH_CS_HIGH();

SSP_FLASH_WaitForWriteEnd();

}

//----------整片擦除--

void SSP_FLASH_BulkErase(void)

{

SSP_FLASH_WriteEnable(); //写使能

FLASH_CS_LOW();

SSP0_WriteByte(0xc7); //整片擦除

FLASH_CS_HIGH();

SSP_FLASH_WaitForWriteEnd();

}

//---------单页写入-----

void SSP_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)

{

SSP_FLASH_WriteEnable();

FLASH_CS_LOW();

SSP0_WriteByte(0x02);//CMD2--0x02--------页写入

SSP0_WriteByte((WriteAddr & 0xFF0000) 》》 16);//写入起始地址

SSP0_WriteByte((WriteAddr & 0xFF00) 》》 8);

SSP0_WriteByte(WriteAddr & 0xFF);

if(NumByteToWrite 》 SSP_FLASH_PerWritePageSize) //写入数据多余页最大数据

NumByteToWrite = SSP_FLASH_PerWritePageSize;

while (NumByteToWrite--)

{

SSP0_WriteByte(*pBuffer); //写数据

pBuffer++;

}

FLASH_CS_HIGH();

SSP_FLASH_WaitForWriteEnd();

}

//--------多页写入---

void SSP_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)

{

uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;

Addr = WriteAddr % SSP_FLASH_PageSize; //首页地址

count = SSP_FLASH_PageSize - Addr;//首页要写入的数据个数

NumOfPage = NumByteToWrite / SSP_FLASH_PageSize;//页数

NumOfSingle = NumByteToWrite % SSP_FLASH_PageSize; //余数--最后一页不满一页个数

if (Addr == 0)

{

if (NumOfPage == 0) //只有一页

{

SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite); //?±?óD′è?

}

else //多页

{

while (NumOfPage--) //写满页的数据

{

SSP_FLASH_PageWrite(pBuffer, WriteAddr, SSP_FLASH_PageSize);

WriteAddr += SSP_FLASH_PageSize;

pBuffer += SSP_FLASH_PageSize;

}

SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);//写最后不满一页的数据

}

}

else

{

if (NumOfPage == 0)

{

if (NumOfSingle 》 count)

{

temp = NumOfSingle - count;

SSP_FLASH_PageWrite(pBuffer, WriteAddr, count);

WriteAddr += count;

pBuffer += count;

SSP_FLASH_PageWrite(pBuffer, WriteAddr, temp);

}

else

{

SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);

}

}

else

{

NumByteToWrite -= count;

NumOfPage = NumByteToWrite / SSP_FLASH_PageSize;

NumOfSingle = NumByteToWrite % SSP_FLASH_PageSize;

SSP_FLASH_PageWrite(pBuffer, WriteAddr, count);

WriteAddr += count;

pBuffer += count;

while (NumOfPage--)

{

SSP_FLASH_PageWrite(pBuffer, WriteAddr, SSP_FLASH_PageSize);

WriteAddr += SSP_FLASH_PageSize;

pBuffer += SSP_FLASH_PageSize;

}

if (NumOfSingle != 0)

{

SSP_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);

}

}

}

}

//--------读数据-----------

void SSP_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)

{

FLASH_CS_LOW();

SSP0_WriteByte(0x03); //CMD3--0x03-----//读数据

SSP0_WriteByte((ReadAddr & 0xFF0000) 》》 16);

SSP0_WriteByte((ReadAddr& 0xFF00) 》》 8);

SSP0_WriteByte(ReadAddr & 0xFF);

while (NumByteToRead--)

{

*pBuffer = SSP0_RegisterByte();//读入到指定数组

pBuffer++;

}

FLASH_CS_HIGH();

}

/*-----------读取厂家ID------------*/

uint32_t SSP_FLASH_ReadID(void)

{

uint32_t temp1=0,temp2=0,temp3=0,temp=0;

LPC_GPIO0-》CLR|=(1《《6); //CS=0

SSP1_WriteByte(0x9F); //读取ID指令

temp1 =SSP1_RegisterByte(); //厂家编号

temp2 =SSP1_RegisterByte();//存储类型

temp3 =SSP1_RegisterByte();//容量

temp =(temp1《《16)|(temp2《《8)|(temp3);

LPC_GPIO0-》SET|=(1《《6);//CS=1;

return temp;

推荐阅读

史海拾趣

Comus_International公司的发展小趣事

Comus International深知,要想在竞争激烈的电子行业中立足,除了不断创新外,还需要注重产品质量和服务。因此,公司一直将质量和服务作为核心竞争力,不断提升产品质量和服务水平。正是这种对质量和服务的执着追求,使得Comus International在市场上赢得了客户的广泛认可和信赖。

Hongfa公司的发展小趣事

宏发公司的发展离不开自主研发和技术创新。1998年,宏发成立了精合公司,开启了自主研发自动化设备设计及制造的征程。此后,公司不断加大在技术研发上的投入,建立了博士后科研工作站和院士专家工作站,形成了从产品研发、模具制造、零件制造到自动化成品装配及在线检测的一体化全产业链。通过技术创新,宏发不仅提升了产品性能和质量,还成功打破了国外技术垄断,实现了高端继电器的自主研发和生产。

GradConn Ltd公司的发展小趣事

GradConn始终将技术创新作为公司发展的核心驱动力。公司拥有一支专业的研发团队,致力于开发新型连接器和电缆组件,以满足不断变化的市场需求。同时,GradConn的所有工厂均通过了ISO 9001:2015和ISO 14001:2015等国际质量管理体系认证,确保了产品的高质量和环境友好性。这些认证不仅提升了GradConn的品牌形象,还为其在全球市场上赢得了更多客户的信任和支持。

ARMKEIL Microcontroller Tools公司的发展小趣事

为了进一步扩大业务范围和提升技术实力,Keil公司决定与美国德克萨斯州理查森的Keil Software Inc进行联合运营。这一举措不仅使公司得以接触更广阔的市场,还促进了双方在技术、产品和市场等方面的深度融合。联合运营后,Keil公司的发展速度明显加快,逐渐在嵌入式系统开发工具市场上占据了重要地位。

蜂鸟无线公司的发展小趣事
由于PWM调速是通过调整电压脉冲的占空比来控制电动机的平均电压,因此能够减少能量损失,提高系统的能效。
ERGOBAHCO公司的发展小趣事

随着公司规模的扩大,ERGOBAHCO公司逐渐意识到品质与创新对于品牌的重要性。公司投入大量资金引进先进的生产设备和技术,并建立了严格的质量管理体系。同时,ERGOBAHCO公司还鼓励员工进行创新研发,不断推出具有市场竞争力的新产品。这些举措使得ERGOBAHCO公司的产品逐渐在行业内树立了良好的口碑,品牌知名度也随之提升。

问答坊 | AI 解惑

全段调频收音机原理图

一个网友的全段调频收音机原理图,该电路比较简捷,采用频率合成高频头,电子控制音量,供大家参考. [ 本帖最后由 RF研究 于 2009-9-14 18:55 编辑 ]…

查看全部问答>

wince 启动初始化 FLASH 之后做什么?

请问,     wince 启动的时候,初始化FLASH之后是做什么操作呢?     我怎么知道 FLASH 初始化有没有成功呢? 谢谢…

查看全部问答>

windows mobile上的数据拷贝(类似于PC的GHOST软件)

各位高手,最近小弟遇到一个问题,如何在windows mobile下实现类似于PC中GHOST软件,即读取ROM中的所有内容. 本人尝试过几种方法:(平台是VS2005 + Windows Mobile 5.0 Smartphone SDK) 1.在PC桌面端开发应用程序,用RAPI读取手机数据,其中用到了CeC ...…

查看全部问答>

请教,在程序只读存储器的绝对地址写数据的问题

芯片是cc2430 运行环境是IAR 片外寄存器的0x0000-0xDF00是程序存储器, 在程序存储器的某个地址定义了一个字节的数据, #define DATA1 ((volatile xdata*)0x0010) = 0x0F 可是读这个地址的数据时,出现了问题 我读DATA1 的值为0x0F,但读地 ...…

查看全部问答>

西安大唐电信FPGA/CPLD设计经验分享

大家一块学习,一块进步。。。。 [ 本帖最后由 何事西风悲画扇 于 2010-11-22 10:56 编辑 ]…

查看全部问答>

555和面包板让我很郁闷

今天,有个人突然给我打电话,是我舍友的朋友。 那家伙说,他想整一个东西: 比方说,游泳池,有人下水。由某个传感器,如果他在水里就一直保持一个信号,出了水,则翻转。(我猜测他是这么想的。) 然后,他的想法也挺可爱:如果在水里超过一定 ...…

查看全部问答>

想要一块LM3S811的评估板!来学习

LM3S811新兵营——TI LM3S811 ARM评估板那天正好在火车上 没网络 没抢到 。下个学期想学习ARM。有人能循环利用下 送我一块吗!最好有板和对板的一些参考资料!谢谢了!有好心的朋友 帮助下我这个爱学习的大专学生把!请联系我QQ315873128!或发邮件 ...…

查看全部问答>

关于TI精品课程欢乐学习季!

为什么我每次进入学习页面后就会卡在第一个界面?  …

查看全部问答>

BioLite Wood Burning CampStove 便携型火力发电站

科技在不断的进步,待机时间在不断的倒退。为了享受更多的功能,一天一充电已经成了智能手机的一项基本特征。这对日常工作生活可能没什么太大影响,但在进行户外活动时,出门在外好几天是常有的事,当您身上能放电的东西都放完了,又寻电无觅处时, ...…

查看全部问答>

关于最近非NQARM官方网络上提供下载的Sate210 orcad 原理图Sate210 PCB的声明

          作者:gooogleman@foxmail.com                                 日期:2013.05.12 & ...…

查看全部问答>