#申请原创#
该播放器是由MDM_2802屏、MP3模块、触摸按键、喇叭及开发板所构成,见图1所示。 通过触摸按键可循环以轮回的方式来选择播放歌曲,并通过串口来控制MP3模块来播放指定的歌曲。
图1 硬件构成
1. MDM_2802屏 MDM_2802屏是一款SPI接口的显示屏,其分辨率为320*240像素点,其几何尺寸为2.8寸。相对于一般的显示屏,它更节省引脚,例如它无需DC控制引脚。此外,它在不接背光引脚的情况下也可正常地显示。 为此除电源引脚外,它只需占用4个I/O口就能工作,它与开发板的连接关系为: LCD_CLK --- P43 LCD_SDA--- P45 LCD_REST--- P44 LCD_CS --- P53
图2 MDM_2802屏接口
在MDM_2802显示屏的驱动上是以I/O口来模拟SPI发送字节数据,其函数内容如下: void send_byte(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
LCD_CLK=0;
if(dat&0x80)
LCD_SDA=1;
else
LCD_SDA=0;
Delay_us(8);
dat<<=1;
LCD_CLK=1;
Delay_us(8);
}
}
该显示屏的核心控制芯片为ili9341,其初始化函数为: void ili9341_init(void)
{
LCD_REST=0;
Delay(20);
LCD_REST=1;
Delay(20);
LCD_CS=0;
write_register(0xCF);
write_data(0x00);
write_data(0xC1);
write_data(0X30);
write_register(0xED);
write_data(0x64);
write_data(0x03);
write_data(0X12);
write_data(0X81);
write_register(0xE8);
write_data(0x85);
write_data(0x10);
write_data(0x7A);
write_register(0xCB);
write_data(0x39);
write_data(0x2C);
write_data(0x00);
write_data(0x34);
write_data(0x02);
write_register(0xF7);
write_data(0x20);
write_register(0xEA);
write_data(0x00);
write_data(0x00);
write_register(0xC0);
write_data(0x1B);
write_register(0xC1);
write_data(0x01);
write_register(0xC5);
write_data(0x30);
write_data(0x30);
write_register(0xC7);
write_data(0XB7);
write_register(0x36);
write_data(0x08);
write_register(0x3A);
write_data(0x55);
write_register(0xB1);
write_data(0x00);
write_data(0x1A);
write_register(0xB6);
write_data(0x0A);
write_data(0xA2);
write_register(0xF2);
write_data(0x00);
write_register(0x26);
write_data(0x01);
write_register(0xE0);
write_data(0x0F);
write_data(0x2A);
write_data(0x28);
write_data(0x08);
write_data(0x0E);
write_data(0x08);
write_data(0x54);
write_data(0XA9);
write_data(0x43);
write_data(0x0A);
write_data(0x0F);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_register(0XE1);
write_data(0x00);
write_data(0x15);
write_data(0x17);
write_data(0x07);
write_data(0x11);
write_data(0x06);
write_data(0x2B);
write_data(0x56);
write_data(0x3C);
write_data(0x05);
write_data(0x10);
write_data(0x0F);
write_data(0x3F);
write_data(0x3F);
write_data(0x0F);
write_register(0x2B);
write_data(0x00);
write_data(0x00);
write_data(0x01);
write_data(0x3f);
write_register(0x2A);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0xef);
write_register(0x11);
lcdc_delay(1000);
write_register(0x29);
ili9341_clear(BLACK);
}
该显示屏的色彩清屏函数为:
void ili9341_clear(int c)
{
unsigned int i,j;
set_cursor(0x00, 0x0000);
gram_prepare();
for(i = 0; i < 320; i++)
{
for(j = 0; j < 240; j++)
{
write_data(c >> 8);
write_data(c);
}
}
}
为了修饰画面,还配置直线绘制函数,其内容为:
void LCD_DrawLine(int fcolor,uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
uint16_t t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1;
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1;
else if(delta_x==0)incx=0;
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x;
else distance=delta_y;
for(t=0;t<=distance+1;t++ )
{
ili9341_draw_pixel(fcolor,uRow, uCol);
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
此外,在字符显示函数的基础上还配置了字符串显示函数,其内容为:
void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
{
while(*p!='\0')
{
if(x>LCD_W-16){x=0;y+=16;}
if(y>LCD_H-16){y=x=0;}
GUI_DispCharv(*p, x,y);
x=x+8;
p++;
}
}
为显示中文歌单,在构建中文字库的基础上,所配置的中文显示函数为:
void showhanzi16(unsigned int x,unsigned int y,unsigned char index, int fcolor, int bcolor)
{
unsigned char i,j,k;
unsigned char *temp=hanzi16;
temp+=index*32;
for(j=0;j<16;j++)
{
for(k=0;k<2;k++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
ili9341_draw_pixel(fcolor, x+i+k*8, y+j);
}
else
{
ili9341_draw_pixel(bcolor, x+i+k*8, y+j);
}
}
temp++;
}
}
}
在以上函数的配合下,所实现的显示界面如图3所示。
图3 显示界面
2. 按键控制与LED指示
为了能轻松地进行播放内容的选取,这里选择的是独立的触摸按键,其连接的引脚则是触摸功能板上触摸键所用的引脚P35。为了则是触摸键的操作结果,是用开发板上的LED来进行指示,其电路如图4所示。当触摸按键时,LED灯会被点亮;释放后,就会熄灭。 图4 按键与LED电路
3. 串行通讯与MP3控制
MP3播放模块是一款可通过串行通讯进行控制的器件,其通讯波特率为9600 bps。为了控制MP3模块,这里所使用的UART1。
UART1的初始化函数为: void SC_USCI1_Init(void)
{
GPIO_Init(GPIO1, GPIO_PIN_1,GPIO_MODE_IN_PU);
GPIO_Init(GPIO1, GPIO_PIN_3,GPIO_MODE_IN_PU);
USCI1_ITConfig(DISABLE,LOW);
USCI1_UART_Init(32000000,9600,USCI1_UART_Mode_10B,USCI1_UART_RX_ENABLE);
}
以串口测试指令发送的结果如图5所示。 图5 串口测试
实现整个显示与播放控制功能的主程序为: void main(void)
{
USCI1_HandleInfoDef USCI1_HandleInfo;
int i,h;
Delay(50);
P0CON = 0xFF;
P0PH = 0x00;
P1CON = 0x00;
P1PH = 0x00;
P2CON = 0xFF;
P2PH = 0x00;
P3CON = 0x00;
P3PH = 0xFF;
P4CON = 0xFF;
P4PH = 0x01;
P5CON = 0xFF;
P5PH = 0x00;
GPIO_Init(GPIO0, GPIO_PIN_1 |GPIO_PIN_6, GPIO_MODE_OUT_PP);
GPIO_Init(GPIO2, GPIO_PIN_2, GPIO_MODE_OUT_PP);
GPIO_Init(GPIO5, GPIO_PIN_3, GPIO_MODE_OUT_PP);
GPIO_Init(GPIO4, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_MODE_OUT_PP);
GPIO_Init(GPIO1, GPIO_PIN_5, GPIO_MODE_IN_PU);
Delay(100);
ili9341_init();
ili9341_clear(RED);
LCD_DrawLine(WHITE ,0, 5, 239, 5);
LCD_DrawLine(WHITE ,0, 55, 239, 55);
LCD_DrawLine(WHITE,0, 296, 239, 296);
showimage();
BACK_COLOR=RED;
POINT_COLOR=YELLOW;
LCD_ShowString(60,300,"BY: jinglixixi");
Delay(1000);
BACK_COLOR=RED;
POINT_COLOR=WHITE;
GUI_DispCharv('M',80,20);
GUI_DispCharv('P',90,20);
GUI_DispCharv('3',100,20);
showhanzi16(115,16,32,YELLOW,RED);
showhanzi16(135,16,33,YELLOW,RED);
showhanzi16(155,16,34,YELLOW,RED);
showhanzi16(175,16,35,YELLOW,RED);
showhanzi16(195,16,36,YELLOW,RED);
BACK_COLOR=RED;
POINT_COLOR=YELLOW;
showhanzi16(60,75,0,YELLOW,RED);
showhanzi16(80,75,1,YELLOW,RED);
showhanzi16(100,75,2,YELLOW,RED);
showhanzi16(30,75,37,YELLOW,RED);
showhanzi16(60,105,3,YELLOW,RED);
showhanzi16(80,105,4,YELLOW,RED);
showhanzi16(100,105,5,YELLOW,RED);
showhanzi16(120,105,6,YELLOW,RED);
showhanzi16(60,135,7,YELLOW,RED);
showhanzi16(80,135,8,YELLOW,RED);
showhanzi16(60,165,9,YELLOW,RED);
showhanzi16(80,165,10,YELLOW,RED);
showhanzi16(60,195,11,YELLOW,RED);
showhanzi16(80,195,12,YELLOW,RED);
showhanzi16(100,195,13,YELLOW,RED);
showhanzi16(120,195,14,YELLOW,RED);
showhanzi16(60,225,15,YELLOW,RED);
showhanzi16(80,225,16,YELLOW,RED);
showhanzi16(100,225,17,YELLOW,RED);
showhanzi16(120,225,18,YELLOW,RED);
showhanzi16(140,225,19,YELLOW,RED);
showhanzi16(60,255,20,YELLOW,RED);
showhanzi16(80,255,21,YELLOW,RED);
showhanzi16(100,255,22,YELLOW,RED);
showhanzi16(120,255,23,YELLOW,RED);
showhanzi16(140,255,24,YELLOW,RED);
showhanzi16(160,255,25,YELLOW,RED);
showhanzi16(180,255,26,YELLOW,RED);
h=75;
i=0;
SC_USCI1_Init();
setVolume(10);
USCI1_HandleInfo.TxState = USCI1_STATE_READY;
USCI1_UART_Transmit(&USCI1_HandleInfo, cmd6, 10, 0xFFFF);
while(1)
{
if(KEY==1)
{
LED=1;
if(i<6)
{
i++;
showhanzi16(30,h,37,RED,RED);
h=h+30;
showhanzi16(30,h,37,YELLOW,RED);
playn(i);
USCI1_HandleInfo.TxState = USCI1_STATE_READY;
USCI1_UART_Transmit(&USCI1_HandleInfo, cmd3, 10, 0xFFFF);
}
else
{
showhanzi16(30,h,37,RED,RED);
h=75;
i=0;
showhanzi16(30,h,37,YELLOW,RED);
playn(i);
USCI1_HandleInfo.TxState = USCI1_STATE_READY;
USCI1_UART_Transmit(&USCI1_HandleInfo, cmd3, 10, 0xFFFF);
}
}
else
{
LED=0;
}
Delay(200);
}
}
后续将尝试以触摸板来控制MP3的播放操作,那样将会更加方便和具有特色!
演示视频:https://www.bilibili.com/video/BV1RW4y1s7d8/?vd_source=f302fc0cc3a0425328db53a3b92082ca
|