打印
[uCOS/RTOS]

【RTOS】+ RTT大赛提交 +智能冰箱

[复制链接]
2076|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 北方西门吹雪 于 2020-7-6 13:38 编辑

【RT-Thread作品秀】智能冰箱
作者:北方西门吹雪


概述
      智能冰箱是通过采集冰箱内的温度变化,自动调节启动停止方式,实现节能的效果。
      使用的硬件是龙芯教育板。基于MIPS指令集的一款完全国产化的SoC集成芯片。搭载 2K1000 处理器(主频 1GHz),板载 DDR3 颗粒,实现 DDR3 的运行存储功能。实现了 GPIO 的输入输出,中断功能。板上集成 1 个网 口,集成 3 个 USB 接口,HDMI 接口,LCD 接口,音频输入/输出,集成 SD 卡接口,集成 2 个 CAN 接口,集成 RTC 计时功能。可以外扩 WIFI 模块。2K 龙芯派可以广泛应用于信息安 全、电力、轨道交通、工业控制、信号处理、数据通信、信息教育等领域。
搭载 2K1000 处理器(主频 1GHz),板载 DDR3 颗粒,实现 DDR3 的运行存储功能。实现了 GPIO 的输入输出,中断功能。板上集成 1 个网 口,集成 3 个 USB 接口,HDMI 接口,LCD 接口,音频输入/输出,集成 SD 卡接口,集成 2 个 CAN 接口,集成 RTC 计时功能。可以外扩 WIFI 模块。2K 龙芯派可以广泛应用于信息安 全、电力、轨道交通、工业控制、信号处理、数据通信、信息教育等领域,选择嵌入式应用是龙芯工业版的领域,这次使用的是龙芯教育版,更多是适合桌面系统。

      本项目实现的功能是实时采集环境温度,并根据温度变化及时调整智能冰箱的通断。
      补充说明:
      最初提出的设计方案,主要包括连接摄像头驱动,导入深度学习引擎tensorflowlite实现图像分割和图像分类的方式,自动记录冰箱内的物品。因为开发的时间短,提供的RTT硬件驱动只有GPIO和UART,因此主要的时间用在RTT的BSP部分开发,主要时间用于完成了I2C的驱动开发,智能完成智能冰箱温控的基本功能。
     RTT调试口使用RS232-UART0。同时编译调试需要进行如下修改,
rtconfig.py,使用自己安装后的路径。
#        EXEC_PATH   = r'D:\Development\DesignParks\codebench\bin'
修改SConstruct这个文件:
rtconfig.AFLAGS += ' -I' + RTT_ROOT + '/libcpu/mips/common'
rtconfig.AFLAGS += ' -I' + str(Dir('#'))
可以写入U盘,然后进入pmon加载
1. load /dev/fs/fat@usb0/rtthread.elf
2. 或者load (usb0,0)/rtthread.elf
3. g

RT-Thread使用情况概述
      RTT内核,使用了I2C,GPIO的硬件驱动,同时使用了thread线程管理,实现RTOS的基本功能。其他组件,软件包,均没有采用。主要是因为适应的驱动生态不够完善,也没有测试,短时还不具备使用条件。
     主要的工作在驱动编写和测试,因为驱动编写的过程比较长,所有按照反方向介绍,更容易理解。所以总结一下RTT的i2c驱动编写过程。
    1. RTT的驱动和开发板的驱动之间是需要一个函数连接,这样使用标准RTT的语句,就重定向到了开发板的专用驱动函数中。不同的硬件,需要不同的语句,对于I2C,需要执行的是总线注册,
rt_i2c_bus_device_register(&l2k_i2c->parent, "i2c0");
这个语句把如下结构体关联到了标准RTT的i2c语句中,
static const struct rt_i2c_bus_device_ops l2k_i2c_ops =
{
  rt_i2c_master_xfer,
  RT_NULL,
  rt_i2c_bus_control
};

     在标准的RTT驱动中,i2c就是通过这样的注册过程,重定向到了在BSP目录下的对应driver。
    2. 然后就是上述对应函数的编写,
rt_size_t rt_i2c_master_xfer(struct rt_i2c_bus_device *bus,  struct rt_i2c_msg *msgs,  rt_uint32_t num)
{
  struct l2k_i2c_bus * i2c_bus = (struct l2k_i2c_bus *)bus;
  l2k_i2c_info_t i2c_info;
  struct rt_i2c_msg *msg;
  int i;
  rt_int32_t ret = RT_EOK;
  i2c_info.clock = 50000; // 50kb/s
  i2c_info.I2Cx = i2c_bus->u32Module;
  i2c_init(&i2c_info);
  for (i = 0; i < num; i++)
  {
  msg = &msgs[i];
  if (msg->flags == RT_I2C_RD)
  {
  i2c_send_start_and_addr(&i2c_info, msg->addr, L2K_I2C_DIRECTION_READ);
  i2c_receive_ack(&i2c_info);
  i2c_receive_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len);
  i2c_send_stop(&i2c_info);
  }
  else if(msg->flags == RT_I2C_WR)
  {
  i2c_send_start_and_addr(&i2c_info, msg->addr, L2K_I2C_DIRECTION_WRITE);
  i2c_receive_ack(&i2c_info);
  i2c_send_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len);
  i2c_send_stop(&i2c_info);
  }
  ret++;
  }
  return ret;
}

    在rt_i2c_master_xfer()函数中,   

3. 根据i2c的传输协议需要写入对应的地址和msg内容,并引用新的语句,如
i2c_send_start_and_addr(&i2c_info, msg->addr, L2K_I2C_DIRECTION_READ);  

代码如下,
l2k_i2c_ret_t i2c_send_start_and_addr(l2k_i2c_info_t *i2c_info_p,  unsigned char slave_addr,  l2k_i2c_direction_t direction)
{
  void *i2c_base = i2c_get_base(i2c_info_p->I2Cx);
  unsigned char data = 0;
  if (!i2c_poll_status(i2c_info_p, L2K_I2C_STATUS_BUSY))
  return L2K_I2C_RET_TIMEOUT;
  data = (slave_addr << 1) | ((L2K_I2C_DIRECTION_READ == direction) ? 1 : 0);
  reg_write_8(data , i2c_base + L2K_I2C_DATA_OFFSET);
  i2c_cmd_start(i2c_info_p);
  if (!i2c_poll_status(i2c_info_p, L2K_I2C_STATUS_TIP))
  return L2K_I2C_RET_TIMEOUT;
  return L2K_I2C_RET_OK;
}


4.   这时就开始接触到硬件部分了
    reg_write_8(data , i2c_base + L2K_I2C_DATA_OFFSET);
    这句直接对内存赋值,赋值的地址是在头文件中选择的基址,如,
#define I2C_BASE_ADDR 0xbfe01000
#define I2C0_OFF   0x0  //0x8 for I2C1, [11]bit of 1
#define I2C0_BASE CKSEG1ADDR(I2C0_BASE_ADDR + I2C0_OFF)

    5. 所以,小结一下就是,首先要按照芯片的手册,获得主要的外围设备访问地址以及控制逻辑。基本上都是大力出奇迹,用直接读写地址和寄存器数据更新的方法。然后,按照RTT的struct 结构体要求,封装控制函数,通过注册函数关联起来。
    6. 驱动编写完成,需要在ENV环境启动menuconfig先构建工程,使用i2c必须选择这个driver,否则在link的过程中显示无法找到 rt_i2c_bus_device_register(),
在配置好环境后,直接输入scons就生产二进制文件。
然后按照pmon管理的方式加载到内存,运行就可以显示结果了。
硬件框架
      硬件主要包括龙芯L2K开发板,12V-10A直流电源,驱动风扇和电机,半导体制冷片。
      调试引脚是RS232_UART_TX=59,RS232_UART_RX=60,
      温度传感器引脚I2C1_SDA=3,I2C1_CLK=5,
      冰箱开关控制 GPIO_07=7,
      公用引脚是P3V3=1,GND=9,
硬件框架图如下。
引脚的编号图,
采用的主要元件,
温度传感器
组装的半导体制冷片,
元件的整体连接图,


软件框架说明
      软件采用RTT实现主要线程管理,并且实现基本的闭环控制,并具备升级到智能节能方案。
方案框图如下,

流程图如下,

软件模块说明
      软件部分包括2个并发的线程,第一个线程实现闭环的温度控制,第二个线程实现智能记录和节能管理。
     使用RTT,就需要使用thread功能,先创建两个thread-entry,然后启动线程管理就可以了。进入RTT编程阶段就非常简单和逻辑清晰了。

演示效果
使用scons编译通过,
复制文件到U盘G:
程序启动直接进入缺省的rtt文件,在SSD硬盘,
启动后按C键,进入PMON,
按照从u盘加载load之后运行的方式执行,进入smart_fridge的程序循环。



代码地址代码在BSP目录下,直接scons就可以了。 Fridge.rar (1.62 MB)
文档:
RT-Thread应用创新设计大赛作品-智能冰箱.rar (950.11 KB)
参考代码
主函数main()参考代码如下:
int main(int argc, char** argv)
{   
    //rt_uint8_t temp[2] = {0, 0};
    rt_thread_t tem_thread, eng_thread;
    rt_uint8_t temp[6];
    float *cur_temp;
    rt_kprintf("Hi, this is Smart Fridge!\n");
    int cnt;
    cnt=10;
    //fridge_init();   
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(TEM_I2C_BUS_NAME);
    if (i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s device!\n", TEM_I2C_BUS_NAME);
    }
    else
    {
        write_reg(i2c_bus, TEM_NORMAL_CMD, temp);
        rt_thread_mdelay(400);

        temp[0] = 0x08;
        temp[1] = 0x00;
        write_reg(i2c_bus, TEM_CALIBRATION_CMD, temp);
        rt_thread_mdelay(400);
        initialized = RT_TRUE;
    }
    //cur_temp=cur_tmp_entry();
    tem_thread = rt_thread_create("tem_trd",
                                  cur_tmp_entry,
                                  "temp_cur",
                                  512,
                                  RT_THREAD_PRIORITY_MAX / 2,
                                  20);
    if (tem_thread != RT_NULL)
    {
    rt_thread_startup(tem_thread);
    }      

    eng_thread = rt_thread_create("eng_trd",
                                  energy_saving_entry,
                                  "eng_sav",
                                  512,
                                  RT_THREAD_PRIORITY_MAX / 2,
                                  20);                                 
    if (eng_thread != RT_NULL)
    {
    rt_thread_startup(eng_thread);
    }                                 
    return 0;
}





使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

102

帖子

1

粉丝