• iic驱动oled屏幕显示温湿度基于FreeRTOS实现多任务


    目录

    oled.c

     模拟iic起始信号

     模拟iic停止信号

     模拟iic读取从机应答信号

    iic读取一个字节byte 

     iic写命令

    iic写数据 

    对oled写入一个字节 

     设置起始页地址

    开显示

    关显示 

    清屏幕 

     显示字符

    oled_init 是固定的

     显示字符串

    计算m^n次方​编辑 

     显示数字

    显示汉字 

    oled.h 

    Dht11.c 

    在函数调用中

    DHT11_Start开始信号

    接收信号

    dht11.h 

     任务函数1

    任务函数2


    oled.c

    我们要用高阻态,所以用开漏输出

     模拟iic起始信号

     模拟iic停止信号

     模拟iic读取从机应答信号

    iic读取一个字节byte 

    高位先行

     iic写命令

    iic写数据 

    对oled写入一个字节 

     设置起始页地址

    把x,y想象成在第四象限

    一个数和1与得到它本身 ,高四位固定了为0001

     

    开显示

     

    关显示 

    清屏幕 

     显示字符

    1. 一页一页写的
    2. 但是有的字符占两页 16 * 8,两页
    3. 8 * 6 ,一页显示一个字符
    4. 每个字符 16 个字节
    5. 一个字符占两页,所以上面是写入上半页,下面是写入下半夜
    6. 八个点阵一个字节
    7. 8 * 2 = 16个字节
    8. 比方说O是47行,O的偏移量为47,则O之前有47*16个字节 c是O的偏移量 i<8
    9. c*16+i就是前8个字节也就是第一页
    10. c*16+i+8就是后8个字节也就是第二页

    oled_init 是固定的

     显示字符串

    计算m^n次方 

     显示数字

    1. 789 i
    2. 789/100%10 = 7 10^(3-1)
    3. 789/10%10 = 8 10^(2-1)
    4. 789/1%10 = 9 10^(1-1)

    显示汉字 

    1. no :第几个字
    2. 每个字占两行
    3. 先讲下数组a[2][3] 两行三列
    4. a[0]a[0] a[0]a[1] a[0][2]
    5. a[1]a[0] a[1]a[1] a[1][2]
    6. 比如 “技” 这个字是第0个 2*0还是0也就是第1行(第一页) 2*0 + 1 = 1也就是第2行(第2页)
    7. 比如 “新” 这个字是第1个 2*1=2 也就是第三行(第三页) 2*1 + 1 = 3也就是第4行(第4页)

     

    oled.h 

     

    Dht11.c 

    1. 配置两个GPIO,为什么会有两个GPIO呢? 因为dht11是通过stm32主机先输出(主机先发送起始信号等待dht11响应之后io口才开始接收数据) 所以第一个输出,浮空输出,既可以输出高也可以输出低
    2. 第二个是输入模式,选择下拉输入
    1. void DHT11_GPIO_Init(void)
    2. {
    3. GPIO_InitTypeDef GPIO_InitStructure;
    4. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    5. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    6. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    7. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    8. GPIO_Init(GPIOB, &GPIO_InitStructure);
    9. GPIO_SetBits(GPIOB, GPIO_Pin_12);
    10. }
    11. void DHT11_GPIO_Init1(void)
    12. {
    13. GPIO_InitTypeDef GPIO_InitStructure;
    14. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    17. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    18. GPIO_Init(GPIOB, &GPIO_InitStructure);
    19. GPIO_SetBits(GPIOB, GPIO_Pin_12);
    20. }

    在函数调用中

    1. 第一个是gpio初始化,输出模式
    2. 第二个是开始信号
    3. 第三个是接收信号
    1. void DHT11_UpdateData()
    2. {
    3. DHT11_GPIO_Init();
    4. DHT11_Start();
    5. DHT11_ReceptionBuff();
    6. }

    DHT11_Start开始信号

    1. void DHT11_Start(void)
    2. {
    3. data0;
    4. delay_ms(20);
    5. data1;
    6. delay_us(10);
    7. DHT11_GPIO_Init1(); //切换到接收模式
    8. while(DHT11_Back()); //等待响应信号
    9. }

    接收信号

    1. 接收5个字节,每个字节8
    2. 接收数字026us~28us
    3. 接收数字170us
    4. 我们折中选择40us,方便区分数字0还是数字1
    5. 我们用两个while
    6. 第一个while(read_data) 接收低电平
    7. 第二个while(!read_data)接收高电平
    8. 并且把初始位(i)设置为0
    9. __nop();函数时空语句,他不会因为我们进去while里面后就不能执行下面的语句了
    10. 每读取一位 就向左移一位 移到低位
    11. 每次移位后中间间隔50us,这里延迟30us
    12. while(read_data);接收下一位时,中间是有一个低电平的,并且每个低电平是50us
    13. 所以我们这里每次进去都要等待低电平,进行下一次for循环
    14. i的值放到Rxbuff里
    1. void DHT11_ReceptionBuff()
    2. {
    3. uint8_t y=1;
    4. uint16_t i;
    5. uint8_t x;
    6. for(x=0;x<5;x++)
    7. {
    8. i=0;
    9. for(y=1;y<9;y++)
    10. {
    11. while(read_data)
    12. {
    13. __nop();
    14. }
    15. delay_us(40);
    16. while(!read_data)
    17. {
    18. __nop();
    19. }
    20. i= i<<1;
    21. delay_us(30);
    22. if(read_data)
    23. {
    24. i |=1;
    25. }
    26. while(read_data);
    27. }
    28. Rxbuff[x] =i;
    29. }
    30. }

     

     

    dht11.h 

    1. #ifndef _DHT11_H
    2. #define _DHT11_H
    3. #include "stm32f10x.h"
    4. #define data1 GPIO_SetBits(GPIOB, GPIO_Pin_11)
    5. #define data0 GPIO_ResetBits(GPIOB, GPIO_Pin_11)
    6. #define read_data GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)
    7. void DHT11_GPIO_Init(void);
    8. void DHT11_GPIO_Init1(void);
    9. void DHT11_Start(void);
    10. void DHT11_ReceptionBuff();
    11. void DHT11_UpdateData();
    12. extern uint16_t Rxbuff[5];
    13. #endif

     任务函数1

    1. void list_task(void *pvParameters)
    2. {
    3. delay_ms(1500);
    4. OLED_Init(); //OLED³õʼ»¯
    5. OLED_Clear();
    6. OLED_ShowCHinese(0,2,6); //µ±
    7. OLED_ShowCHinese(16,2,7); //ǰ
    8. OLED_ShowCHinese(32,2,8); //ÎÂ
    9. OLED_ShowCHinese(48,2,9); //¶È
    10. OLED_ShowCHinese(66,2,10); //£º
    11. OLED_ShowCHinese(90,2,15); //.
    12. OLED_ShowCHinese(112,2,11); //C
    13. OLED_ShowCHinese(16,5,6); //µ±
    14. OLED_ShowCHinese(32,5,7); //ǰ
    15. OLED_ShowCHinese(48,5,12); //ʪ
    16. OLED_ShowCHinese(64,5,9); //¶È
    17. OLED_ShowCHinese(80,5,10); //£º
    18. OLED_ShowCHinese(112,5,13); //.
    19. while(1)
    20. {
    21. uint16_t i;
    22. uint8_t k;
    23. uint8_t kk;
    24. uint8_t kkk;
    25. DHT11_UpdateData();
    26. i = Rxbuff[0]+ Rxbuff[1]+Rxbuff[2]+ Rxbuff[3];
    27. if(Rxbuff[4] ==i)
    28. {
    29. k=Rxbuff[2];
    30. kk=Rxbuff[0];
    31. kkk=Rxbuff[3];
    32. OLED_ShowNum(74,2,k/10,3,3);
    33. OLED_ShowNum(82,2,k%10,3,3);
    34. OLED_ShowNum(98,2,kkk,3,3);
    35. OLED_ShowNum(88,5,kk/10,3,3);
    36. OLED_ShowNum(98,55,kkk%10,3,3);
    37. }
    38. delay_ms(2000);
    39. }
    40. }

    任务函数2

    1. void led0_task(void *pvParameters)
    2. {
    3. while(1)
    4. {
    5. LED0=~LED0;
    6. vTaskDelay(500);
    7. }
    8. }

  • 相关阅读:
    近段时间天气暴热,所以采集北上广深去年天气数据,制作可视化图看下
    Java虚拟机(Jvm详解)
    Runc 漏洞(CVE-2021-30465)离线修复
    Abnova丨CMV CISH 探头解决方案
    2024年小程序云开发CMS内容管理无法使用,无法同步内容模型到云开发数据库的解决方案,回退老版本CMS内容管理的最新方法
    华为云安全亮相世界互联网大会
    Springboot毕设项目码头船只出行及配套货柜码放管理系统89t3y(java+VUE+Mybatis+Maven+Mysql)
    数据结构哈希表(散列)Hash,手写实现(图文推导)
    修改angular cli 的默认包管理器
    react事件系统(新版本)
  • 原文地址:https://blog.csdn.net/Paradise_Violet/article/details/126352116