- nvs,data,nvs,0x9000,24K,
- phy_init,data,phy,0xf000,4K,
- factory,app,factory,0x10000,3000K,
- hzk,80,50,0x2fe000,300K,
其中0x2fe000是烧录hzk的烧录地址
编译后给出的烧录命令
- C:\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.1.2\components\esptool_py\esptool\esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x1000 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\a2dp-demo.bin
需要修改下,把gb2312.bin也一起烧录,为了方便,可以将下面内容放到一个bat文件中。
- C:\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe C:\Espressif\frameworks\esp-idf-v5.1.2\components\esptool_py\esptool\esptool.py -p COM10 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x1000 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\a2dp-demo.bin 0x2fe000 gb2312_80.bin
COM10酌情修改,gb2312_80.bin放到工程根目录。
4、读取汉字库并在LCD上显示
通过前面操作可以在每次烧录时将汉字库烧录到0x2fe000的起始位置。要读取它需要利用2个函数:
esp_partition_find_first:Find first partition based on one or more parameters。通过类型、子类型、标识获取分区句柄
esp_partition_read:Read data from the partition。从分区上读取指定字节数据
实现函数:
获取分区句柄:
- void getHzkPartition(void)
- {
- hzkPartition= esp_partition_find_first(0x50,0x32,"hzk");
- }
获取字模数据
- void getMatrix(const unsigned short nmCode)
- {
- uint32_t offset;
- unsigned char GBH,GBL;
- unsigned short nm=nmCode;
- GBH=nm>>8;
- GBL=nm;
- if(GBH>=0xb0)
- {
- offset=((GBH-0xa7)*94+GBL-0xa1)*32;
- }else
- {
- offset=((GBH-0xa1)*94+GBL-0xa1)*32;
- }
- esp_partition_read(hzkPartition,offset,MatrixBuff,32);
- }
通过GB2312汉字编码获取在字库中的偏移量,然后通过esp_partition_read读取字模数据。
将字模在LCD上显示函数:
- void GUI_Write16CnCharMatrix(unsigned char x, unsigned char y, char *cn, unsigned short wordColor, unsigned short backColor)
- {
- uint8_t i=0, j,mx,my,wordByte;
- uint16_t zm;
- uint16_t color;
- uint8_t wordNum;
- mx=x;
- my=y;
- while (*cn != '\0')
- {
- if(mx>170){
- mx=x;
- my+=16;
- }
- if(*cn<128){
- wordNum = *cn - 32;
- setXY(mx,my,mx+7, my+15);
- for (wordByte=0; wordByte<16; wordByte++)
- {
- color = Font_Data[wordNum].dat[wordByte];
- for (j=0; j<8; j++)
- {
- if ((color&0x80) == 0x80)
- {
- setPixel(wordColor);
- }
- else
- {
- setPixel(backColor);
- }
- color <<= 1;
- }
- }
- cn++;
- mx +=8;
- }
- else
- {
- setXY(mx, my, mx+15, my+15);
- zm=*cn;
- zm<<=8;
- zm|=*(cn+1);
- getMatrix(zm);
- for(i=0; i<32; i++)
- { //MSK的位数
- color=MatrixBuff[i];
- for(j=0;j<8;j++)
- {
- if((color&0x80)==0x80)
- {
- setPixel(wordColor);
- }
- else
- {
- setPixel(backColor);
- }
- color<<=1;
- }//for(j=0;j<8;j++)结束
- }
- cn += 2;
- mx += 16;
- }
- }
- }
可以显示ASCII和汉字。
六、UTF转GBK的函数
UTF汉字不能直接转换为GBK,需要先将UTF转换为unicode,再将unicode通过查表法转换为GBK。
这部分不用自己实现,网上有现成的。https://gitee.com/zhangkt1995/my-code/tree/master/utf8_gb2312_switch
使用起来很方便
七、实现蓝牙歌词功能
ESP IDF下有一个传统蓝牙接收设备(sink)例程:
esp-idf-v5.1.2\examples\bluetooth\bluedroid\classic_bt\a2dp_sink
可以选择这个做为模板新建一个工程。
将前面四、五、六步的程序加到这个工程中。
打开其中bt_app_av.c,在430行左右,修改
- memset(gb2312Data,' ',sizeof(gb2312Data));
- size_t gb2312DataLen = utf8_to_gb2312((uint8_t *)rc->meta_rsp.attr_text, strlen((char*)rc->meta_rsp.attr_text), (uint8_t *)gb2312Data, sizeof(gb2312Data));
- if((rc->meta_rsp.attr_id==0x01)&&(gb2312DataLen>0)){
- gb2312Data[gb2312DataLen]=' ';
- gb2312Data[128]='\0';
- printf("%s",gb2312Data);
- GUI_Write16CnCharMatrix(10,90,gb2312Data,VGA_WHITE,VGA_RED);
- }
当收到ESP_AVRC_CT_METADATA_RSP_EVT消息后,将收到的AVRCP协议数据显示出来。为什么要在这里添加,如果想深入了解,还是需要参考AVRCP协议相关内容。rc->meta_rsp.attr_id==0x01,标识接收的是歌曲TITLE信息,同时歌词也复用该字段。
通过utf8_to_gb2312将收到的歌词由UTF-8转换为gb2312编码。
通过GUI_Write16CnCharMatrix将歌词显示在LCD上。
八、运行效果
手机打开蓝牙,连接ESP_SPEAKER
打开搜狗音乐,找一首歌播放
这时LCD上歌词会实时显示。