quansirx 发表于 2024-11-19 22:41

【Follow me第二季第3期】基础任务---QSPI、OSPI Flash及DAC测试

本帖最后由 quansirx 于 2024-11-19 23:00 编辑

<p>一、QSPI Flash配置</p>

<p lang="en-US">1.1</p>

<p>使用e2 studio新建MCU自定义工程,MCU型号为R7FA6M5BH3CFC</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>打开开发板原理图文件,找到QSPI Flash的原理图</p>

<p>&nbsp;</p>

<p>在FSP配置界面找到Pins栏,引脚配置与原理图一致,注意引脚组选项为_B only</p>

<p>操作模式为Quad</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>在stacks栏新增qspi flash</p>

<p lang="en-US">&nbsp;</p>

<p> &nbsp;</p>

<p>Qspi flash stack属性设置保持默认</p>

<p>FSP设置完成后点击右上角的Generate Project Content</p>

<p lang="en-US">1.2</p>

<p lang="en-US">&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>在工程目录src下新建bsp文件夹,并新建qspi的两个c/h驱动文件</p>

<p>bsp_qspi_flash.h头文件内容如下</p>

<pre>
<code>#ifndef QSPI_FLASH_BSP_QSPI_FLASH_H_

#define QSPI_FLASH_BSP_QSPI_FLASH_H_

#include "hal_data.h"

#include "r_qspi.h"



#define  FLASH_ID_W25Q32JV      0xEF4016    // W25Q32JV

#define  FLASH_ID_AT25SF321B    0x1F8701    // AT25SF321B



#define SPI_FLASH_PageSize              256

#define SPI_FLASH_PerWritePageSize      256

#define RESET_VALUE                    (0x00)





/*命令定义-开头*******************************/

#define WriteEnable                 0x06

#define WriteDisable                0x04

#define ReadStatusReg               0x05

#define WriteStatusReg              0x01

#define ReadData                    0x03

#define FastReadData                0x0B

#define FastReadDual                0x3B

#define PageProgram                 0x02

#define BlockErase                  0xD8

#define SectorErase                 0x20

#define ChipErase                   0xC7

#define PowerDown                   0xB9

#define ReleasePowerDown            0xAB

#define DeviceID                    0xAB

#define ManufactDeviceID            0x90

#define JedecDeviceID               0x9F



/* WIP(busy)标志,FLASH内部正在写入 */

#define WIP_Flag                    0x01

#define Dummy_Byte                  0xFF

/*命令定义-结尾*******************************/



void QSPI_Flash_Init(void);

uint32_t QSPI_Flash_ReadID(void);

uint32_t QSPI_Flash_ReadDeviceID(void);

void QSPI_Flash_PowerDown(void);

void QSPI_Flash_WakeUp(void);

void QSPI_Flash_WriteEnable(void);

fsp_err_t QSPI_Flash_WaitForWriteEnd(void);



void QSPI_Flash_SectorErase(uint32_t adress);

void QSPI_Flash_PageWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite); //页写入

void QSPI_Flash_BufferWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);

void QSPI_Flash_BufferRead(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);



//static void qspi_d0_byte_write_standard (uint8_t byte);

fsp_err_t R_QSPI_Read(spi_flash_ctrl_t *p_ctrl, uint8_t *p_src, uint8_t *const p_dest, uint32_t byte_count);

#endif /* QSPI_FLASH_BSP_QSPI_FLASH_H_ */</code></pre>

<p>&nbsp;</p>

<p>bsp_qspi_flash.c文件内容如下</p>

<pre>
<code>#include "bsp_qspi_flash.h"



void QSPI_Flash_Init(void)

{

    R_QSPI_Open(&amp;g_qspi0_flash_ctrl, &amp;g_qspi0_flash_cfg);

    R_BSP_SoftwareDelay(10u, BSP_DELAY_UNITS_MILLISECONDS);

}

/**

* @brief  读取FLASH ID

* @param  无

* @retval FLASH ID

*/

uint32_t QSPI_Flash_ReadID(void)

{

   unsigned char data = {};

   uint32_t back;

   data = JedecDeviceID;



   R_QSPI_DirectWrite(&amp;g_qspi0_flash_ctrl, &amp;data, 1, true);     //false: close the spi  true: go go go

   R_QSPI_DirectRead(&amp;g_qspi0_flash_ctrl, &amp;data, 3);



   /*把数据组合起来,作为函数的返回值*/

   back = (data &lt;&lt; 16) | (data &lt;&lt; 8) | (data);



   return back;

}



/**

* @brief  读取FLASH 设备ID

* @param  无

* @retval FLASH ID

*/

uint32_t QSPI_Flash_ReadDeviceID(void)

{

    unsigned char data = {};

    uint32_t back;

    data = DeviceID;

    data = 0xff;

    data = 0xff;

    data = 0xff;

    R_QSPI_DirectWrite(&amp;g_qspi0_flash_ctrl, &amp;data, 4, true);     //false: close the spi  true: go go go

    R_QSPI_DirectRead(&amp;g_qspi0_flash_ctrl, &amp;data, 3);



    /*把数据组合起来,作为函数的返回值*/

    back = (data &lt;&lt; 16) | (data &lt;&lt; 8) | (data);



    return back;

}

/**

* @brief  等待WIP(BUSY)标志被置0,即等待FLASH内部数据写入完毕

* @param  无

*/

fsp_err_t QSPI_Flash_WaitForWriteEnd(void)

{

    spi_flash_status_t status = {.write_in_progress = true};

    int32_t time_out          = (INT32_MAX);

    fsp_err_t err             = FSP_SUCCESS;



    do

    {

        /* Get status from QSPI flash device */

        err = R_QSPI_StatusGet(&amp;g_qspi0_flash_ctrl, &amp;status);

        if (FSP_SUCCESS != err)

        {

            //printf("R_QSPI_StatusGet Failed\r\n");

            return err;

        }



        /* Decrement time out to avoid infinite loop in case of consistent failure */

        --time_out;



        if (RESET_VALUE &gt;= time_out)

        {

            //printf("\r\n ** Timeout : No result from QSPI flash status register ** \r\n");

            return FSP_ERR_TIMEOUT;

        }



    }

    while (false != status.write_in_progress);



    return err;

}

/**

* @brief  擦除FLASH扇区

* @param  SectorAddr:要擦除的扇区地址

* @retval 无

*/

void QSPI_Flash_SectorErase(uint32_t adress)

{

    unsigned char data = {};



    data = 0x06;     //write_enable_command

    data = 0x20;     //erase_command

    data = (uint8_t)(adress &gt;&gt; 16);

    data = (uint8_t)(adress &gt;&gt; 8);

    data = (uint8_t)(adress);

    R_QSPI-&gt;SFMCMD = 1U;

    R_QSPI-&gt;SFMCOM = data;

    R_QSPI_DirectWrite(&amp;g_qspi0_flash_ctrl, &amp;data, 4, false);



    QSPI_Flash_WaitForWriteEnd();

}

/**

 * @brief  对FLASH写入数据,调用本函数写入数据前需要先擦除扇区

 * @param  pBuffer,要写入数据的指针

 * @param  WriteAddr,写入地址

 * @param  NumByteToWrite,写入数据长度

 * @retval 无

 */

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

{

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



    /*mod运算求余,若writeAddr是SPI_FLASH_PageSize整数倍,运算结果Addr值为0*/

    Addr = WriteAddr % SPI_FLASH_PageSize;



    /*差count个数据值,刚好可以对齐到页地址*/

    count = SPI_FLASH_PageSize - Addr;

    /*计算出要写多少整数页*/

    NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;

    /*mod运算求余,计算出剩余不满一页的字节数*/

    NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;



    /* Addr=0,则WriteAddr 刚好按页对齐 aligned  */

    if (Addr == 0)

    {

        /* NumByteToWrite &lt; SPI_FLASH_PageSize */

        if (NumOfPage == 0)

        {

            R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, NumByteToWrite);

            QSPI_Flash_WaitForWriteEnd();



        }

        else /* NumByteToWrite &gt; SPI_FLASH_PageSize */

        {

            /*先把整数页都写了*/

            while (NumOfPage--)

            {

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, SPI_FLASH_PageSize);

                QSPI_Flash_WaitForWriteEnd();



                WriteAddr +=  SPI_FLASH_PageSize;

                pBuffer += SPI_FLASH_PageSize;

            }

            /*若有多余的不满一页的数据,把它写完*/

            R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, NumOfSingle);

            QSPI_Flash_WaitForWriteEnd();



        }

    }

    /* 若地址与 SPI_FLASH_PageSize 不对齐  */

    else

    {

        /* NumByteToWrite &lt; SPI_FLASH_PageSize */

        if (NumOfPage == 0)

        {

            /*当前页剩余的count个位置比NumOfSingle小,一页写不完*/

            if (NumOfSingle &gt; count)

            {

                temp = NumOfSingle - count;

                /*先写满当前页*/

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, count);

                QSPI_Flash_WaitForWriteEnd();





                WriteAddr +=  count;

                pBuffer += count;

                /*再写剩余的数据*/

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, temp);

                QSPI_Flash_WaitForWriteEnd();



            }

            else /*当前页剩余的count个位置能写完NumOfSingle个数据*/

            {

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, NumByteToWrite);

                QSPI_Flash_WaitForWriteEnd();



            }

        }

        else /* NumByteToWrite &gt; SPI_FLASH_PageSize */

        {

            /*地址不对齐多出的count分开处理,不加入这个运算*/

            NumByteToWrite -= count;

            NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;

            NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;



            /* 先写完count个数据,为的是让下一次要写的地址对齐 */

            R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, count);

            QSPI_Flash_WaitForWriteEnd();



            /* 接下来就重复地址对齐的情况 */

            WriteAddr +=  count;

            pBuffer += count;

            /*把整数页都写了*/

            while (NumOfPage--)

            {

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, SPI_FLASH_PageSize);

                QSPI_Flash_WaitForWriteEnd();



                WriteAddr +=  SPI_FLASH_PageSize;

                pBuffer += SPI_FLASH_PageSize;

            }

            /*若有多余的不满一页的数据,把它写完*/

            if (NumOfSingle != 0)

            {

                R_QSPI_Write(&amp;g_qspi0_flash_ctrl, pBuffer, WriteAddr, NumOfSingle);

                QSPI_Flash_WaitForWriteEnd();

            }

        }

    }

}

/**

* @brief  读取FLASH数据,减少ctrl这个标志

* @param  pBuffer,存储读出数据的指针

* @param  ReadAddr,读取地址

* @param  NumByteToRead,读取数据长度

* @retval 无

*/

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

{

    R_QSPI_Read(&amp;g_qspi0_flash_ctrl, pBuffer, ReadAddr, NumByteToRead);

}

/**

* @brief  读取flash数据

* @param  p_ctrl

* @param  p_src     需要传回的数据

* @param  p_dest    数据地址

* @param  byte_count    数据长度

*/



void qspi_d0_byte_write_standard(uint8_t byte)

{

    R_QSPI-&gt;SFMCOM = byte;

}

fsp_err_t R_QSPI_Read(spi_flash_ctrl_t     *p_ctrl,

                      uint8_t              *p_src,

                      uint8_t *const       p_dest,

                      uint32_t              byte_count)

{

    qspi_instance_ctrl_t *p_instance_ctrl = (qspi_instance_ctrl_t *) p_ctrl;





    uint32_t chip_address = (uint32_t) p_dest - (uint32_t) QSPI_DEVICE_START_ADDRESS + R_QSPI-&gt;SFMCNT1;



    bool restore_spi_mode = false;

    void (* write_command)(uint8_t byte) = qspi_d0_byte_write_standard;

    void (* write_address)(uint8_t byte) = qspi_d0_byte_write_standard;



#if QSPI_CFG_SUPPORT_EXTENDED_SPI_MULTI_LINE_PROGRAM



    /* If the peripheral is in extended SPI mode, and the configuration provided in the BSP allows for programming on

     * multiple data lines, and a unique command is provided for the required mode, update the SPI protocol to send

     * data on multiple lines. */

    if ((SPI_FLASH_DATA_LINES_1 != p_instance_ctrl-&gt;data_lines) &amp;&amp;

            (SPI_FLASH_PROTOCOL_EXTENDED_SPI == R_QSPI-&gt;SFMSPC_b.SFMSPI))

    {

        R_QSPI-&gt;SFMSPC_b.SFMSPI = p_instance_ctrl-&gt;data_lines;



        restore_spi_mode = true;



        /* Write command in extended SPI mode on one line. */

        write_command = gp_qspi_prv_byte_write;



        if (SPI_FLASH_DATA_LINES_1 == p_instance_ctrl-&gt;p_cfg-&gt;page_program_address_lines)

        {

            /* Write address in extended SPI mode on one line. */

            write_address = gp_qspi_prv_byte_write;

        }

    }

#endif



    /* Enter Direct Communication mode */

    R_QSPI-&gt;SFMCMD = 1;



    /* Send command to enable writing */

    write_command(0x03);



    /* Write the address. */

    if ((p_instance_ctrl-&gt;p_cfg-&gt;address_bytes &amp; R_QSPI_SFMSAC_SFMAS_Msk) == SPI_FLASH_ADDRESS_BYTES_4)

    {

        /* Send the most significant byte of the address */

        write_address((uint8_t)(chip_address &gt;&gt; 24));

    }



    /* Send the remaining bytes of the address */

    write_address((uint8_t)(chip_address &gt;&gt; 16));

    write_address((uint8_t)(chip_address &gt;&gt; 8));

    write_address((uint8_t)(chip_address));



    /* Write the data. */

    uint32_t index = 0;

    while (index &lt; byte_count)

    {

        /* Read the device memory into the passed in buffer */

        *(p_src + index) = (uint8_t) R_QSPI-&gt;SFMCOM;

        index++;

    }



    /* Close the SPI bus cycle. Reference section 39.10.3 "Generating the SPI Bus Cycle during Direct Communication"

     * in the RA6M3 manual R01UH0886EJ0100. */

    R_QSPI-&gt;SFMCMD = 1;





    /* Return to ROM access mode */

    R_QSPI-&gt;SFMCMD = 0;



    return FSP_SUCCESS;

}</code></pre>

<p>1.3 hal_entry.c代码编写</p>

<p>&nbsp;</p>

<p>hal_entry.c添加内容</p>

<pre>
<code>//add***

uint32_t flag=0;

uint32_t id;

uint32_t id1;



#define  FLASH_WriteAddress     0x00000

#define  FLASH_ReadAddress      FLASH_WriteAddress

#define  FLASH_SectorToErase    FLASH_WriteAddress



/* 发送缓冲区初始化 */

uint8_t Tx_Buffer[] = "Hello Digikey&amp;EEWorld!\n";

uint8_t Rx_Buffer;

int Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)

{

    while (BufferLength--)

    {

        if (*pBuffer1 != *pBuffer2)

        {

            return 1;

        }



        pBuffer1++;

        pBuffer2++;

    }

    return 0;

}

//add***</code></pre>

<p>&nbsp;</p>

<p>hal_entry函数添加如下内容</p>

<pre>
<code>//add***

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

 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function

 * is called by main() when no RTOS is used.

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

void hal_entry(void)

{

    /* TODO: add your own code here */

    //add***

//    uint32_t FlashID = 0;

//    uint32_t FlashDeviceID = 0;

    QSPI_Flash_Init();  // 串行FLASH初始化

//    FlashID = QSPI_Flash_ReadID();

//    FlashDeviceID = QSPI_Flash_ReadDeviceID();



    QSPI_Flash_SectorErase(FLASH_SectorToErase);



    /* 将发送缓冲区的数据写到flash中 */

           // 这里写一页,一页的大小为256个字节

           QSPI_Flash_BufferWrite(Tx_Buffer, FLASH_WriteAddress, sizeof(Tx_Buffer));

           //printf("写入的数据为:%s \r\n", Tx_Buffer);



           /* 将刚刚写入的数据读出来放到接收缓冲区中 */

           QSPI_Flash_BufferRead(Rx_Buffer, FLASH_ReadAddress, sizeof(Tx_Buffer));

           //printf("读出的数据为:%s \r\n", Rx_Buffer);



           if (Buffercmp(Tx_Buffer, Rx_Buffer, sizeof(Tx_Buffer)) == 0)

           {

               flag=1;

               //printf("\r\n32Mbit串行Flash测试成功!\r\n");

               //LED3_ON;





           }

           else

           {

               flag=0;

               //printf("\r\n32Mbit串行Flash测试失败!\r\n");

               //LED1_ON;

           }

    //add***</code></pre>

<p>编译工程后进入调试模式</p>

<p>打开Jlink RTT查看日志输出</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>这里往QSPI Flash的起始地址写入一行字符串,并读出该地址的字符数据,如果写入的数据与读出的数据一致,说明QSPI Flash读写测试成功</p>

<p>二、OSPI配置</p>

<p lang="en-US">2.1</p>

<p>使用e2 studio新建MCU自定义工程</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>打开开发板原理图文件,找到OSPI Flash的原理图</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>在FSP配置界面找到Pins栏,引脚配置与原理图一致,注意引脚组选项为Mixed</p>

<p>操作模式为Custom</p>

<p> &nbsp;</p>

<p>在stacks栏新增ospi flash</p>

<p> &nbsp;</p>

<p>ospi flash stack属性设置保持默认,由于OPSI外设使用独立的OCTASPICLK时钟信号,需要在Clocks配置OSPI的时钟信号,时钟树配置如下</p>

<p> &nbsp;</p>

<p lang="en-US">2.2</p>

<p>在工程目录src下新建bsp文件夹,并新建ospi的两个c/h驱动文件</p>

<p>bsp_ospi_flash.h头文件内容如下</p>

<p lang="en-US"> &nbsp;</p>

<p>&nbsp;</p>

<p>bsp_ospi_flash.h头文件内容如下</p>

<pre>
<code>/*

 * bsp_ospi_flash.h

 *

 *  Created on: 2024年11月17日

 *      Author: quansirx

 */



#ifndef OSPI_FLASH_BSP_OSPI_FLASH_H_

#define OSPI_FLASH_BSP_OSPI_FLASH_H_

#include "hal_data.h"

#include "r_ospi.h"

#define RESET_VALUE             (0x00)

void QSPI_Flash_Init(void);

fsp_err_t ospi_init(void);

#endif /* OSPI_FLASH_BSP_OSPI_FLASH_H_ */</code></pre>

<p>bsp_ospi_flash.c文件内容如下</p>

<pre>
<code>/*

 * bsp_ospi_flash.c

 *

 *  Created on: 2024年11月17日

 *      Author: quansirx

 */

#include "bsp_ospi_flash.h"







void QSPI_Flash_Init(void){



//    bsp_octaclk_settings_t octaclk        = {RESET_VALUE};

//    octaclk.source_clock = BSP_CFG_OCTA_SOURCE;  /* 200MHz */

//    octaclk.divider      = BSP_CLOCKS_OCTA_CLOCK_DIV_2;

//    R_BSP_OctaclkUpdate(&amp;octaclk);//更新OSI 时钟频率

//

//    fsp_err_t          err                =  FSP_SUCCESS;

//    err = ospi_init();



    R_OSPI_Open(&amp;g_ospi_ctrl, &amp;g_ospi_cfg);





}

spi_flash_cfg_t     g_loc_ospi_cfg;

ospi_extended_cfg_t g_loc_ospi_extnd_cfg;

#define DEVICE_SECTOR_SIZE                              (4096U)

#define DEVICE_BLOCK_SIZE                               (65536U)

#define INITIAL_INDEX                                   (0U)

#define OSPI_OPI_CMD_ERASE_SECTOR                       (0x21DEU)

#define OSPI_OPI_CMD_ERASE_BLOCK                        (0xDC23U)

#define OSPI_OPI_CMD_ERASE_CHIP                         (0xC738U)



static const spi_flash_erase_command_t opi_erase_command_list[] =

{

 { .command = OSPI_OPI_CMD_ERASE_SECTOR, .size = DEVICE_SECTOR_SIZE },



 { .command = OSPI_OPI_CMD_ERASE_BLOCK, .size = DEVICE_BLOCK_SIZE },



 { .command = OSPI_OPI_CMD_ERASE_CHIP, .size = SPI_FLASH_ERASE_SIZE_CHIP_ERASE },

};



fsp_err_t ospi_init(void)

{

    fsp_err_t err                = FSP_SUCCESS;



    /*Configuration setup of Extended SPI configuration into local config*/

    ospi_extended_cfg_t* textd = NULL;

    textd = (void *)g_ospi_cfg.p_extend;

    g_loc_ospi_extnd_cfg = *textd;

    g_loc_ospi_cfg =  g_ospi_cfg;

    g_loc_ospi_cfg.p_erase_command_list = &amp;opi_erase_command_list;

    g_loc_ospi_cfg.p_extend = &amp;g_loc_ospi_extnd_cfg;



    /* In the current OSPI device model, the default status of the device is set to SPI mode.

     * Therefore, it is necessary to initialize the OSPI driver module in SPI mode

     * to ensure compatibility with the device's default SPI protocol.

     */

    g_loc_ospi_cfg.spi_protocol = SPI_FLASH_PROTOCOL_EXTENDED_SPI;



    /*Open Octa Flash device in Extended SPI Mode */

    err = R_OSPI_Open(&amp;g_ospi_ctrl, &amp;g_loc_ospi_cfg);

    if (FSP_SUCCESS != err)

    {

        //APP_ERR_PRINT ("\r\n** R_OSPI_Open API FAILED **\r\n");

    }

    return err;

}</code></pre>

<p>三、DAC波形测试</p>

<p>以快速向导工程为模版,驱动DAC产生正弦波波形</p>

<p lang="en-US">3.1</p>

<p>打开quickstart_ek_ra6m5_ep工程下FSP配置文件</p>

<p>在stack栏新增DAC外设</p>

<p> &nbsp;</p>

<p>pins栏配置DAC输出引脚为P014</p>

<p lang="en-US"> &nbsp;</p>

<p>DAC波形产生需要使用定时器,这里使用示例工程中g_gpt_blue这一定时器</p>

<p> &nbsp;</p>

<p>g_gpt_blue定时器已经使能定时器溢出中断,中断回调函数为gpt_blue_callback</p>

<p>使用全局搜索gpt_blue_callback,找到gpt_blue_callback的函数定义</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>gpt_blue_callback定义在common_init.c文件</p>

<p>在gpt_blue_callback添加以下内容</p>

<pre>
<code>#include "math.h"

#define M_PI 3.141592

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

 * Function Name: gpt_blue_callback

 * Description  : Callback function for driver g_gpt_blue.

 * Argument     : p_args

 * Return Value : .

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

void gpt_blue_callback(timer_callback_args_t * p_args)

{

    /* Void the unused params */

    uint16_t dacvalue=0;

    static double w=0.0;

    w+=M_PI/90;

    if(w&gt;=2*M_PI){

        w=0.0;

    }

    dacvalue=4095*(cos(w)+1)/2;

    R_DAC_Write(&amp;g_dac0_ctrl, dacvalue);



    FSP_PARAMETER_NOT_USED(p_args);



    switch (s_blueled_flashing)

    {

        case ON:

        {

            if ((s_intense++ ) &lt; s_duty)

            {

                TURN_BLUE_ON

            }

            else

            {

                TURN_BLUE_OFF

            }



            if (s_intense &gt;= 100)

            {

                s_intense = 0;

                s_duty = g_pwm_dcs;

            }

            break;

        }

        default:

        {

            TURN_BLUE_OFF

            s_intense = 0;

            s_duty = g_pwm_dcs;

        }

    }

}
</code></pre>

<p>&nbsp;</p>

<p>进行程序调试</p>

<p>我这里没有示波器观察DAC波形,使用e2 studio内置的real-time chart观察dacvalue的变化情况</p>

<p>&nbsp;&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>因为real-time chart的刷新速率慢,所以波形会有些失真</p>
页: [1]
查看完整版本: 【Follow me第二季第3期】基础任务---QSPI、OSPI Flash及DAC测试