学校课设,记录一下.
DHT温湿度传感器部分代码
//dht22.h
#ifndef __DHT22_H
#define __DHT22_H
#include "sys.h"
//IO方向设置
#define DHT22_IO_IN() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=4<<4;}
#define DHT22_IO_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=3<<4;}
IO操作函数
#define DHT22_DQ_OUT PBout(9) //数据端口 PB9
#define DHT22_DQ_IN PBin(9) //数据端口 PB9
u8 DHT22_Init(void);
u8 DHT22_Read_Data(u16 *temp,u16 *humi);
u8 DHT22_Read_Byte(void);
u8 DHT22_Read_Bit(void);
u8 DHT22_Check(void);
void DHT22_Rst(void);
#endif
//dht22.c
#include "dht22.h"
#include "delay.h"
//如果使用ucosII,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucosII 使用
#endif
//复位DHT22
//主机信号
void DHT22_Rst(void)
{
DHT22_IO_OUT();//SET OUTPUT
DHT22_DQ_OUT=0;//拉低DQ
delay_ms(1);//主机知道拉低500us
DHT22_DQ_OUT=1;//DQ=1
delay_us(30);//主机拉高20~40us
}
//等待DHT22的回应
//返回1:未检测到DHT22的存在
//返回0:DHT22已连接
//数据维持电平固定时间为80us左右,故等待时间为其2倍,即200us,观察200us之内
//检查电平状态是否会改变,先变低再变高
u8 DHT22_Check(void)
{
u8 retry=0;
DHT22_IO_IN();//SET INPUT
while (DHT22_DQ_IN&&retry<200)//等待低电平
{
retry++;
delay_us(1);
}
if(retry>=200)return 1;//如果retry大于200直接返回1
else retry=0;
while (!DHT22_DQ_IN&&retry<200)//DHT22拉低后会再次拉高80us左右
{
retry++;
delay_us(1);
}
if(retry>=200)return 1;
else return 0;
}
//从DHT22读取一个位
//返回值:1/0
u8 DHT22_Read_Bit(void)
{
u8 retry=0;
while(DHT22_DQ_IN&&retry<200)//等待变为低电平
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT22_DQ_IN&&retry<200)//等待变高电平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(DHT22_DQ_IN)return 1;
return 0;
}
//从DHT22读取一个字节
//返回值:读到的数据
u8 DHT22_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT22_Read_Bit();
}
return dat;
}
//从DHT22读取一次数据
//temp:温度值(范围:-40~80°)
//humi:湿度值(范围:20%~100%)
//返回值:0,正常;1,读取失败DHT22连接断开
u8 DHT22_Read_Data(u16 *temp,u16 *humi)
{
u8 buf[5];
u8 i,sum;
DHT22_Rst();//等待响应
if(DHT22_Check()==0)
{
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT22_Read_Byte();
}
// *humi=buf[0]*256+buf[1];
// *temp=buf[2]*256+buf[3];
sum =((buf[0]+buf[1]+buf[2]+buf[3])&0xFF);
if(sum==buf[4])//校验
{
*humi=buf[0]*256+buf[1];
*temp=buf[2]*256+buf[3];
}
}else return 1;
return 0;
}
//初始化DHT22的IO口 DQ 同时检测DHT22的存在
//返回1:不存在
//返回0:存在
u8 DHT22_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PB9端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化IO口
GPIO_SetBits(GPIOB,GPIO_Pin_9); //PB9 输出高
DHT22_Rst(); //复位DHT22
return DHT22_Check();//等待DHT22的回应
}
OLED
0.96' 四脚 GND VCC SCL SDA
//oled.h
#ifndef __OLED_H
#define __OLED_H
#include "stm32f10x.h"
#include "sys.h"
#define I2C_SPEED 400000
#define OWN_ADDRESS 0X77
#define OLED_ADDRESS 0X78
#define OLED_I2C I2C1
#define I2CT_FLAG_TIMEOUT ((uint32_t)300)
#define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))
#define EEPROM_ERROR(fmt,arg...) printf("<<-OLED-ERROR->> "fmt"\n",##arg)
void OLED_Init(void);
void WriteCmd(unsigned char I2C_Command);
void WriteDat(unsigned char I2C_Data);
void Oled_WriteByte(u8 reg_add,u8 reg_dat);
void OLED_GRAM_FILL(unsigned char fill_Data);
void OLED_Refresh_Gram(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);// -- ??
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);
void OLED_ShowStr(u8 x,u8 y,const u8 *p,u8 size,u8 mode);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char* BMP);
void OLED_draw_line(const u8 x0,const u8 y0,const float k,u8 mode);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
#endif
//oled.c
#include "oled.h"
#include "oledfont.h"
/**
******************************************************************************
* @file
* @author
* @version
* @date
* @brief i2c OLED???
******************************************************************************
* Function List:
void OLED_Init(void);// -- OLED???? ?????PB6->SCL
// PB7->SDA
uint32_t Write_Byte_to_OLED(u8 Cmd_or_Data,u8 Data)//??I2C?Cmd_or_Data??Data
void WriteCmd(unsigned char I2C_Command);// -- ???
void WriteDat(unsigned char I2C_Data);// -- ???
void OLED_Refresh_Gram(void);//??
void OLED_ON(void);// -- ??
void OLED_OFF(void);//) -- ??
void OLED_SetPos(unsigned char x, unsigned char y);// -- ???????
void OLED_Fill(unsigned char fill_Data);// -- ????
void OLED_CLS(void);// -- ??
void OLED_DrawPoint(u8 x,u8 y,u8 t);// --??
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);// --??????
void OLED_ShowStr(u8 x,u8 y,const u8 *p,u8 size);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);// -- ????(???????,????oledfont.h?)
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);// -- BMP??
*
**/
u8 OLED_GRAM[128][8];
static __IO uint32_t I2CTimeout = I2CT_LONG_TIMEOUT;
static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);
/************************************
* @brief Write_Byte_to_OLED,HARDWARE I2C
* @param ?
* @retval ?
***********************************/
uint32_t Write_Byte_to_OLED(u8 Cmd_or_Data,u8 Data)
{
I2C_GenerateSTART(OLED_I2C, ENABLE);
//????
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(OLED_I2C, I2C_EVENT_MASTER_MODE_SELECT))
//EV5
{
if((I2CTimeout--) == 0)
return I2C_TIMEOUT_UserCallback(0);
}
I2C_Send7bitAddress(OLED_I2C, OLED_ADDRESS, I2C_Direction_Transmitter);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(OLED_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EV6
{
if((I2CTimeout--) == 0)
return I2C_TIMEOUT_UserCallback(1);
}
I2C_SendData(OLED_I2C, Cmd_or_Data);
//??????????,??0x00,??0x40
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(OLED_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
//EV8 and clear it */
{
if((I2CTimeout--) == 0)
return I2C_TIMEOUT_UserCallback(2);
}
I2C_SendData(OLED_I2C, Data); //????????
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(OLED_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //EV8 and clear it */
{
if((I2CTimeout--) == 0)
return I2C_TIMEOUT_UserCallback(3);
}
I2C_GenerateSTOP(OLED_I2C, ENABLE); //????
return 1;
}
/************************************
* @brief OLED_Init,???OLED
* @param ?
* @retval ?
***********************************/
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = OWN_ADDRESS;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
delay_ms(1000); // 1s,????????,?????,?????????
WriteCmd(0xAE);//--display off
WriteCmd(0x00);//---set low column address
WriteCmd(0x10);//---set high column address
WriteCmd(0x40);//--set start line address
WriteCmd(0xB0);//--set page address
WriteCmd(0x81); // contract control
WriteCmd(0xFF);//--128
WriteCmd(0xA1);//set segment remap
WriteCmd(0xA6);//--normal / reverse
WriteCmd(0xA8);//--set multiplex ratio(1 to 64)
WriteCmd(0x3F);//--1/32 duty
WriteCmd(0xC8);//Com scan direction
WriteCmd(0xD3);//-set display offset
WriteCmd(0x00);//
WriteCmd(0xD5);//set osc division
WriteCmd(0x80);//
WriteCmd(0xD8);//set area color mode off
WriteCmd(0x05);//
WriteCmd(0xD9);//Set Pre-Charge Period
WriteCmd(0xF1);//
WriteCmd(0xDA);//set com pin configuartion
WriteCmd(0x12);//
WriteCmd(0xDB);//set Vcomh
WriteCmd(0x30);//
WriteCmd(0x8D);//set charge pump enable
WriteCmd(0x14);//
WriteCmd(0xAF);//--turn on OLED panel
}
/**********************************************************************
* @brief WriteCmd,?OLED????
* @param I2C_Command:????
* @retval ?
*********************************************************************/
void WriteCmd(unsigned char I2C_Command)//???
{
Write_Byte_to_OLED(0x00, I2C_Command);
}
/**********************************************************************
* @brief OLED_WriteDat
* @param I2C_Data:??
* @retval ?
*********************************************************************/
void WriteDat(unsigned char I2C_Data)//???
{
Write_Byte_to_OLED(0x40, I2C_Data);
}
/*****************************************************Draw********************************************/
//?????OLED
void OLED_Refresh_Gram(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
WriteCmd(0xb0+i); //?????(0~7)
WriteCmd(0x00); //??????????
WriteCmd(0x10); //??????????
for(n=0;n<128;n++)WriteDat(OLED_GRAM[n][i]);
}
}
/*************************************************************************
* @brief OLED_ON,?OLED??????
* @param ?
* @retval ?
************************************************************************/
void OLED_ON(void)
{
WriteCmd(0X8D); //?????
WriteCmd(0X14); //?????
WriteCmd(0XAF); //OLED??
}
/*************************************************************************
* @brief OLED_OFF,?OLED?? -- ?????,OLED????10uA
* @param ?
* @retval ?
************************************************************************/
void OLED_OFF(void)
{
WriteCmd(0X8D); //?????
WriteCmd(0X10); //?????
WriteCmd(0XAE); //OLED??
}
/*************************************************************************
* @brief OLED_SetPos,????
* @param x,??x??
* y,??y??
* @retval ?
************************************************************************/
void OLED_SetPos(unsigned char x, unsigned char y) //???????
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
/*************************************************************************
* @brief OLED_Fill,??????
* @param fill_Data:??????
* @retval ?
************************************************************************/
void OLED_Fill(unsigned char fill_Data)//????
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
OLED_GRAM[n][m] = fill_Data;
}
}
}
/*************************************************************************
* @brief OLED_Fill,??????
* @param fill_Data:??????
* @retval ?
************************************************************************/
void OLED_GRAM_FILL(unsigned char fill_Data)//????
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
OLED_GRAM[n][m] = fill_Data;
}
}
}
/*************************************************************************
* @brief OLED_CLS,??
* @param ?
* @retval ?
************************************************************************/
void OLED_CLS(void)//??
{
OLED_Fill(0x00);
}
/*************************************************************************
* @brief OLED_DrawPoint ??
* @param x:0~127
* y:0~63
* t:1 ?? 0,??
* @retval ?
************************************************************************/
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
u8 pos,bx,temp=0;
if(x>127||y>63)return;//?????.
pos=y/8;
bx=y%8;
temp=1<<(bx);
if(t)OLED_GRAM[x][pos]|=temp;
else OLED_GRAM[x][pos]&=~temp;
}
/*************************************************************************
* @brief OLED_char,??????,?6*8?16*16 24*24???
* @param x,y : ?????(x:0~127, y:0~63);
* chr :- ??????;
* Size : ????(12/16/24)
* mode:0,????;1,????
* @retval ?
************************************************************************/
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{
u8 temp,t,t1;
u8 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2); //???????????????????
chr=chr-' ';//???????
for(t=0;t=' '))//?????????!
{
if(x>(128-(size/2))){x=0;y+=size;}
if(y>(64-size)){y=x=0;OLED_CLS();}
OLED_ShowChar(x,y,*p,size,mode);
x+=size/2;
p++;
}
}
/*************************************************************************
* @brief OLED_ShowCN,??codetab.h????,16*16??
* @param x,y: ?????(x:0~127, y:0~7);
* N:???codetab.h????
* @retval ?
************************************************************************/
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(CN16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(CN16x16[adder]);
adder += 1;
}
}
/************************************************************************
* @brief OLED_DrawBMP,??BMP[]???
* @param x0,y0 :?????(x0:0~127, y0:0~7);
* x1,y1 : ?????(???)???(x1:1~128,y1:1~8)
* @retval ?
************************************************************************/
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;y0 &&x <128 )&& (y<64&&y>0))
{
OLED_DrawPoint(x,y,mode);
x++;
y+=k;
}
x=x0,y=y0;
while(x>0 && y>0)
{
OLED_DrawPoint(x,y,mode);
x--;
y-=k;
}
}
//m^n函数
u32 mypow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t
main函数部分:
//DHT22 温湿度传感器
//+ 接 3.3V或5V
//- 接 GND
//out 接 PB9
#include "led.h"
#include "oled.h"
#include "delay.h"
#include "sys.h"
#include "dht22.h"
#include "usart.h"
int main(void){
u16 temperature,humidity;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
delay_init();
LED_Init();
OLED_Init();
OLED_ShowStr(0,0,"Temperature: . C",12,1);
OLED_ShowStr(0,12,"Humidity: . %",12,1);
DHT22_Init();
delay_ms(1000);
while(1){
OLED_Refresh_Gram();
DHT22_Read_Data(&temperature,&humidity);
OLED_ShowNum(93,0,temperature%10,2,12);
OLED_ShowNum(73,0,temperature/10,2,12);
OLED_ShowNum(93,12,humidity%10,2,12);
OLED_ShowNum(73,12,humidity/10,2,12);
delay_ms(10);
LED=!LED;
delay_ms(1000);
}
}
参考文章:STM32寄存器操作端口模式CRL/CRH详解_weixin_45164090的博客-CSDN博客_crl和crh
stm32f103c8t6模拟IIC驱动0.96'oled_贾晓籽的博客-CSDN博客STM32F103驱动DHT22温湿度传感器程序讲解(附加程序下载)_帅奎奎的博客-CSDN博客_dht22 stm32