ARM技术论坛
直播中

王超

7年用户 1318经验值
私信 关注
[经验]

基于SPI液晶屏与MM32F5270开发板制作一个音乐播放器

一、前言

在上周,收到了MM32F5270开发板,多余的介绍就不说了(官网比较详细)。板子上集成了音频功放,可用IIS驱动音频芯片或者直接使用单片机的DAC输出音频,有SD卡可以存储数据,正好家里又有2.8寸的液晶屏,那就组合一下做个音乐播放器吧。

二、硬件接口

2.8寸屏幕: 使用SPI1驱动(不使用PA4和PA5引脚,可复用为其它引脚)

电阻触摸: 使用软件模拟SPI驱动

音频: 使用芯片内置DAC驱动,因为通用性强(不考虑音质)。

SD卡: 使用SPI3驱动(开发板连接好)

三、屏幕驱动

屏幕使用SPI1进行驱动,关于这一部分可以参考官方给的例程,这里只贴出SPI部分,关于屏幕其他部分都是一样的,此处省略。

void bsp_spi1_config(void)

{

SPI_Master_Init_Type    SPI_InitStructure;

GPIO_Init_Type          GPIO_InitStructure;



RCC_EnableAHB1Periphs(BSP_SPI1_GPIO_RCU, true);

RCC_EnableAPB2Periphs(BSP_SPI1_RCU, true);

#if USB_SPI1_CS

/* CS */

 GPIO_InitStructure.Pins = BSP_SPI1_CS_PIN;

GPIO_InitStructure.Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.PinMode = GPIO_PinMode_Out_PushPull;

GPIO_Init(BSP_SPI1_CS_PORT, &GPIO_InitStructure);

GPIO_PinAFConf(BSP_SPI1_CS_PORT, BSP_SPI1_CS_PIN, GPIO_AF_5);

#endif

/* SCK */

GPIO_InitStructure.Pins = BSP_SPI1_SCK_PIN;

GPIO_InitStructure.Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.PinMode = GPIO_PinMode_AF_PushPull;

GPIO_Init(BSP_SPI1_SCK_PORT, &GPIO_InitStructure);

GPIO_PinAFConf(BSP_SPI1_SCK_PORT, BSP_SPI1_SCK_PIN, GPIO_AF_5);

#if USB_SPI1_READ

/* MISO */

GPIO_InitStructure.Pins = BSP_SPI1_MISO_PIN;

GPIO_InitStructure.PinMode  = GPIO_PinMode_In_Floating;

GPIO_Init(BSP_SPI1_MISO_PORT, &GPIO_InitStructure);

GPIO_PinAFConf(BSP_SPI1_MISO_PORT, BSP_SPI1_MISO_PIN, GPIO_AF_5);

#endif

/* MOSI */

GPIO_InitStructure.Pins = BSP_SPI1_MOSI_PIN;

GPIO_InitStructure.PinMode = GPIO_PinMode_AF_PushPull;

GPIO_Init(BSP_SPI1_MOSI_PORT, &GPIO_InitStructure);

GPIO_PinAFConf(BSP_SPI1_MOSI_PORT, BSP_SPI1_MOSI_PIN, GPIO_AF_5);



/* Setup SPI Master. */

SPI_InitStructure.ClockFreqHz = CLOCK_APB2_FREQ;

SPI_InitStructure.BaudRate = 40000000u;  /* 40Mhz. */

SPI_InitStructure.XferMode = SPI_XferMode_TxRx;

SPI_InitStructure.PolPha = SPI_PolPha_Alt2;  // CPOL = 1, CPHA = 1,

SPI_InitStructure.DataWidth = SPI_DataWidth_8b;

SPI_InitStructure.LSB = false;

SPI_InitStructure.AutoCS = false;  /* if set false, need SPI_EnableCS after spi enable. */

SPI_InitMaster(USB_SPI1, &SPI_InitStructure);



/* Enable SPI Master. */

SPI_Enable(USB_SPI1, true);

}

发送和接收数据部分:

uint8_t spi1_send_byte(uint8_t byte)

{

/* Tx. */

while ( SPI_STATUS_TX_FULL & SPI_GetStatus(USB_SPI1) )

{}

SPI_PutData(USB_SPI1, byte);



/* Rx. */

while (0u == (SPI_STATUS_RX_DONE & SPI_GetStatus(USB_SPI1)) )

{}



return SPI_GetData(USB_SPI1);

}

完成上面两部分之后,SPI就初始化好了。

四、触摸驱动

这里也是使用SPI驱动,大家可以使用硬件SPI,这里我就省事就直接用软件的了。

void bsp_software_spi_config(void)

{

GPIO_Init_Type GPIO_InitStructure;



RCC_EnableAHB1Periphs(BSP_SOFTWARE_SPI_SCK_RCU|BSP_SOFTWARE_SPI_MOSI_RCU, true);

#if USB_SOFTWARE_SPI_READ

RCC_EnableAHB1Periphs(BSP_SOFTWARE_SPI_MISO_RCU, true);

#endif

/* SCK */

GPIO_InitStructure.Pins = BSP_SOFTWARE_SPI_SCK_PIN;

GPIO_InitStructure.Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.PinMode = GPIO_PinMode_Out_PushPull;

GPIO_Init(BSP_SOFTWARE_SPI_SCK_PORT, &GPIO_InitStructure);

#if USB_SOFTWARE_SPI_READ

/* MISO */

GPIO_InitStructure.Pins = BSP_SOFTWARE_SPI_MISO_PIN;

GPIO_InitStructure.Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.PinMode = GPIO_PinMode_In_PullUp; // 输入上拉

GPIO_Init(BSP_SOFTWARE_SPI_MISO_PORT, &GPIO_InitStructure);

#endif

/* MOSI */

GPIO_InitStructure.Pins = BSP_SOFTWARE_SPI_MOSI_PIN;

GPIO_InitStructure.Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.PinMode = GPIO_PinMode_Out_PushPull;

GPIO_Init(BSP_SOFTWARE_SPI_MOSI_PORT, &GPIO_InitStructure);

}

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

@功能:软件SPI写入一个字节

@日期:2022-08-14 09:03

@作者:lengyuefeng

@说明:

@参数: 无

@返回值: 无

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

static void software_spi_write_byte(uint8_t byte)

{

uint8_t i = 0;   

for(i = 0; i < 8; i++)  

{       

    if(byte&0x80)

        BSP_SOFTWARE_SPI_MOSI_WRITE(1); 

    else 

        BSP_SOFTWARE_SPI_MOSI_WRITE(0);   

    byte <<= 1;    

    BSP_SOFTWARE_SPI_SCK_WRITE(0);     

    BSP_SOFTWARE_SPI_SCK_WRITE(1);        //上升沿有效            

}

}

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

@功能:软件SPI写入一个字节

@日期:2022-08-14 09:03

@作者:lengyuefeng

@说明:

@参数: 无

@返回值: 无

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

static uint16_t software_spi_read_byte(void)

{

uint8_t i = 0;   

uint16_t byte = 0;

BSP_SOFTWARE_SPI_SCK_WRITE(0); 

BSP_SOFTWARE_SPI_DELAY_US(6);

BSP_SOFTWARE_SPI_SCK_WRITE(1);        //给1个时钟,清除BUSY                

BSP_SOFTWARE_SPI_SCK_WRITE(0);                  

for(i = 0; i < 12; i++)  

{       

    byte <<= 1;      

    BSP_SOFTWARE_SPI_SCK_WRITE(0);    //下降沿有效                 

    BSP_SOFTWARE_SPI_SCK_WRITE(1);

    if(BSP_SOFTWARE_SPI_MISO_READ())

        byte ++;                  

}

return byte;

}

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

@功能:uint8_t software_spi_send_byte(uint8_t byte)

@日期:2022-08-14 09:03

@作者:lengyuefeng

@说明:

@参数: 无

@返回值: 无

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

uint16_t software_spi_send_byte(uint8_t byte)

{

BSP_SOFTWARE_SPI_SCK_WRITE(0);        //先拉低时钟      

BSP_SOFTWARE_SPI_MOSI_WRITE(0);     //拉低数据线

software_spi_write_byte(byte);

BSP_SOFTWARE_SPI_DELAY_US(1);

return software_spi_read_byte();

}

五、测试

完成屏幕移植和触摸移植之后,可以测试一下功能。这里屏幕就简单显示一下,然后触摸呢,写了一个测试矫正函数。

显示部分:

ScreenGUI_DrawFontGBK32((OLED_W-32*5)/2,30,BLACK,WHITE,"音乐播放器");

ScreenGUI_ShowPicture(30,OLED_H-50-30,50,50,gImage_pic_music);

ScreenGUI_ShowPicture(OLED_W / 2 - 25,OLED_H-50-30,50,50,gImage_pic_video);

ScreenGUI_ShowPicture(OLED_W-30-50,OLED_H-50-30,50,50,gImage_pic_setting);

测试效果:

1.jpg

触摸部分:

用触摸测试函数,首先会在左上角出现字符,点击之后消失,然后出现在右上角,以此类推,会出现在四个角。

测试效果:

1.jpg

2.jpg

六、后续

音乐播放器在开发中,一切从简(没有使用lvgl等图形库,纯贴图),不做太复杂的界面,也没有特别多的功能,只有音乐播放这一个功能。

原作者:卢阿涛

更多回帖

发帖
×
20
完善资料,
赚取积分