目录
oled.c
我们要用高阻态,所以用开漏输出
模拟iic起始信号
模拟iic停止信号
模拟iic读取从机应答信号
iic读取一个字节byte
高位先行
iic写命令
iic写数据
对oled写入一个字节
设置起始页地址
把x,y想象成在第四象限
一个数和1与得到它本身 ,高四位固定了为0001
开显示
关显示
清屏幕
显示字符
一页一页写的
但是有的字符占两页 16 * 8,两页
8 * 6 ,一页显示一个字符
每个字符 16 个字节
一个字符占两页,所以上面是写入上半页,下面是写入下半夜
八个点阵一个字节
8 * 2 = 16个字节
比方说O是47行,O的偏移量为47,则O之前有47*16个字节 c是O的偏移量 i<8
c*16+i就是前8个字节也就是第一页
c*16+i+8就是后8个字节也就是第二页
oled_init 是固定的
显示字符串
计算m^n次方
显示数字
789 i
789/100%10 = 7 10^(3-1)
789/10%10 = 8 10^(2-1)
789/1%10 = 9 10^(1-1)
显示汉字
no :第几个字
每个字占两行
先讲下数组a[2][3] 两行三列
a[0]a[0] a[0]a[1] a[0][2]
a[1]a[0] a[1]a[1] a[1][2]
比如 “技” 这个字是第0个 2*0还是0也就是第1行(第一页) 2*0 + 1 = 1也就是第2行(第2页)
比如 “新” 这个字是第1个 2*1=2 也就是第三行(第三页) 2*1 + 1 = 3也就是第4行(第4页)
oled.h
Dht11.c
配置两个GPIO,为什么会有两个GPIO呢? 因为dht11是通过stm32主机先输出(主机先发送起始信号等待dht11响应之后io口才开始接收数据) 所以第一个输出,推挽输出,既可以输出高也可以输出低
第二个是输入模式,选择下拉输入
void DHT11_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
void DHT11_GPIO_Init1(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
在函数调用中
第一个是gpio初始化,输出模式
第二个是开始信号
第三个是接收信号
void DHT11_UpdateData()
{
DHT11_GPIO_Init();
DHT11_Start();
DHT11_ReceptionBuff();
}
DHT11_Start开始信号
void DHT11_Start(void)
{
data0;
delay_ms(20);
data1;
delay_us(10);
DHT11_GPIO_Init1(); //切换到接收模式
while(DHT11_Back()); //等待响应信号
}
接收信号
接收5个字节,每个字节8位
接收数字0是 26us~28us
接收数字1是 70us
我们折中选择40us,方便区分数字0还是数字1
我们用两个while
第一个while(read_data) 接收低电平
第二个while(!read_data)接收高电平
并且把初始位(i)设置为0位
__nop();函数时空语句,他不会因为我们进去while里面后就不能执行下面的语句了
每读取一位 就向左移一位 移到低位
每次移位后中间间隔50us,这里延迟30us
while(read_data);接收下一位时,中间是有一个低电平的,并且每个低电平是50us
所以我们这里每次进去都要等待低电平,进行下一次for循环
把i的值放到Rxbuff里
void DHT11_ReceptionBuff()
{
uint8_t y=1;
uint16_t i;
uint8_t x;
for(x=0;x<5;x++)
{
i=0;
for(y=1;y<9;y++)
{
while(read_data)
{
__nop();
}
delay_us(40);
while(!read_data)
{
__nop();
}
i= i<<1;
delay_us(30);
if(read_data)
{
i |=1;
}
while(read_data);
}
Rxbuff[x] =i;
}
}
dht11.h
#ifndef _DHT11_H
#define _DHT11_H
#include "stm32f10x.h"
#define data1 GPIO_SetBits(GPIOB, GPIO_Pin_11)
#define data0 GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define read_data GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)
void DHT11_GPIO_Init(void);
void DHT11_GPIO_Init1(void);
void DHT11_Start(void);
void DHT11_ReceptionBuff();
void DHT11_UpdateData();
extern uint16_t Rxbuff[5];
#endif
任务函数1
void list_task(void *pvParameters)
{
delay_ms(1500);
OLED_Init(); //OLED³õʼ»¯
OLED_Clear();
OLED_ShowCHinese(0,2,6); //µ±
OLED_ShowCHinese(16,2,7); //ǰ
OLED_ShowCHinese(32,2,8); //ÎÂ
OLED_ShowCHinese(48,2,9); //¶È
OLED_ShowCHinese(66,2,10); //£º
OLED_ShowCHinese(90,2,15); //.
OLED_ShowCHinese(112,2,11); //C
OLED_ShowCHinese(16,5,6); //µ±
OLED_ShowCHinese(32,5,7); //ǰ
OLED_ShowCHinese(48,5,12); //ʪ
OLED_ShowCHinese(64,5,9); //¶È
OLED_ShowCHinese(80,5,10); //£º
OLED_ShowCHinese(112,5,13); //.
while(1)
{
uint16_t i;
uint8_t k;
uint8_t kk;
uint8_t kkk;
DHT11_UpdateData();
i = Rxbuff[0]+ Rxbuff[1]+Rxbuff[2]+ Rxbuff[3];
if(Rxbuff[4] ==i)
{
k=Rxbuff[2];
kk=Rxbuff[0];
kkk=Rxbuff[3];
OLED_ShowNum(74,2,k/10,3,3);
OLED_ShowNum(82,2,k%10,3,3);
OLED_ShowNum(98,2,kkk,3,3);
OLED_ShowNum(88,5,kk/10,3,3);
OLED_ShowNum(98,55,kkk%10,3,3);
}
delay_ms(2000);
}
}
任务函数2
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
}
}