- /**
- ****************************************************************************************
- *
- * [url=home.php?mod=space&uid=288409]@file[/url] lcd_12864.c
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] lcd_12864 driver.
- *
- * Copyright (C) TChip 2014
- *
- * $Rev: 1.0 $
- *
- ****************************************************************************************
- */
- /**
- ****************************************************************************************
- * @addtogroup SPI
- * @{
- ****************************************************************************************
- */
- /*
- * INCLUDE FILES
- ****************************************************************************************
- */
- #include "fsl_dspi_master_driver.h"
- #include "fsl_spi_master_driver.h"
- #include "fsl_gpio_hal.h"
- #include "fsl_port_hal.h"
- #include "fsl_debug_console.h"
- #include "delay.h"
- #include "oled.h"
- #include "oledfont.h"
- /*
- * MARCO VARIABLE DECLARATION
- ****************************************************************************************
- */
- #define TRANSFER_SIZE (1) /*! Transfer size */
- #define TRANSFER_BAUDRATE (1000000U) /*! Transfer baudrate - 500k */
- #define MASTER_TRANSFER_TIMEOUT (5000U) /*! Transfer timeout of master - 5s */
- /*
- * LOCAL VARIABLE DECLARATION
- ****************************************************************************************
- */
- //check spi status
- volatile uint8_t oled_rx_flag = 0;
- volatile uint8_t oled_tx_flag = 0;
- //uint8_t i;
- uint8_t buffer[32];
- //Init the OLED
- //static uint8_t Init_buffer[] =
- //{
- // 0xAE ,//--turn off oled panel
- // 0x00 ,//---set low column address
- // 0x10 ,//---set high column address
- // 0x40 ,//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- // 0x81 ,//--set contrast control register
- // 0xCF , // Set SEG Output Current Brightness
- // 0xA1 ,//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
- // 0xC8 ,//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
- // 0xA6 ,//--set normal display
- // 0xA8 ,//--set multiplex ratio(1 to 64)
- // 0x3f ,//--1/64 duty
- // 0xD3 ,//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- // 0x00 ,//-not offset
- // 0xd5 ,//--set display clock divide ratio/oscillator frequency
- // 0x80 ,//--set divide ratio, Set Clock as 100 Frames/Sec
- // 0xD9 ,//--set pre-charge period
- // 0xF1 ,//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- // 0xDA ,//--set com pins hardware configuration
- // 0x12 ,
- // 0xDB ,//--set vcomh
- // 0x40 ,//Set VCOM Deselect Level
- // 0x20 ,//-Set Page Addressing Mode (0x00/0x01/0x02)
- // 0x02 ,//
- // 0x8D ,//--set Charge Pump enable/disable
- // 0x14 ,//--set(0x10) disable
- // 0xA4 ,// Disable Entire Display On (0xa4/0xa5)
- // 0xA6 ,// Disable Inverse Display On (0xa6/a7)
- // 0xAF ,//--turn on oled panel
- //
- // 0xAF , /*display ON*/
- //};
- /*
- * GLOBAL VARIABLE DECLARATION
- ****************************************************************************************
- */
- #if (NXP_OLED)
- //void DelayUs(uint32_t us)
- //{
- // for(int i=us*30;i>0;i--)
- // __NOP();
- //}
- //void DelayMs(uint32_t ms)
- //{
- // for(int i=ms;i>0;i--)
- // DelayUs(1000);
- //}
- /**
- ****************************************************************************************
- * [url=home.php?mod=space&uid=247401]@brief[/url] SPI RX CALLBACK FUNCTION.
- * @description
- *
- ****************************************************************************************
- */
- void oled_read_done(void)
- {
- oled_rx_flag = 0;
- }
- /**
- ****************************************************************************************
- * [url=home.php?mod=space&uid=247401]@brief[/url] SPI TX CALLBACK FUNCTION.
- * @description
- *
- ****************************************************************************************
- */
- void oled_write_done(void)
- {
- oled_tx_flag = 0;
- }
- /**
- ****************************************************************************************
- * @brief Configure the SPI GPIO and set RS 、 RST GPIO output,Init them.
- * @description
- *
- ****************************************************************************************
- */
- void oled_io_config(void)
- {
- //Init Gpio with a callback,it's necessary
- //set the LCD_RS_PIN an output
- PORT_HAL_SetMuxMode(PORTB,OLED_DC_PIN,kPortMuxAsGpio);
- GPIO_HAL_SetPinDir(OLED_DC,OLED_DC_PIN,kGpioDigitalOutput);
- GPIO_HAL_ClearPinOutput(OLED_DC,OLED_DC_PIN);
- //set the LCD_RST_PIN an output
- //prevent it reset the lcd
- PORT_HAL_SetMuxMode(PORTC,OLED_RST_PIN,kPortMuxAsGpio);
- GPIO_HAL_SetPinDir(OLED_RST,OLED_RST_PIN,kGpioDigitalOutput);
- GPIO_HAL_SetPinOutput(OLED_RST,OLED_RST_PIN);
- }
- void OLED_Set_Pos(unsigned char x, unsigned char y)
- {
- OLED_WR_Byte(0xb0+y,OLED_CMD);
- OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
- OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);
- }
- //开启OLED显示
- void OLED_Display_On(void)
- {
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
- OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
- OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
- }
- //关闭OLED显示
- void OLED_Display_Off(void)
- {
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
- OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
- OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
- }
- //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
- void OLED_Clear(void)
- {
- uint8_t i,n;
- for(i=0; i<8; i++)
- {
- OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
- OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
- OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
- for(n=0; n<128; n++)
- OLED_WR_Byte(0,OLED_DATA);
- } //更新显示
- }
- void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
- {
- dspi_status_t dspiResult;
- buffer[0] = dat;
- if(cmd)
- OLED_DC_Set();
- else
- OLED_DC_Clr();
- OLED_CS_Clr();
- //spi_write(QN_SPI1, buffer, 1, oled_write_done);
- dspiResult = DSPI_DRV_MasterTransferBlocking(SPI1_IDX,
- NULL,
- buffer,
- NULL,
- 1,
- MASTER_TRANSFER_TIMEOUT);
- if(kStatus_DSPI_Success != dspiResult)
- while(1);
- oled_write_done();
- DelayUs(100);
- OLED_CS_Set();
- OLED_DC_Set();
- }
- //void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
- //{
- // //uint8_t i;
- // uint8_t buffer[1];
- // buffer[0] = dat;
- // if(cmd)
- // OLED_DC_Set();
- // else
- // OLED_DC_Clr();
- // OLED_CS_Clr();
- // spi_write(QN_SPI1, buffer, 1, lcd_write_done);
- // delay(100);
- //
- // OLED_CS_Set();
- // OLED_DC_Set();
- //}
- void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr)
- {
- unsigned char c=0,i=0;
- c=chr-' ';//得到偏移后的值
- if(x>Max_Column-1) {
- x=0;
- y=y+2;
- }
- if(SIZE ==16)
- {
- OLED_Set_Pos(x,y);
- for(i=0; i<8; i++)
- OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
- OLED_Set_Pos(x,y+1);
- for(i=0; i<8; i++)
- OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
- }
- else {
- OLED_Set_Pos(x,y+1);
- for(i=0; i<6; i++)
- OLED_WR_Byte(F6x8[c][i],OLED_DATA);
- }
- }
- //m^n函数
- uint32_t oled_pow(uint8_t m,uint8_t n)
- {
- uint32_t result=1;
- while(n--)result*=m;
- return result;
- }
- //显示2个数字
- //x,y :起点坐标
- //len :数字的位数
- //size:字体大小
- //mode:模式 0,填充模式;1,叠加模式
- //num:数值(0~4294967295);
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size)
- {
- uint8_t t,temp;
- uint8_t enshow=0;
- for(t=0; t<len; t++)
- {
- temp=(num/oled_pow(10,len-t-1))%10;
- if(enshow==0&&t<(len-1))
- {
- if(temp==0)
- {
- OLED_ShowChar(x+(size/2)*t,y,' ');
- continue;
- } else enshow=1;
- }
- OLED_ShowChar(x+(size/2)*t,y,temp+'0');
- }
- }
- //显示一个字符号串
- void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr)
- {
- unsigned char j=0;
- while (chr[j]!='\0')
- { OLED_ShowChar(x,y,chr[j]);
- x+=8;
- if(x>120) {
- x=0;
- y+=2;
- }
- j++;
- }
- }
- //显示汉字
- void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
- {
- uint8_t t,adder=0;
- OLED_Set_Pos(x,y);
- for(t=0; t<16; t++)
- {
- OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
- adder+=1;
- }
- OLED_Set_Pos(x,y+1);
- for(t=0; t<16; t++)
- {
- OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
- adder+=1;
- }
- }
- /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
- void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
- {
- unsigned int j=0;
- unsigned char x,y;
- if(y1%8==0) y=y1/8;
- else y=y1/8+1;
- for(y=y0; y<y1; y++)
- {
- OLED_Set_Pos(x0,y);
- for(x=x0; x<x1; x++)
- {
- OLED_WR_Byte(BMP[j++],OLED_DATA);
- }
- }
- }
- void SPI_Init()
- {
- static uint32_t calculatedBaudRate;
- static dspi_master_state_t masterState;
- static dspi_device_t masterDevice;
- static dspi_master_user_config_t masterUserConfig = {
- .isChipSelectContinuous = false,
- .isSckContinuous = false,
- .pcsPolarity = kDspiPcs_ActiveLow,
- .whichCtar = kDspiCtar0,
- .whichPcs = kDspiPcs0
- };
- dspi_status_t dspiResult;
- // Setup the configuration.
- masterDevice.dataBusConfig.bitsPerFrame = 8;
- masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge;
- masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
- masterDevice.dataBusConfig.direction = kDspiMsbFirst;
- // Initialize master driver.
- dspiResult = DSPI_DRV_MasterInit(SPI1_IDX,
- &masterState,
- &masterUserConfig);
- while(dspiResult != kStatus_DSPI_Success);
- // Configure baudrate.
- masterDevice.bitsPerSec = 32;
- dspiResult = DSPI_DRV_MasterConfigureBus(SPI1_IDX,
- &masterDevice,
- &calculatedBaudRate);
- while(dspiResult != kStatus_DSPI_Success);
- }
- //初始化SSD1306
- void OLED_Init(void)
- {
- oled_io_config();
-
- SPI_Init();
- OLED_RST_Set();
- DelayMs(10);
- OLED_RST_Clr();
- DelayMs(10);
- OLED_RST_Set();
- OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
- OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
- OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
- OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
- OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
- OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
- OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
- OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
- OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- OLED_WR_Byte(0x00,OLED_CMD);//-not offset
- OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
- OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
- OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
- OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
- OLED_WR_Byte(0x12,OLED_CMD);
- OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
- OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
- OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
- OLED_WR_Byte(0x02,OLED_CMD);//
- OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
- OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
- OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
- OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
- OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
- OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
- OLED_Clear();
- OLED_Set_Pos(0,0);
- }
- #endif
- ///end
5、主程序代码
- /*
- * Copyright (c) 2016, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or
- * other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * [File Name] main.c
- * [Platform] FRDM-K22F
- * [Project] K22F_PM25
- * [Version] 1.00
- * [Author] Goth
- * [Date] 01/19/2016
- * [Language] 'C'
- * [History] 1.00 - Original Release
- *
- */
- //-----------------------------------------------------------------------
- // Standard C/C++ Includes
- //-----------------------------------------------------------------------
- #include <stdio.h>
- #include <math.h>
- //-----------------------------------------------------------------------
- // KSDK Includes
- //-----------------------------------------------------------------------
- #include "main.h"
- //-----------------------------------------------------------------------
- // Application Includes
- //-----------------------------------------------------------------------
- #include "oled.h"
- #include "dht11.h"
- #include "gp2y.h"
- #include "ch2o.h"
- #include "delay.h"
- //-----------------------------------------------------------------------
- // Function Prototypes
- //-----------------------------------------------------------------------
- void ReadCH2O(void);
- void ReadDHT11(void);
- void ReadGP2Y(void);
- //-----------------------------------------------------------------------
- // Constants
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- // Typedefs
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- // Global Variables
- //-----------------------------------------------------------------------
- extern char **[];
- //-----------------------------------------------------------------------
- // Macros
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- // Main Function
- //-----------------------------------------------------------------------
- int main(void)
- {
- // Configure board specific pin muxing
- hardware_init();
- OSA_Init();
- // Initialize UART terminal
- dbg_uart_init();
-
- DelayInit();
-
- DHT11_Init();
- CH2O_Init();
- GP2Y_init();
- OLED_Init();
- OLED_Clear();
- PRINTF("\r\nRunning the K22F_PM25 project.\r\n");
- //Show **
- OLED_DrawBMP(0,0,128,8,(unsigned char*)**);
- DelayMs(1000);
- OLED_Clear();
- for (;;) // Forever loop
- {
- ReadCH2O();
- ReadDHT11();
- ReadGP2Y();
- DelayUs(1000);
- }
- }
- void ReadCH2O(void)
- {
- uint8_t receiveBuffer[32];
- uint8_t rx;
-
- rx = 0x00;
- for(int i=0;i<9;i++)
- receiveBuffer[i] = 0;
- // Call received API
- UART_DRV_ReceiveData(UART2_IDX, &rx, 1u);
- // Wait until we receive a character
- while (kStatus_UART_RxBusy == UART_DRV_GetReceiveStatus(UART2_IDX, NULL));
- if(rx == 0xFF)
- {
- receiveBuffer[0] = rx;
- for(int i=1;i<9;i++)
- {
- // Call received API
- UART_DRV_ReceiveData(UART2_IDX, &rx, 1u);
- // Wait until we receive a character
- while (kStatus_UART_RxBusy == UART_DRV_GetReceiveStatus(UART2_IDX, NULL));
- receiveBuffer[i] = rx;
- }
- }
- /*国家标准室内0.08mg/m3 = 833 * 0.08 = 66.64 ppb。*/
- int pm25Value = receiveBuffer[4]*256 + receiveBuffer[5];
- float result = pm25Value / 66.64 * 0.08;
- /*
- int v1 = (int)result;
- int v2 = (int)((result - v1)*1000);
- PRINTF("CH2O: %d.%03d(mg/m3)\r\n",v1,v2);
- */
- sprintf((char*)receiveBuffer,":%1.3f mg/",result);
- OLED_ShowCHinese(0,0,4);//显示汉字甲
- OLED_ShowCHinese(16,0,5);//显示汉字醛
- OLED_ShowString(32,0,receiveBuffer);
- OLED_ShowCHinese(112,0,10);//显示m³
- }
- void ReadDHT11(void)
- {
- uint8_t showBuffer[32];
- uint8_t temp;
- uint8_t humi;
- DHT11_Read_Data(&temp,&humi);
-
- sprintf((char*)showBuffer,":%3d",temp);
- OLED_ShowCHinese(0,2,6);//显示汉字温
- OLED_ShowCHinese(16,2,8);//显示汉字度
- OLED_ShowString(32,2,showBuffer);
- OLED_ShowCHinese(64,2,9);//显示℃
-
- sprintf((char*)showBuffer,":%3d",humi);
- OLED_ShowCHinese(0,4,7);//显示汉字温
- OLED_ShowCHinese(16,4,8);//显示汉字度
- OLED_ShowString(32,4,showBuffer);
- OLED_ShowCHinese(64,4,11);//显示%
- }
- void ReadGP2Y(void)
- {
- uint8_t showBuffer[32];
- int new_pm25 = 0;
- static int prev_pm25 = 0;
- int last_pm25 = 0;
-
- GP2Y_ON;
- DelayUs(280);
- float adValue = GP2Y_Read();
- DelayUs(40);
- GP2Y_OFF;
- DelayUs(9680);
-
- /*无尘测得电压值为0.6,手册上每0.1mg/m3 电压增加0.5V
- *使用excel记算得出公式:y = 0.2x-0.12 */
- new_pm25 = (0.2f*adValue-0.12f)*1000; //电压-灰尘转换
- /*一阶滤波*/
- last_pm25 = 0.2*new_pm25+0.8*prev_pm25;
- prev_pm25 = new_pm25;
-
- sprintf((char*)showBuffer,"PM25:%3d ug/",last_pm25);
- OLED_ShowString(0,6,showBuffer);
- OLED_ShowCHinese(112,6,10);//显示m³
- }
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
6、效果演示