创客神器NanoPi
直播中

donatello1996

9年用户 737经验值
擅长:MEMS/传感技术
私信 关注
[经验]

【NanoPi K1 Plus试用体验】驱动DHT11和DS3231

    NanoPi系列的UbuntuCore系统中大多支持wiringPi软件库,这个软件库就是对GPIO相关寄存器操作的一级封装,类似于STM32的标准库和LL库,可以在系统中直接通过代码操作GPIO驱动各种外设,如I2C SPI UART等。不过NanoPi系列大部分的开发板都是针对Linux系统应用操作的,对GPIO操作的实时性和多样性无法跟一般的ARM单片机相提并论,wiringPi可以操作的I2C、SPI、UART、PWM等外设接口都极其有限,只有1~2个接口可以调用,并且功能也非常单一,这个是由ARM Cortex-A内核决定的。
    NanoPi的系统自带了wiringPi软件库,软件库的位置就在SSH登录的默认目录/root/WiringNP:
58.JPG
进入该路径后,使用
  1. ./build
命令编译wiringPi软件库,使系统识别软件库的环境变量路径:
51.JPG
搞定之后,就可以使用常见的wiringPi函数如pinMode()、digitalWrite()等,可以通过
  1. gpio readall
命令查看软件库是否安装成功:
59.jpg
    操作DHT11的方法就是简单地操作GPIO的输入及输出,网上大多都有教程可以参考,我这里也是直接贴出代码供大家参考:
int DHT11_Read()
{
    unsigned char lststate=HIGH,counter=0,j=0,i;
    for(i=0;i<5;i++)
        dht11_val=0;

    pinMode(DHT11PIN,OUTPUT);
    digitalWrite(DHT11PIN,LOW);
    delay(18);
    digitalWrite(DHT11PIN,HIGH);
    delayMicroseconds(40);

    pinMode(DHT11PIN,INPUT);
    for(i=0;i<85;i++)
    {
        counter=0;
        while(digitalRead(DHT11PIN)==lststate)
        {
            counter++;
            delayMicroseconds(1);
            if(counter==255)
                break;
        }
        lststate=digitalRead(DHT11PIN);

        if(counter==255)break;
        if((i>=4)&&(i%2==0))
        {
            dht11_val[j/8]<<=1;
            if(counter>16)
                dht11_val[j/8]|=1;
            j++;
        }
    }
    if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])&0xFF)))
        return 0;

    return 1;
}

这里需要注意的是,DHT11对于主机的命令时序要求非常严格,初始化器件所用的18毫秒拉低、40微秒拉高,只能大不能小,并且也不能延时太长导致主线程响应缓慢。当DHT11输出的四个数据校验和正确之后,该组数据的第1个和第3个数据就能分别作为温度和湿度数据输出。

然后是驱动I2C器件DS3231,驱动该器件之前需要先确认DS3231器件与NanoPi正常通信,使用DS3231连接I2C0接口,并使用
  1. i2cdetect -y 0

命令检测DS3231的存在:
60.jpg
这个0x68便是DS3231的从机地址号。然后就可以用i2c_fd=wiringPiI2CSetup(0x68)函数启用I2C0总线驱动DS3231日历时钟外设。
可以用

  1. i2cdemp -y 0 0x68
命令将DS3231的数据导出:
61.jpg
wiringPiI2CReadReg8(int fd,unsigned char reg)是读取8位寄存器的数据,wiringPiI2CWriteReg8(int fd,unsigned char reg,unsigned char data)是写入8位寄存器数据,DS3231的0~6号这7个寄存器分别代表秒、分、时、星期、日、月、年的实时日历数据。

查看代码:
    wiringPiSetup();
    i2c_fd=wiringPiI2CSetup(0x68);
    wiringPiI2CWriteReg8(i2c_fd,6,BYTE_to_BCD(18));
    wiringPiI2CWriteReg8(i2c_fd,5,BYTE_to_BCD(9));
    wiringPiI2CWriteReg8(i2c_fd,4,BYTE_to_BCD(9));
    wiringPiI2CWriteReg8(i2c_fd,3,BYTE_to_BCD(7));
    wiringPiI2CWriteReg8(i2c_fd,2,BYTE_to_BCD(23));
    wiringPiI2CWriteReg8(i2c_fd,1,BYTE_to_BCD(50));
    wiringPiI2CWriteReg8(i2c_fd,0,BYTE_to_BCD(0));
    while(1)
    {

        //V4l2_Grab();
        //Yuyv_2_RGB888(buffers,frame_buffer);
        //Encode_Jpeg(frame_buffer,IMAGEWIDTH,IMAGEHEIGHT,"1.jpg");
        //LCD_Show_Buffer((unsigned char*)"/dev/fb0",640,480,frame_buffer);
        //Show_Chinese_64(384,800,0,0xff00ffff,0);
        //LCD_Effect();

        result=DHT11_Read();
        if(result==0)
        {
            Show_Chinese_64(0,0,0,0xff00ffff,0);
            Show_Chinese_64(64,0,0,0xff00ffff,2);
            Show_ASCII_64(128,0,0,0xff00ffff,':');
            Show_ASCII_64(160,0,0,0xff00ffff,dht11_val[2]/10+'0');
            Show_ASCII_64(192,0,0,0xff00ffff,dht11_val[2]%10+'0');

            Show_Chinese_64(0,64,0,0xff00ffff,1);
            Show_Chinese_64(64,64,0,0xff00ffff,2);
            Show_ASCII_64(128,64,0,0xff00ffff,':');
            Show_ASCII_64(160,64,0,0xff00ffff,dht11_val[0]/10+'0');
            Show_ASCII_64(192,64,0,0xff00ffff,dht11_val[0]%10+'0');
            LCD_Effect();
        }

        sec=wiringPiI2CReadReg8(i2c_fd,0);
        sec=BCD_to_BYTE(sec);

        min=wiringPiI2CReadReg8(i2c_fd,1);
        min=BCD_to_BYTE(min);

        hour=wiringPiI2CReadReg8(i2c_fd,2);
        hour=BCD_to_BYTE(hour);

        day=wiringPiI2CReadReg8(i2c_fd,3);

        date=wiringPiI2CReadReg8(i2c_fd,4);
        date=BCD_to_BYTE(date);

        month=wiringPiI2CReadReg8(i2c_fd,5);
        month=BCD_to_BYTE(month);

        year=wiringPiI2CReadReg8(i2c_fd,6);
        year=BCD_to_BYTE(year);

        Show_ASCII_64(0,128,0,0xff00ffff,year/10+'0');
        Show_ASCII_64(32,128,0,0xff00ffff,year%10+'0');
        Show_ASCII_64(64,128,0,0xff00ffff,'/');
        Show_ASCII_64(96,128,0,0xff00ffff,month/10+'0');
        Show_ASCII_64(128,128,0,0xff00ffff,month%10+'0');
        Show_ASCII_64(160,128,0,0xff00ffff,'/');
        Show_ASCII_64(192,128,0,0xff00ffff,date/10+'0');
        Show_ASCII_64(224,128,0,0xff00ffff,date%10+'0');

        Show_ASCII_64(0,192,0,0xff00ffff,hour/10+'0');
        Show_ASCII_64(32,192,0,0xff00ffff,hour%10+'0');
        Show_ASCII_64(64,192,0,0xff00ffff,':');
        Show_ASCII_64(96,192,0,0xff00ffff,min/10+'0');
        Show_ASCII_64(128,192,0,0xff00ffff,min%10+'0');
        Show_ASCII_64(160,192,0,0xff00ffff,':');
        Show_ASCII_64(192,192,0,0xff00ffff,sec/10+'0');
        Show_ASCII_64(224,192,0,0xff00ffff,sec%10+'0');

        LCD_Effect();

    }

查看效果(昨天录制的GIF):
2.gif

更多回帖

×
20
完善资料,
赚取积分