全志H616开发(3)——基于官方外设开发(2)

基于官方外设开发(2)

一、SG90舵机开发

  1. 舵机基本介绍
    如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM。信号控制用处:垃圾桶项目开盖 用、智能小车的全比例转向、摄像头云台、机械臂等。常见的有0-90°、0-180°、0-360°。 在这里插入图片描述
  2. 怎么控制转角
    • 向黄色信号线“灌入”PWM信号。
    • PWM波的频率不能太高,50hz,即周期=1/频率=1/50=0.02s,20ms左右数据:
    • 不同的PWM波形对应不同的旋转角度,以20ms为周期,50hz为频率的PWM波。
    • 时器需要定时20ms,关心的单位0.5ms, 20ms = 0.5ms * 40:在这里插入图片描述
      在这里插入图片描述
  3. Linux定时器
    • 分析:实现定时器,通过itimerval结构体以及函数setitimer产生的信号,系统随之使用signal信号处理。
    • 函数来处理产生的定时信号。从而实现定时器。
    • 先看itimerval的结构体
    • setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值。
    • which:三种类型
    • ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM。
    • ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
    • ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
    • 很明显,这边需要捕获对应的信号进行逻辑相关处理 signal(SIGALRM,signal_handler);
    • 返回说明:成功执行时,返回0。失败返回-1
    struct itimerval
    {
    /* Value to put into `it_value' when the timer expires. */
    struct timeval it_interval;
    /* Time to the next timer expiration. */
    struct timeval it_value;
    };
    
    //it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置
    //it_value:程序跑到这之后,多久启动定时器
    
    struct timeval
    {
    __time_t tv_sec; /* Seconds. */
    __suseconds_t tv_usec; /* Microseconds. */
    };
    int setitimer (__itimer_which_t __which,
    const struct itimerval *__restrict __new,
    struct itimerval *__restrict __old)
    
    • 实现代码:
    /*该代码实现的功能是: 1s后开启定时器,然后每隔1s向终端打印hello。*/
    #include <stdio.h>
    #include <sys/time.h>
    #include <stdlib.h>
    #include <signal.h>
    static int cnt;
    
    void sig_handler(int num)
    {
    	cnt++;
    	if(cnt == 2000) {
    		cnt = 0;
    		printf("Hello\n");
    	}
    }
    
    int main(void)
    {
    	struct itimerval itv;
    
    	//设定定时时间
    	itv.it_interval.tv_sec = 0;
    	itv.it_interval.tv_usec = 500;
    	//设定开始生效,启动定时器的时间
    	itv.it_value.tv_sec = 1;
    	itv.it_value.tv_usec = 0;
    
    	//设定定时方式
    	if(-1 == setitimer(ITIMER_REAL,&itv,NULL)){
    		perror("error");
    		exit(-1);
    	}
    	signal(SIGALRM, sig_handler);
    
    	while(1);
    
    	return 0;
    }
    
    • 这种方法需要注意的是,一个进程只能创建一个定时器
  4. SG90编程实现:键盘输入不同的值,让舵机转动,软件PWM实现
    #include <stdio.h>
    #include <sys/time.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <wiringPi.h>
    static int cnt;
    int jd = 0;
    
    #define SG90 5
    
    void sig_handler(int num)
    {
    	if(cnt <= jd) {
    		digitalWrite(SG90, HIGH);
    	}
    	else {
    		digitalWrite(SG90, LOW);
    	}
    
    	if(cnt == 40) {
    		cnt = 0;
    	}
    	cnt++;
    }
    
    int main(void)
    {
    	struct itimerval itv;
    
    	jd = 0;
    	wiringPiSetup();
    	pinMode(SG90, OUTPUT);
    
    	itv.it_interval.tv_sec = 0;
    	itv.it_interval.tv_usec = 500;
    	itv.it_value.tv_sec = 1;
    	itv.it_value.tv_usec = 0;
    
    	//设定定时方式
    	if(-1 == setitimer(ITIMER_REAL,&itv,NULL)){
    		perror("error");
    		exit(-1);
    	}
    	signal(SIGALRM, sig_handler);
    
    	while(1)
    	{
    		printf("input jd 1-0 2-45 3-90 4-135\n");
    		scanf("%d",&jd);
    	}
    
    	return 0;
    }
    

二、OLED屏应用-IIC协议

  1. OLED屏幕在这里插入图片描述
  2. Orangepi的IIC接口
    • 由 26pin 的原理图可知, Orange Pi Zero 2 可用的 i2c 为 i2c3在这里插入图片描述
    • 启动 linux 系统后, 先确认下/dev 下存在 i2c-3 的设备节点
    • 从命令运行结果能观察到系统支持I2C-3和I2C-5的驱动,而H616的外设我们看到只有一个IIC接口,用的是IIC-3
    • Linux一切皆文件,每个硬件设备“对应”一个文件,由驱动程序提供映射在这里插入图片描述
  3. 开始测试 i2c, 首先安装 i2c-tools
    • sudo apt-get install i2c-tools在这里插入图片描述
  4. 实战OLED屏幕开发
    /*
     * Copyright (c) 2015, Vladimir Komendantskiy
     * MIT License
     *
     * SSD1306 demo of block and font drawing.
     */
    
    //
    // fixed for OrangePiZero by HypHop
    //
    
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <stdint.h>
    
    #include "oled.h"
    #include "font.h"
    
    int oled_demo(struct display_info *disp) {
    	int i;
    	char buf[100];
    
    	//putstrto(disp, 0, 0, "Spnd spd  2468 rpm");
    	//	oled_putstrto(disp, 0, 9+1, "Spnd cur  0.46 A");
    	oled_putstrto(disp, 0, 9+1, "Welcome       to");
    	disp->font = font1;
    	//	oled_putstrto(disp, 0, 18+2, "Spnd tmp    53 C");
    	oled_putstrto(disp, 0, 18+2, "----OrangePi----");
    	disp->font = font2;
    	//	oled_putstrto(disp, 0, 27+3, "DrvX tmp    64 C");
    	oled_putstrto(disp, 0, 27+3, "This is 0.96OLED");
    	oled_putstrto(disp, 0, 36+4, "");
    	oled_putstrto(disp, 0, 45+5, "");
    	disp->font = font1;
    	//	oled_putstrto(disp, 0, 54, "Total cur  2.36 A");
    	oled_putstrto(disp, 0, 54, "*****************");
    	oled_send_buffer(disp);
    
    	disp->font = font3;
    	for (i=0; i<100; i++) {
    		sprintf(buf, "Spnd spd  %d rpm", i);
    		oled_putstrto(disp, 0, 0, buf);
    		oled_putstrto(disp, 135-i, 36+4, "===");
    		oled_putstrto(disp, 100, 0+i/2, ".");
    		oled_send_buffer(disp);
    	}
    	//oled_putpixel(disp, 60, 45);
    	//oled_putstr(disp, 1, "hello");
    
    return 0;
    }
    
    void show_error(int err, int add) {
    	//const gchar* errmsg;
    	//errmsg = g_strerror(errno);
    	printf("\nERROR: %i, %i\n\n", err, add);
    	//printf("\nERROR\n");
    }
    
    void show_usage(char *progname) {
    	printf("\nUsage:\n%s <I2C bus device node >\n", progname);
    }
    
    int main(int argc, char **argv) {
    	int e;
    	char filename[32];
    	struct display_info disp;
    
    	if (argc < 2) {
    		show_usage(argv[0]);
    		
    		return -1;
    	}
    
    	memset(&disp, 0, sizeof(disp));
    	sprintf(filename, "%s", argv[1]);
    	disp.address = OLED_I2C_ADDR;
    	disp.font = font2;
    
    	e = oled_open(&disp, filename);
    
    	if (e < 0) {
    		show_error(1, e);
    	} else {
    		e = oled_init(&disp);
    	if (e < 0) {
    		show_error(2, e);
    	} else {
    		printf("---------start--------\n");
    		if (oled_demo(&disp) < 0)
    			show_error(3, 777);
    			printf("----------end---------\n");
    		}
    	}
    
    	return 0;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值