历史上的今天
返回首页

历史上的今天

今天是:2024年12月12日(星期四)

正在发生

2018年12月12日 | LPC1768 SPI 外设控制DA(PCM1796)调试记录

2018-12-12 来源:eefocus

#include "DA1796.h"

#define SPI_ID          (2)



#define    SPI2_CS      (1 << 16)                                        /* P0.16口为片选脚              */

#define    CE2_Low()    (LPC_GPIO0->FIOCLR |=  SPI2_CS)                   /* 选中从器件                   */

#define    CE2_High()   (LPC_GPIO0->FIOSET |=  SPI2_CS)



#define    SPI3_CS      (1 << 21)                                        /* P1.21口为片选脚              */

#define    CE3_Low()    (LPC_GPIO1->FIOCLR |=  SPI3_CS)                   /* 选中从器件                   */

#define    CE3_High()   (LPC_GPIO1->FIOSET |=  SPI3_CS)


#define  RESET_1796()   (LPC_GPIO4->FIOCLR |=  (1<<28))

#define  WORK_1796()    (LPC_GPIO4->FIOSET |=  (1<<28))



volatile uint8_t   RcvFlag = 0;                                         /* 接收到新数据标志              */

volatile uint8_t   RcvData = 0;                                         /* 接收到的数据                 */



//U47

void  SSP1_Init_SPI1(void)

{

    LPC_SC->PCONP |= (1 << 21);                                         /* 打开SSP0电源                 */

    /**

    P0.6:SPI1_SEL

    P0.7:SPI1_CLK

    P0.8:SPI1_MISO

    P0.9:SPI1_MOSI

    **/

    /* SSEL1 | SCK1 |MISO1 | MOSI1 设置管脚功能                 */

    LPC_PINCON->PINSEL0 |= (0x02ul << 12) | (0x02ul << 14) | (0x02ul << 16) |(0x02ul << 18);

    /*

    * 设置数据长度为8位,帧格式SPI,SCK高有效,第一个时钟沿采样,位速率为默认值

    */

    LPC_SSP1 ->CR0 = (0x01 << 8)                                         /* SCR  设置SPI时钟分频   25M/(0x24 * (0x01+1))      */

                     | (0x00 << 7)                                         /* CPHA 时钟输出相位            */

                     | (0x00 << 6)                                         /* CPOL 时钟输出极性            */

                     | (0x00 << 4)                                         /* FRF  帧格式 00=SPI           */

                     | (0x0F << 0);                                        /* DSS  数据长度,16bit       */


    LPC_SSP1->CR1 = (0x00 << 3)                                         /* SOD  从机输出禁能,0=允许     */

                    | (0x00 << 2)                                         /* MS   主从选择,0=主机,1=从机  */

                    | (0x01 << 1)                                         /* SSE  SSP使能                 */

                    | (0x00 << 0);                                        /* LBM  回写模式                */

    LPC_SSP1->CPSR = 0x24; //0x52;                                              /* 设置SSP从PCLK获得的分频值,   */

    /* 主模式下有效, 最小值为0x02   */

}



/*********************************************************************************************************

** Function name:      SSP_SendData

** Descriptions:       SSP接口向SSP总线发送数据

** input parameters:   data        待发送的数据

** output parameters:  返回值为读取的数据

*********************************************************************************************************/

uint16_t  SSP1_SendData(uint16_t data)

{

    while ((LPC_SSP1->SR & 0x02) == 0);                                 /* 等待发送FIFO留出空间         */

    LPC_SSP0->DR = data;

    while ((LPC_SSP1->SR & 0x10) == 0x10);                              /* 等待数据帧发送完毕           */

    return ((uint16_t)LPC_SSP1->DR);

}


void SSPSendCmd_SPI1(uint8_t addr,uint8_t ndata)

{

    uint16_t data = (0<<15) | (addr<<8) | (ndata);

    SSP1_SendData(data);

}


 


 


/*********************************************************************************************************

** Function name:     SSP0_Init

** Descriptions:      将SSP控制器设置为主机

** input parameters:  无

** output parameters: 无

**********************************************************************************************************/

void  SSP0_Init_SPI3(void)

{

    LPC_SC->PCONP |= (1 << 21);                                         /* 打开SSP0电源                 */


    /**

    P1.21:SPI3_SEL

    P1.20:SPI3_CLK

    P1.23:SPI3_MISO

    P1.24:SPI3_MOSI

    **/

    /* SSEL0 | SCK0 |MISO0 | MOSI0 设置管脚功能          U2       */

    LPC_PINCON->PINSEL3 |= (0x03ul << 8) | (0x03ul << 10) | (0x03ul << 14) |(0x03ul << 16);


    /*

    * 设置数据长度为8位,帧格式SPI,SCK高有效,第一个时钟沿采样,位速率为默认值

    */

    LPC_SSP0->CR0 = (0x01 << 8)                                         /* SCR  设置SPI时钟分频   25M/(0x24 * (0x01+1))      */

                    | (0x00 << 7)                                         /* CPHA 时钟输出相位            */

                    | (0x00 << 6)                                         /* CPOL 时钟输出极性            */

                    | (0x00 << 4)                                         /* FRF  帧格式 00=SPI           */

                    | (0x0F << 0);                                        /* DSS  数据长度,16bit       */


    LPC_SSP0->CR1 = (0x00 << 3)                                         /* SOD  从机输出禁能,0=允许     */

                    | (0x00 << 2)                                         /* MS   主从选择,0=主机,1=从机  */

                    | (0x01 << 1)                                         /* SSE  SSP使能                 */

                    | (0x00 << 0);                                        /* LBM  回写模式                */

    LPC_SSP0->CPSR = 0x24; //0x52;                                              /* 设置SSP从PCLK获得的分频值,   */

    /* 主模式下有效, 最小值为0x02   */

}


/*********************************************************************************************************

** Function name:      SSP_SendData

** Descriptions:       SSP接口向SSP总线发送数据

** input parameters:   data        待发送的数据

** output parameters:  返回值为读取的数据

*********************************************************************************************************/

uint16_t  SSP0_SendData(uint16_t data)

{

    while ((LPC_SSP0->SR & 0x02) == 0);                                 /* 等待发送FIFO留出空间         */

    LPC_SSP0->DR = data;

    while ((LPC_SSP0->SR & 0x10) == 0x10);                              /* 等待数据帧发送完毕           */

    return ((uint16_t)LPC_SSP0->DR);

}


void SSPSendCmd_SPI3(uint8_t addr,uint8_t ndata)

{

    uint16_t data = (0<<15) | (addr<<8) | (ndata);

    SSP0_SendData(data);

}


 



/*********************************************************************************************************

** Function name:       SPI_IRQHandler

** Descriptions:        SPI中断服务函数

** input parameters:    无

** output parameters:   无

** Returned value:      无

*********************************************************************************************************/

void  SPI_IRQHandler(void)

{

    uint32_t tmp = 0;

    /*

     * SPI读取数据寄存器之前,必须先读SPSR寄存器,清零SPIF位。

     */

    tmp     = LPC_SPI->SPSR;

    RcvData = LPC_SPI->SPDR;                                            /* 接收数据                     */

    RcvFlag = 0x01;                                                     /* 接收到新数据                 */

    LPC_SPI->SPINT = 0x01;                                              /* 清除标志位                   */

    tmp = tmp;

}


 



//初始化SPI

void InitSPI2(void)

{

    LPC_SC->PCONP |= (1 << 8);//I2C0


    /* 初始化SPI2引脚  SPI外设时钟 25M   */

    LPC_PINCON->PINSEL0 |= (0x03ul << 30);                             /* 设置P0.15脚为SCK脚           */

    LPC_PINCON->PINSEL1 &= ~(0x03 << 0);                                /*P0.16为GPIO*/

    LPC_GPIO0->FIODIR   |=  SPI2_CS;                                    /* 设置SPI的片选引脚            */

    LPC_PINCON->PINSEL1 |=  (0x03 << 2) | (0x03 << 4);                 /* 设置P0.17、P0.18             */

    /* 引脚为SPI引脚                */



    /* 初始化SPI寄存器  PCM1796 SCK 最大10M    */

    LPC_SPI->SPCCR  =  0x48;                                            /* 设置SPI时钟分频 在主机模式下此值必须大于8的偶数    2.5M         */

    LPC_SPI->SPCR   =   (1 << 2) |                                      /* SPI控制器每次传输   PCM1796 传输数据16bit         */

                        /* 发送和接收多位数据            */

                        (0 << 3) |                                      /* CPHA = 0, 数据在SCK          */

                        /* 的第一个时钟沿采样           */

                        (0 << 4) |                                      /* CPOL = 0, SCK 为高有效       */

                        (1 << 5) |                                      /* MSTR = 1, SPI 处于主模式     */

                        (0 << 6) |                                      /* LSBF = 0, SPI 数据           */

                        /* 传输MSB (位7)在先            */

                        (1 << 7)|                                       /* SPIE = 0, SPI 中断被使能     */

                        (0x00 << 8);                                 //  8-11位控制传输数据的位数


    NVIC_EnableIRQ(SPI_IRQn);                                           /* 初始化SPI的中断接口           */

    NVIC_SetPriority(SPI_IRQn, 4);

}



/*********************************************************************************************************

** 函数名称:  SPISndByte

** 函数功能:  通过硬件SPI接口发送一个字节

** 入口参数:  data

** 出口参数:  无

PCM1796 操作写数据都是16位,读数据是低8位有效

bit15: 1-R  0-W

bit14-8:addr

bit7-0:data

*********************************************************************************************************/

void SPI2SndByte(uint8_t addr,uint8_t ndata)

{

    uint32_t temp = 0;

    addr = addr & 0x7F;

    uint16_t SPI_data = (0<<15) | (addr<<8) | (ndata);


    CE2_Low();


    LPC_SPI->SPDR = SPI_data;

    while (0 == (LPC_SPI->SPSR & 0x80));                                /* 等待SPIF置位,               */

    /* 即等待数据发送完毕           */

    temp   = (uint32_t)LPC_SPI->SPSR;                                   /* 通过读S0SPSR,               */

    /* 清除SPIF标志                 */


    CE2_High();


    temp = temp;

}


 


//发送读命令

void SPIReadCmd(uint8_t SpiID,uint8_t addr)

{

    uint32_t temp = 0;

    uint8_t ndata = 0;

    addr = addr & 0x7F;

    uint16_t SPI_data = (1<<15) | (addr<<8) | (ndata);

    if(2 == SpiID)

        CE2_Low();

    else if(3 == SpiID)

        CE3_Low();

    else

        return;

    LPC_SPI->SPDR = SPI_data;

    while (0 == (LPC_SPI->SPSR & 0x80));                                /* 等待SPIF置位,               */

    /* 即等待数据发送完毕           */

    temp   = (uint32_t)LPC_SPI->SPSR;                                   /* 通过读S0SPSR,               */

    /* 清除SPIF标志                 */

    if(2 == SpiID)

        CE2_High();

    else if(3 == SpiID)

        CE3_High();

    else

        return;


    temp = temp;

}


 


/* 在配置FIODIR为输出后,会将默认为低电平,此时接到复位,将芯片会复位*/

//注意1796复位管脚连接到P4.28  至少20ns的低电平复位

void Init1796(void)

{

    //配置P4.28为GPIO口

//    int nRet = 0;

//    LPC_GPIO4->FIODIR |= (0x00000000|(1<<28)); //方向控制

//    LPC_GPIO4->FIOPIN |=  (0x00000000|(1<<28));

//    LPC_PINCON->PINSEL9 |= (0x02<<24);  //内部不上拉也不下拉

//    while(1) {

//        RESET_1796();

//        for( nRet = 0; nRet<1000; nRet++);

//        WORK_1796();

//        for( nRet = 0; nRet<1000; nRet++);

//    }

// U1

    InitSPI2();

    //先读23号寄存器

    while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG23_ADDR);

        if((RcvFlag == 1) && (RcvData == 0x1f))

            break;

    }


    SPI2SndByte(PCM1796_REG20_ADDR,0x40);    //复位PCM1796

    for(int i = 0; i<1000; i++);  //复位后短暂延时

////////////////////////////////////////////

 while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG18_ADDR);

        if((RcvFlag == 1))

            break;

    }

 while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG19_ADDR);

        if((RcvFlag == 1))

            break;

    }

 while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG20_ADDR);

        if((RcvFlag == 1))

            break;

    }

 while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG21_ADDR);

        if((RcvFlag == 1))

            break;

    }

 

/////////////////////////////////////////////////////

//    SPI2SndByte(PCM1796_REG16_ADDR,0xFF);    //不衰减

//    SPI2SndByte(PCM1796_REG17_ADDR,0xFF);


    SPI2SndByte(PCM1796_REG18_ADDR,0x36);        //0b10110100  48k 24bit 左对齐

    while(1) {

        RcvFlag = 0;

        RcvData = 0;

//        SPIReadCmd(SPI_ID,PCM1796_REG18_ADDR);

//        if((RcvFlag == 1) && (RcvData == 0x36))

//            break;

    }

    SPI2SndByte(PCM1796_REG19_ADDR,0x20);

    while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG19_ADDR);

        if((RcvFlag == 1)  && (RcvData == 0x20))

            break;

    }

//    SPI2SndByte(PCM1796_REG20_ADDR,0x01);

    SPI2SndByte(PCM1796_REG20_ADDR,0x02);

    while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG20_ADDR);

        if((RcvFlag == 1) && (RcvData == 0x02))

            break;

    }


    SPI2SndByte(PCM1796_REG21_ADDR,0x01);

    while(1) {

        RcvFlag = 0;

        RcvData = 0;

        SPIReadCmd(SPI_ID,PCM1796_REG21_ADDR);

        if((RcvFlag == 1)  && (RcvData == 0x01))

            break;

    }

//初始化U2

    SSP0_Init_SPI3();

    SSPSendCmd_SPI3(PCM1796_REG20_ADDR,0x40);    //复位PCM1796

    SSPSendCmd_SPI3(PCM1796_REG20_ADDR,0x00);

    SSPSendCmd_SPI3(PCM1796_REG20_ADDR,0x02);//|0x08|0x04

    SSPSendCmd_SPI3(PCM1796_REG18_ADDR,0x36);

    SSPSendCmd_SPI3(PCM1796_REG19_ADDR,0x20);

    SSPSendCmd_SPI3(PCM1796_REG21_ADDR,0x01);


//U47

    SSP1_Init_SPI1();

    SSPSendCmd_SPI1(PCM1796_REG20_ADDR,0x40);    //复位PCM1796

    SSPSendCmd_SPI1(PCM1796_REG20_ADDR,0x00);

    SSPSendCmd_SPI1(PCM1796_REG20_ADDR,0x02);

    SSPSendCmd_SPI1(PCM1796_REG18_ADDR,0x36);

    SSPSendCmd_SPI1(PCM1796_REG19_ADDR,0x20);

    SSPSendCmd_SPI1(PCM1796_REG21_ADDR,0x01);

}


}


推荐阅读

史海拾趣

Hamlin ( Littelfuse )公司的发展小趣事

故事一:市场定位与技术创新

HAHN - Elektrobau GmbH & Co KG公司自成立以来,便在电子行业中找到了自己的独特定位,专注于生产面向特定应用的特种变压器线圈。起初,公司通过深入研究市场需求,发现传统变压器线圈在特定应用中存在效率低下、体积过大等问题。于是,HAHN投入大量资源进行技术研发,优化产品设计,成功开发出了一系列高效、紧凑的特种变压器线圈,迅速赢得了市场的认可。这一举措不仅巩固了公司在电子行业中的地位,也为后续的发展奠定了坚实的基础。

故事二:合作与共赢

在发展过程中,HAHN深知合作的重要性。公司积极与上下游企业建立紧密的合作关系,共同推动技术进步和产业升级。例如,HAHN与多家知名电子制造商建立了长期合作关系,共同开发新产品,优化生产工艺。通过这些合作,HAHN不仅获得了宝贵的市场信息和技术支持,还成功地将自身产品打入了更广阔的市场领域。同时,公司还积极与供应商和分包商合作,通过优化供应链管理,降低了生产成本,提高了生产效率,实现了共赢发展。

故事三:全球化战略

随着电子行业的全球化趋势日益明显,HAHN也开始了自己的全球化战略。公司不仅在欧洲市场取得了显著成绩,还积极向亚洲、北美等市场扩张。为了更好地服务全球客户,HAHN在多个国家和地区设立了分支机构,并建立了完善的销售和服务网络。通过这些举措,HAHN成功地将自己的产品和服务推向了全球市场,进一步提升了品牌知名度和市场份额。

故事四:品质与服务的双重保障

在电子行业中,品质和服务是企业生存和发展的关键。HAHN深知这一点,因此始终将品质和服务放在首位。公司建立了严格的质量控制体系,对每一个环节都进行严格的把关,确保产品质量达到最高标准。同时,公司还注重提升客户服务水平,建立了专业的客户服务团队,为客户提供全方位、个性化的服务。这些举措不仅赢得了客户的信赖和好评,也为公司赢得了更多的业务机会。

故事五:持续研发与创新

面对日新月异的电子行业技术,HAHN始终保持着高度的敏锐性和前瞻性。公司不断加大研发投入,引进高端人才和先进设备,致力于新技术、新产品的开发。通过持续的研发和创新,HAHN不断推出具有自主知识产权的新产品和技术方案,为电子行业的发展注入了新的活力。同时,公司还积极参与行业标准的制定和修订工作,推动行业技术进步和产业升级。这些努力不仅提升了公司的核心竞争力,也为公司的可持续发展奠定了坚实的基础。

Caddell-Burns Manufacturing公司的发展小趣事

随着科技的不断发展,Caddell-Burns Manufacturing公司意识到技术创新是保持竞争力的关键。于是,公司加大了对研发的投入,引进了一批高素质的技术人才,不断推出具有创新性的电子产品。这些新产品不仅提高了公司的市场份额,也为客户提供了更优质的服务。同时,公司还积极与高校和研究机构合作,开展产学研一体化项目,进一步提升了公司的技术实力。

EEMB Co Ltd公司的发展小趣事

为了适应公司业务的快速发展和满足市场需求的不断增长,EEMB集团于2017年在汉川市修建了新工厂。新工厂占地面积120亩,使用面积达27000平方米,配备了先进的生产设备和技术。一期工程全面投入生产后,公司的产能得到了显著提升,能够更好地满足客户的订单需求。同时,新工厂的建成也进一步提升了公司的生产效率和产品质量。

艾谱科(Epticore)公司的发展小趣事

艾谱科公司深知技术创新的重要性。为了保持产品的竞争力,公司不断加大研发投入,积极引进高素质人才,并与国内外知名科研机构建立合作关系。在研发团队的努力下,艾谱科不断推出具有创新性的产品,如低功耗处理器、高速数据传输模块等。这些新产品不仅提升了公司的市场竞争力,也为客户提供了更加优质的产品选择。

FCI / Amphenol公司的发展小趣事

FCI公司起源于1988年,当时由Framatome组建,其初衷是作为核能领域外的一个多样化经营项目。然而,随着市场的变化和公司的战略调整,FCI逐渐将重心转向连接器制造。经过20多次的精心收购和策略性扩张,FCI在短短20年内便成长为全球最大的连接器制造公司之一。这一转变不仅展现了FCI对市场敏锐的洞察力,也体现了其卓越的管理能力和执行力。

BELLING LEE公司的发展小趣事

随着电子市场的不断发展和消费者需求的多样化,BELLING LEE公司意识到单一的产品线已无法满足市场需求。于是,公司开始积极拓展产品线,推出了包括智能手机、平板电脑、智能家居设备等一系列新产品。这些新产品不仅满足了消费者的多样化需求,也进一步巩固了公司在电子市场的领先地位。

问答坊 | AI 解惑

PCB设计技巧百问(1-10)

1、如何选择PCB板材? 选择PCB板材必须在满足设计需求和可量产性及成本中间取得平衡点。设计需求包含电气和 机构这两部分。通常在设计非常高速的PCB板子(大于GHz的频率)时这材质问题会比较重要。 例如,现在常用的FR-4材质,在几个GHz的频率时 ...…

查看全部问答>

碰到一个问题关于EP2C35

上周调试时,碰到一个问题,同一个程序在两块相同的硬件表现为不同的现象。一块正常,一块不正常。为啥?…

查看全部问答>

如何判断USB HOST功能正常与否

调了好长时间的OTG的HOST功能. 现在有点眉目,但是如何判断HOST功能已经正常了? 现在U盘插上去后,灯闪了一下就灭了. 打印消息说, 已探测到外部设备插入,而且识别了设备的速度,然后就等待port的状态变化... 这种现象正常吗? 我 ...…

查看全部问答>

WINCE下驱动项目外包

现有两个WINCE下驱动项目外包: 1、S3C2416下驱动16C554多串口芯片的驱动程序 2、S3C2416的声音驱动(芯片的驱动代码有2442平台下的可以做参考) 有意者请加QQ嵌入式外包群:48348107 谢谢各位!…

查看全部问答>

WINCE的补丁文件哪里有下载啊

WINCE的补丁文件哪里有下载啊…

查看全部问答>

串口传输的奇怪问题

Hi all 由于使用芯片的升级,公司使用的vxworks(5.4)的BSP包也随之升级,使用的是tornado2.02 现在目标板的bootrom烧进去,可以正常启动 可是不知道为什么,下载vxworks的映像文件的时候常常出错,提示 rpccore target server can\'t decode arg ...…

查看全部问答>

看到许多朋友抱怨LPC17xx的资料难找,发一套全套示例代码

这是一套基于LPC17XX各个模块的示例代码,开发环境是基于KEIL MDK的,我现在用LPC1756做开发,也是初次接触。 这套资料还比较齐全,给了我不少帮助,希望对你们有用。…

查看全部问答>

2011年竞赛题目分析

本帖最后由 paulhyde 于 2014-9-15 04:02 编辑 2011年的国赛题目已经出来了。我大致看了一下,今年的题目大致可以分为四类,比以前分的类要少。下面大致说一下个人的理解。 今年的题目大致可分为四类:电源类、控制类、放大类、仪器仪表类。其中 ...…

查看全部问答>

求个cc2530套件下载地址

求个cc2530套件下载地址,本人装了一个但说应用程序初始化(0xc0000135)失败,不知道怎么解决??求大侠指点,3q…

查看全部问答>

第二季铁电开发板名单出了吗?

如题,第二季的铁电名单怎么还没出啊? 我是第一期的,还在礼品还未收到,也不知是什么? 这效率是不是该提高点了。…

查看全部问答>