1.SD卡模块,采用SPI1接线
(CLK)SCK <—>PA5
(DATA0)MISO <—>PA6
(CMD)MOSI <—>PA7
(DATA3)CS <—>PA4
前面小括号里的是SDIO模式的接线,可以忽略。
2.0.96寸oled屏模块
oledp屏的spi接线有六针和七针的,其实没什么区别,片选C/S不接就是六针了,RST与D/C两个引脚也可以使用普通IO,程序里满足电平条件就行,这里使用板子硬件SPI2资源。
六针七针:
GND — 接地端口
VCC — 接3.3V电源端口
SCL(D0) — SK时钟信号端口 PB13
SDA (D1) — MOSI数据端口 PB15
RST — 复位端口 PB12
D/C — 数据/命令选择引脚 PB0(可自定义io 口)
C/S— 片选 不接
3.DHT11模块
DATA <—>PC7
可以自己选择任意IO口,代码对应就行。
代码是在野火的SD卡测试代码和原子的oled屏代码上更新修改的,所以接口初始化啥的直接参考野火或者其它的就可以,读取变量写入SD卡的实现之前已经写过了,所以就不再写一遍了,这里只写一下oled驱动的变量显示和利用软件生成自己所需要的字库字库。
屏幕像素:128*64
显示坐标起始:x从左向右, y从上到下
gui.c: 实现一些显示功能,太长了就不贴了。重要的是包含字库文件,对应的文件夹里要有字库文件
#include "oledfont.h"
spi.c:初始化spi就行了;
oled.c:
#include "oled.h"
#include "stdlib.h"
#include "string.h"
#include "delay.h"
#include "spi.h"
#include "sys.h"
//OLED显存总共分为8页
//每页8行,一行128个像素点
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127 (0~7)行
//[1]0 1 2 3 ... 127 (8~15)行
//[2]0 1 2 3 ... 127 (16~23)行
//[3]0 1 2 3 ... 127 (24~31)行
//[4]0 1 2 3 ... 127 (32~39)行
//[5]0 1 2 3 ... 127 (40~47)行
//[6]0 1 2 3 ... 127 (48~55)行
//[7]0 1 2 3 ... 127 (56~63)行
//数组每个bit存储OLED每个像素点的颜色值(1-亮(白色),0-灭(黑色))
//每个数组元素表示1列8个像素点,一共128列
static unsigned char OLED_buffer[1024] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/*******************************************************************
* @name :void OLED_WR_Byte(unsigned dat,unsigned cmd)
* @date :2018-08-27
* @function :Write a byte of content to the OLED screen
* @parameters :dat:Content to be written
cmd:0-write command
1-write data
* @retvalue :None
********************************************************************/
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
OLED_DC_Set();
}
else
{
OLED_DC_Clr();
}
OLED_CS_Clr();
SPI_WriteByte(SPI2,dat);
OLED_CS_Set();
}
/*******************************************************************
* @name :void OLED_Set_Pos(unsigned char x, unsigned char y)
* @date :2018-08-27
* @function :Set coordinates in the OLED screen
* @parameters :x:x coordinates
y:y coordinates
* @retvalue :None
********************************************************************/
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
OLED_WR_Byte(YLevel+y/PAGE_SIZE,OLED_CMD);
OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte(((x+2)&0x0f),OLED_CMD);
}
/*******************************************************************
* @name :void OLED_Display_On(void)
* @date :2018-08-27
* @function :Turn on OLED display
* @parameters :None
* @retvalue :None
********************************************************************/
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
}
/*******************************************************************
* @name :void OLED_Display_Off(void)
* @date :2018-08-27
* @function :Turn off OLED display
* @parameters :None
* @retvalue :None
********************************************************************/
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
}
/*******************************************************************
* @name :void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color)
* @date :2018-08-27
* @function :set the value of pixel to RAM
* @parameters :x:the x coordinates of pixel
y:the y coordinates of pixel
color:the color value of the point
1-white
0-black
* @retvalue :None
********************************************************************/
void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color)
{
if(color)
{
OLED_buffer[(y/PAGE_SIZE)*WIDTH+x]|= (1<<(y%PAGE_SIZE))&0xff;
}
else
{
OLED_buffer[(y/PAGE_SIZE)*WIDTH+x]&= ~((1<<(y%PAGE_SIZE))&0xff);
}
}
/*******************************************************************
* @name :void OLED_Display(void)
* @date :2018-08-27
* @function :Display in OLED screen
* @parameters :None
* @retvalue :None
********************************************************************/
void OLED_Display(void)
{
u8 i,n;
for(i=0;i<PAGE_SIZE;i++)
{
OLED_WR_Byte (YLevel+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (XLevelL,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (XLevelH,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<WIDTH;n++)
{
OLED_WR_Byte(OLED_buffer[i*WIDTH+n],OLED_DATA);
}
} //更新显示
}
/*******************************************************************
* @name :void OLED_Clear(unsigned dat)
* @date :2018-08-27
* @function :clear OLED screen
* @parameters :dat:0-Display full black
1-Display full white
* @retvalue :None
********************************************************************/
void OLED_Clear(unsigned dat)
{
if(dat)
{
memset(OLED_buffer,0xff,sizeof(OLED_buffer));
}
else
{
memset(OLED_buffer,0,sizeof(OLED_buffer));
}
OLED_Display();
}
/*******************************************************************
* @name :void OLED_Reset(void)
* @date :2018-08-27
* @function :Reset OLED screen
* @parameters :dat:0-Display full black
1-Display full white
* @retvalue :None
********************************************************************/
void OLED_Reset(void)
{
OLED_RST_Set();
Delay_ms(100);
OLED_RST_Clr();
Delay_ms(100);
OLED_RST_Set();
}
/*******************************************************************
* @name :void OLED_Init_GPIO(void)
* @date :2018-08-27
* @function :Reset OLED screen
* @parameters :None
* @retvalue :None
********************************************************************/
void OLED_Init_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能B端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12; //GPIOB10,11,12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB10、11、12
GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);
}
/*******************************************************************
* @name :void OLED_Init(void)
* @date :2018-08-27
* @function :initialise OLED SH1106 control IC
* @parameters :None
* @retvalue :None
********************************************************************/
void OLED_Init(void)
{
SPI2_Init(); //初始化SPI2
OLED_Init_GPIO(); //初始化GPIO
Delay_ms(200);
OLED_Reset(); //复位OLED
/**************初始化SSD1306*****************/
OLED_WR_Byte(0xAE,OLED_CMD); /*display off*/
OLED_WR_Byte(0x00,OLED_CMD); /*set lower column address*/
OLED_WR_Byte(0x10,OLED_CMD); /*set higher column address*/
OLED_WR_Byte(0x40,OLED_CMD); /*set display start line*/
OLED_WR_Byte(0xB0,OLED_CMD); /*set page address*/
OLED_WR_Byte(0x81,OLED_CMD); /*contract control*/
OLED_WR_Byte(0xFF,OLED_CMD); /*128*/
OLED_WR_Byte(0xA1,OLED_CMD); /*set segment remap*/
OLED_WR_Byte(0xA6,OLED_CMD); /*normal / reverse*/
OLED_WR_Byte(0xA8,OLED_CMD); /*multiplex ratio*/
OLED_WR_Byte(0x3F,OLED_CMD); /*duty = 1/64*/
OLED_WR_Byte(0xC8,OLED_CMD); /*Com scan direction*/
OLED_WR_Byte(0xD3,OLED_CMD); /*set display offset*/
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xD5,OLED_CMD); /*set osc division*/
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD); /*set pre-charge period*/
OLED_WR_Byte(0XF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD); /*set COM pins*/
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD); /*set vcomh*/
OLED_WR_Byte(0x30,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD); /*set charge pump disable*/
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
}
不同大小字体的字库不同,这里只列一个16*16大小的字库:包含(温湿度检测:)这几个字,在hui.c里的oledfont.h中
typedef struct
{
unsigned char Index[2];
char Msk[32];
}typFNT_GB16;
//宋体
//16*16大小
//逐行式,顺向(高位在前)
const typFNT_GB16 cfont16[] =
{
"温",0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,
0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00,/*"温",0*/
"湿",0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,
0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00,/*"湿",1*/
"度",0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,
0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E,/*"度",2*/
"检",0x10,0x40,0x10,0x40,0x10,0xA0,0x10,0xA0,0xFD,0x10,0x12,0x08,0x35,0xF6,0x38,0x00,
0x54,0x88,0x50,0x48,0x92,0x48,0x11,0x50,0x11,0x10,0x10,0x20,0x17,0xFE,0x10,0x00,/*"检",3*/
"测",0x00,0x04,0x27,0xC4,0x14,0x44,0x14,0x54,0x85,0x54,0x45,0x54,0x45,0x54,0x15,0x54,
0x15,0x54,0x25,0x54,0xE5,0x54,0x21,0x04,0x22,0x84,0x22,0x44,0x24,0x14,0x08,0x08,/*"测",4*/
":",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,/*":",5*/
};
使用的是PCtoLCD2002软件,
1.选择字符模式
2.字体设置:
3.取模设置
1.以"温湿度检测"为例,宋体,16*16
2.取模设置
3.生成字模文件保存
4.将取模的结果复制到oledfont.h中,注意看有没有漏掉逗号,还要再最前面加上对应的汉字,不知道有没有更方便的取模软件。
之后就可以输出字库里的汉字了。
1.oled显示部分
char buff[20];//存储sprintf转换后的字符串
char buffh[10];
char bufft[10];
/*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
{
printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",
DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
//\n前不要有空格,否则换行符失效
sprintf(buff,"%d.%d %RH,%d.%d℃\n",
DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
//u8 buff[]=DHT11_Data.humi_int;
GUI_Fill(0,0,WIDTH-1,HEIGHT/2-1,0);
sprintf(buffh,"%d.%dRH",DHT11_Data.humi_int,DHT11_Data.humi_deci);
sprintf(bufft,"%d.%d",DHT11_Data.temp_int,DHT11_Data.temp_deci);
OLED_Clear(0);
GUI_ShowCHinese(0,0,16,"温湿度检测:",1);//起始坐标(0,0),大小16,写入中文(字库里要有)
GUI_ShowString(0,20,"hum: ",16,1);
GUI_ShowString(35,20,(u8 *)buffh,16,1);
GUI_ShowString(0,40,"tem: ",16,1);
GUI_ShowString(35,40,(u8 *)bufft,16,1);
2.主函数完整代码(包括SD卡写入部分)
/**
******************************************************************************
* @file main.c
* @author fire
* @version V1.0
* @date 2013-xx-xx
* @brief SD卡文件系统例程
******************************************************************************
* @attention
*
* 实验平台:野火 STM32 F103-指南者 开发板
* 论坛 :http://www.firebbs.cn
* 淘宝 :https://fire-stm32.taobao.com
*
******************************************************************************
*/
#include "stm32f10x.h"
#include "bsp_spi_sdcard.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "ff.h"
#include "dht11.h"
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "oled.h"
#include "gui.h"
/**
******************************************************************************
* 定义变量
******************************************************************************
*/
FATFS fs; /* FatFs文件系统对象 */
FIL fnew; /* 文件对象 */
FRESULT res_sd; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
extern SD_CardInfo SDCardInfo;
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
DHT11_Data_TypeDef DHT11_Data;
/* 初始化系统定时器 */
SysTick_Init();
/* 初始化调试串口,一般为串口1 */
USART_Config();
/*初始化DTT11的引脚*/
DHT11_Init ();
// NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear(0); //清屏(全黑)
while(1)
{
char buff[20];//存储sprintf转换后的字符串
char buffh[10];
char bufft[10];
/*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
{
printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",
DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
//\n前不要有空格,否则换行符失效
sprintf(buff,"%d.%d %RH,%d.%d℃\n",
DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
//u8 buff[]=DHT11_Data.humi_int;
GUI_Fill(0,0,WIDTH-1,HEIGHT/2-1,0);
sprintf(buffh,"%d.%dRH",DHT11_Data.humi_int,DHT11_Data.humi_deci);
sprintf(bufft,"%d.%d",DHT11_Data.temp_int,DHT11_Data.temp_deci);
OLED_Clear(0);
GUI_ShowCHinese(0,0,16,"温湿度检测:",1);//起始坐标(0,0),大小16,写入中文(字库里要有)
GUI_ShowString(0,20,"hum: ",16,1);
GUI_ShowString(35,20,(u8 *)buffh,16,1);
GUI_ShowString(0,40,"tem: ",16,1);
GUI_ShowString(35,40,(u8 *)bufft,16,1);
//在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
res_sd = f_mount(&fs,"0:",1);
/*----------------------- 格式化测试 ---------------------------*/
/* 如果没有文件系统就格式化创建创建文件系统 */
if(res_sd == FR_NO_FILESYSTEM)
{
printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
/* 格式化 */
res_sd=f_mkfs("0:",0,0);
if(res_sd == FR_OK)
{
printf("》SD卡已成功格式化文件系统。\r\n");
/* 格式化后,先取消挂载 */
res_sd = f_mount(NULL,"0:",1);
/* 重新挂载 */
res_sd = f_mount(&fs,"0:",1);
}
else
{
LED_RED;
printf("《《格式化失败。》》\r\n");
while(1);
}
}
else if(res_sd!=FR_OK)
{
printf("!!SD卡挂载文件系统失败。(%d)\r\n",res_sd);
printf("!!可能原因:SD卡初始化不成功。\r\n");
while(1);
}
else
{
printf("》文件系统挂载成功,可以进行读写测试\r\n");
}
/*----------------------- 文件系统测试:写测试 -----------------------------*/
/* 打开文件,如果文件不存在则创建它 */
printf("\r\n****** 即将进行文件写入测试... ******\r\n");
//注意f_open第三个参数,打开文件模式设置要注意
//创建CSV文件
res_sd = f_open(&fnew, "0:test.csv",FA_OPEN_ALWAYS | FA_WRITE );
if ( res_sd == FR_OK )
{
printf("》打开/创建test.csv文件成功,向文件写入数据。\r\n");
//文件对象的读写指针移动到文件结束处
f_lseek (&fnew,f_size (&fnew));
printf("%lu",f_size (&fnew));
/* 将指定存储区内容写入到文件内 */
res_sd= f_write(&fnew,buff,sizeof(buff),&fnum);
if(res_sd==FR_OK)
{
printf("》文件写入成功,写入字节数据:%d\n",fnum);
}
else
{
printf("!!文件写入失败:(%d)\n",res_sd);
}
/* 不再读写,关闭文件 */
f_close(&fnew);
f_mount(NULL,"0:",1);
}
else
{
LED_RED;
printf("!!打开/创建文件失败。\r\n");
}
}
else
{
printf("Read DHT11 ERROR!\r\n");
}
printf("等待下一次记录");
Delay_ms(5000);
}
}
1.oled显示,5S刷新一次