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:
进入该路径后,使用
命令编译wiringPi软件库,使系统识别软件库的环境变量路径:
搞定之后,就可以使用常见的wiringPi函数如pinMode()、digitalWrite()等,可以通过
命令查看软件库是否安装成功:
操作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接口,并使用
命令检测DS3231的存在:
这个0x68便是DS3231的从机地址号。然后就可以用i2c_fd=wiringPiI2CSetup(0x68)函数启用I2C0总线驱动DS3231日历时钟外设。
可以用
命令将DS3231的数据导出:
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):