硬件部分 一块ESP32开发板、一块TFT显示屏(驱动ILI9341、不用触摸、尺寸自选,用的是240*320,2.8寸)、Micro SD卡读取模块、micro SD卡(我测试的时候2G的挂载成功但是无法读取,最后用的128M的)、PAJ7620手势传感器。
SP32模块作为主控,实现天气信息获取以及将SD卡内图片推送到TFT屏幕上。在连线时,需要注意一点:因为TFT屏幕与SD卡共用一套SPI,所以他们的一些引脚是接在一起的,只需要控制片选引脚即可,PAJ7620使用的是IIC总线(PAJ7620未在图中绘出),在源码里我注释了接线的引脚。 软件流程 流程根据功能化为4个部分,心知天气API获取,网页图片上传、手势传感器切花,FTF显示,每个部分的相关操作如下图:
硬件部分与软件流程图:
部分代码
- #include "JpegDecoder.h"
- #include <math.h>
- #include <stdlib.h>
- using namespace std;
- //---------------------------------------------------------------------------
- void JpegDecoder::DecoderTable()
- {
- int val = 0; // type of table ( DC(0,1) or AC(0,1) )
- uint8_t buf[16];
- fread(&val, 1, 1, fp); // get type of table
- fread(buf, 1, 16, fp); // get key value
- map<string, uint8_t> &tb = huffman[val];
- string keyStr = "";
- for (int i = 0; i < 16; i++) // length of key (i.e. i = 2 means key = 000 , 001 , 010 , 011 or ...)
- {
- int cnt = buf[i]; // number of key, which length is (i+1)
- /* alignment */
- for (int k = keyStr.length(); k <= i; k++)
- {
- keyStr += "0";
- }
- while (cnt > 0)
- {
- /* value of key */
- fread(&val, 1, 1, fp); // read value
- //printf("%s = %X\n", keyStr.c_str(), val);
- tb.insert(pair<string, uint8_t>(keyStr, val));
- /* increment */
- int carry = 1; //??λ
- for (int k = keyStr.length() - 1; k >= 0; k--)
- {
- int tmpVal = (keyStr[k] + carry - '0'); //?????λ
- carry = tmpVal / 2;
- keyStr[k] = tmpVal % 2 + '0'; //??????λ???
- }
- cnt = cnt - 1;
- }
- }
- }
- //-------------------------------------------------------------------------------
- Mtx JpegDecoder::InveseSample(Mtx& block, int number)
- {
- Mtx ret;
- int x = (number / 2) * 4;
- int y = (number % 2) * 4;
- for (int i = 0; i < 8; i += 2)
- {
- for (int j = 0; j < 8; j += 2)
- {
- ret[i][j] = ret[i][j + 1] = ret[i + 1][j] = ret[i + 1][j + 1] = block[x + i / 2][y + j / 2];
- }
- }
- return ret;
- }
- /* @brief ????????? YCbCr -> RGB
- */
- void JpegDecoder::ConvertClrSpace(Mtx &Y, Mtx &Cb, Mtx &Cr, Pixel out[8][8])
- {
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 8; j++)
- {
- out[i][j].R = Y[i][j] + 1.402 * Cr[i][j] + 128;
- out[i][j].G = Y[i][j] - 0.34414 * Cb[i][j] - 0.71414 * Cr[i][j] + 128;
- out[i][j].B = Y[i][j] + 1.772 * Cb[i][j] + 128;
- /* ??? */
- if (out[i][j].R > 255) out[i][j].R = 255;
- if (out[i][j].G > 255) out[i][j].G = 255;
- if (out[i][j].B > 255) out[i][j].B = 255;
- /* ??? */
- if (out[i][j].R < 0) out[i][j].R = 0;
- if (out[i][j].G < 0) out[i][j].G = 0;
- if (out[i][j].B < 0) out[i][j].B = 0;
- }
- }
- }
- /* @brief ???? ConvertClrSpace(), ?? MCU ?е? YCbCr ??????? RGB ???
- */
- void JpegDecoder::Convert()
- {
- Mtx cb;
- Mtx cr;
- Pixel out[8][8];
- cb = InveseSample(mcu.cbMtx, 0);
- cr = InveseSample(mcu.crMtx, 0);
- ConvertClrSpace(mcu.yMtx[0], cb, cr, out);
- WriteToRGBBuffer(out, 0);
- cb = InveseSample(mcu.cbMtx, 1);
- cr = InveseSample(mcu.crMtx, 1);
- ConvertClrSpace(mcu.yMtx[1], cb, cr, out);
- WriteToRGBBuffer(out, 1);
- cb = InveseSample(mcu.cbMtx, 2);
- cr = InveseSample(mcu.crMtx, 2);
- ConvertClrSpace(mcu.yMtx[2], cb, cr, out);
- WriteToRGBBuffer(out, 2);
- //for (int i = 0; i < 8; i++)
- //{
- // for (int j = 0; j < 8; j++)
- // {
- // cr[i][j] = mcu.crMtx[4 + i % 4][4 + j % 4];
- // cb[i][j] = mcu.cbMtx[4 + i % 4][4 + i % 4];
- // }
- //}
- cb = InveseSample(mcu.cbMtx, 3);
- cr = InveseSample(mcu.crMtx, 3);
- ConvertClrSpace(mcu.yMtx[3], cb, cr, out);
- WriteToRGBBuffer(out, 3);
- }
- /* @brief ??????????RGB????д??RGB????????
- @buf: ????????
- @blockIndex: ?????? ????Χ: 00, 01, 10, 11 (??????) -> 0??1??2??3 (?????)
- */
- void JpegDecoder::WriteToRGBBuffer(Pixel buf[8][8], int blockIndex)
- {
- int xOffset = 8 * (blockIndex & 0x02) >> 1; // binary: blockIndex & 10 (i.e. if blockIndex = 01 => blockIndex & 0x02 == 01 & 10 => xOffset = 0 * 8 = 0 )
- int yOffset = 8 * (blockIndex & 0x01); // binary: blockIndex & 01 (i.e. if blockIndex = 01 => blockIndex & 0x01 == 01 & 01 => yOffset = 1 * 8 = 8 )
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 8; j++)
- {
- rgbBuf[xOffset + i][yOffset + j].R = buf[i][j].R;
- rgbBuf[xOffset + i][yOffset + j].G = buf[i][j].G;
- rgbBuf[xOffset + i][yOffset + j].B = buf[i][j].B;
- }
- }
- }
- //-------------------------------------------------------------------------------
- /* @brief ??????? MCU
- */
- void JpegDecoder::DecoderNextMCU()
- {
- /* Y ?????? ??? 0??? */
- DecoderMtx(mcu.yMtx[0], 0, quantY, dcY);
- DecoderMtx(mcu.yMtx[1], 0, quantY, dcY);
- DecoderMtx(mcu.yMtx[2], 0, quantY, dcY);
- DecoderMtx(mcu.yMtx[3], 0, quantY, dcY);
- /* Cb, Cr ?????? ??? 1??? */
- DecoderMtx(mcu.cbMtx, 1, quantC, dcCr);
- DecoderMtx(mcu.crMtx, 1, quantC, dcCb);
- }
- //--------------------------------------------------------------------
- /* @brief ??????? 8 x 8 ??????
- */
- void JpegDecoder::DecoderMtx(Mtx &block, int table, uint8_t *quant, int &dc)
- {
- if (endOfDecoder) return; // ???????
- // reset matrix
- for (int i = 0; i < 64; i++) block[i / 8][i % 8] = 0x0;
- // decoder DC of matrix
- int length = FindKeyValue(table);
- int value = GetRealValue(length);
- dc += value; // DC
- block[0][0] = dc;
- // decoder AC of matrix, table = table + 16 => table = 0x00 (DC-0)-> table = 0x10 (AC-0)
- for (int i = 1; i < 64; i++)
- {
- length = FindKeyValue(table + 16);
- if (length == 0x0) break; // ????????
- value = GetRealValue(length & 0xf); // ??? 4λ??????????
- i += (length >> 4); // ??? 4λ???г????
- block[i / 8][i % 8] = value; // AC
- }
- // ??????
- for (int i = 0; i < 64; i++) block[i / 8][i % 8] *= quant[i];
- // ?? Zig-Zag ????
- UnZigZag(block);
- // ?????????任
- IDCT(block);
- }
- /* @brief ?????????????????????Ч?
- */
- int JpegDecoder::FindKeyValue(int table)
- {
- map<string, uint8_t> &huf = huffman[table];
- string keyStr = "";
- while (huf.find(keyStr) == huf.end())
- {
- //printf("%s\n", keyStr.c_str());
- keyStr += (NextBit() + '0'); // char of 0 or 1
- }
- //printf("%s = %d\n", keyStr.c_str(), huf[keyStr]);
- return huf[keyStr];
- }
- /* ????????????????????? */
- int JpegDecoder::GetRealValue(int length)
- {
- int retVal = 0;
- for (int i = 0; i < length; i++)
- {
- retVal = (retVal << 1) + NextBit();
- }
- return (retVal >= pow(2, length - 1) ? retVal : retVal - pow(2, length) + 1);
- }
- //---------------------------------------------------------------------
- /* @brief ????
- */
- BitmapImage &JpegDecoder::Decoder()
- {
- /* decoder quant table */
- DecoderQuant();
- /* decoder width and height of image */
- DecoderSize();
- /* decoder huffman table of DC and AC */
- DecoderHuffman();
- /* decoder data */
- ToStartOfData();
- /* decoder MCU */
- int totalBlock = xNumberOfBlock * yNumberOfBlock;
- while (!endOfDecoder && (idxOfBlock < totalBlock))
- {
- DecoderNextMCU();
- Convert();
- WirteBlock(rgbBuf);
- }
- /* end of decoder */
- return img;
- }
复制代码 |