树莓派控制230EVM是通过I2C和Parallel RGB,这里主要介绍I2C。

由于官网的例程是python语言,想要改成C语言,重点在于I2C函数的写。

以下代码为读取adc电源的例程。(16位)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>int i2c_write_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char *data_wr = NULL;int ret = -1;data_wr = (unsigned char *)malloc(len + 2);if (!data_wr) {printf("%s, malloc failed!\n", __func__);return -1;}data_wr[0] = reg_addr / 0xff;data_wr[1] = reg_addr % 0xff;memcpy(&data_wr[2], data, len);ioctl(fd, I2C_SLAVE, slave_addr);ioctl(fd, I2C_TIMEOUT, 1);ioctl(fd, I2C_RETRIES, 1);ret = write(fd, data_wr, len+2);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}printf("%s, write ok, num: %d\n", __func__, ret); //if (data_wr != NULL) {free(data_wr);data_wr = NULL;}return ret;
}int i2c_read_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char addr[2] = { 0 };int ret = -1;ioctl(fd, I2C_SLAVE, slave_addr);ioctl(fd, I2C_TIMEOUT, 1);ioctl(fd, I2C_RETRIES, 1);addr[0] = reg_addr / 0xff;addr[1] = reg_addr % 0xff;ret = write(fd, addr, 2);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}ret = read(fd, data, len);if (ret < 0) {printf("%s, read failed, ret: 0x%x\n", __func__, ret);return ret;}// printf("%s, read ok, num: %d\n", __func__, ret);return ret;
}float adc_read_votage(char * dev, unsigned short slave_addr, unsigned short reg_addr, int len)
{int fd = -1;unsigned char buf[2] = { 0 };float ret = 0.0;fd = open(dev, O_RDWR);if (fd < 0) {printf("%s, open failed!\n", __func__);return -1;}if(i2c_read_bytes(fd, slave_addr, reg_addr, buf, len) < 0){printf("%s, i2c read failed!\n", __func__);return -1;}// calculate votage valueret = (float)((buf[0]<<4) + (buf[1] >> 4))/255*3.4*20.32/4.32;close(fd);return ret;
}int main(void){int fd = -1;int len = 2;int i = 0;float value = 0.0;fd = open("/dev/i2c-7", O_RDWR);if (fd < 0) {printf("%s, open failed!\n", __func__);return -1;close(fd);return 0;}

原本的python程序如下。(调用的函数及其他文件未附上,可在官网下载查看)

本代码是最简短完成该功能的。(注释部分可恢复)

import struct
import timefrom enum import Enumimport sys, os.path
python_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
sys.path.append(python_dir)
from api.dlpc343x_xpr4 import *
from api.dlpc343x_xpr4_evm import *
from linuxi2c import *
import i2cclass Set(Enum):Disabled = 0Enabled = 1def main():'''Initializes the Raspberry Pi's GPIO lines to communicate with the DLPDLCR230NPEVM,and configures the DLPDLCR230NPEVM to project RGB666 parallel video input received from the Raspberry Pi.It is recommended to execute this script upon booting the Raspberry Pi.'''gpio_init_enable = True          # Set to FALSE to disable default initialization of Raspberry Pi GPIO pinouts. TRUE by default.i2c_time_delay_enable = False    # Set to FALSE to prevent I2C commands from waiting. May lead to I2C bus hangups with some commands if FALSE.i2c_time_delay = 0.8             # Lowering this value will speed up I2C commands. Too small delay may lead to I2C bus hangups with some commands.protocoldata = ProtocolData()def WriteCommand(writebytes, protocoldata):'''Issues a command over the software I2C bus to the DLPDLCR230NP EVM.Set to write to Bus 7 by defaultSome commands, such as Source Select (splash mode) may perform asynchronous access to the EVM's onboard flash memory.If such commands are used, it is recommended to provide appropriate command delay to prevent I2C bus hangups.'''# print ("Write Command writebytes ", [hex(x) for x in writebytes])if(i2c_time_delay_enable): time.sleep(i2c_time_delay)i2c.write(writebytes)       returndef ReadCommand(readbytecount, writebytes, protocoldata):'''Issues a read command over the software I2C bus to the DLPDLCR230NP EVM.Set to read from Bus 7 by defaultSome commands, such as Source Select (splash mode) may perform asynchronous access to the EVM's onboard flash memory.If such commands are used, it is recommended to provide appropriate command delay to prevent I2C bus hangups.'''# print ("Read Command writebytes ", [hex(x) for x in writebytes])if(i2c_time_delay_enable): time.sleep(i2c_time_delay)i2c.write(writebytes) readbytes = i2c.read(readbytecount)return readbytes# ##### ##### Initialization for I2C ##### ###### register the Read/Write Command in the Python libraryDLPC343X_XPR4init(ReadCommand, WriteCommand)i2c.initialize()if(gpio_init_enable): InitGPIO()# ##### ##### Command call(s) start here ##### #####  print("Setting DLPC3436 Input Source to Raspberry Pi...")Summary = WriteDisplayImageCurtain(1,Color.Black)Summary = WriteSourceSelect(Source.ExternalParallelPort, Set.Disabled)#Summary = WriteInputImageSize(1920, 1080)print("Configuring DLPC3436 Source Settings for Raspberry Pi...")#Summary = WriteActuatorGlobalDacOutputEnable(Set.Enabled)#Summary = WriteExternalVideoSourceFormatSelect(ExternalVideoFormat.Rgb666)#Summary = WriteVideoChromaChannelSwapSelect(ChromaChannelSwap.Cbcr)#Summary = WriteParallelVideoControl(ClockSample.FallingEdge,  Polarity.ActiveHigh,  Polarity.ActiveLow,  Polarity.ActiveLow)#Summary = WriteColorCoordinateAdjustmentControl(0)#Summary, BitRate, PixelMapMode = ReadFpdLinkConfiguration()#Summary = WriteDelay(50)time.sleep(1)Summary = WriteDisplayImageCurtain(0,Color.Black)# ##### ##### Command call(s) end here ##### #####i2c.terminate()if __name__ == "__main__" : main()

此代码用C语言改写的如下,添加了投图的功能。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>#define slave_address 0x1b#define WriteDisplayImageCurtain    0x16   //0x01
#define WriteSourceSelect           0x05   // 0x01
#define WriteInputImageSize    0x60      //1920*1080
#define WriteActuatorGlobalDacOutputEnable 0xae   //0x01
#define WriteExternalVideoSourceFormatSelect  0x6d //0x02
#define WriteVideoChromaChannelSwapSelect   0x4d  //0x08
#define WriteParallelVideoControl  0x6B   //0x02
#define WriteColorCoordinateAdjustmentControl 0x86   //0x00
#define ReadFpdLinkConfiguration
#define WriteDelayint i2c_write_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char *data_wr = NULL;int ret = -1;data_wr = (unsigned char *)malloc(len + 1); //将申请的动态内存的“地址”复制给指针变量data_wrif (!data_wr) {printf("%s, malloc failed!\n", __func__);      return -1;}data_wr[0] = reg_addr;memcpy(&data_wr[1], data, len); //由data所指内存区域复制len个字节到data_wr所指内存区域ioctl(fd, I2C_SLAVE, slave_addr); //设置从机地址ioctl(fd, I2C_TIMEOUT, 1); //设置超时ioctl(fd, I2C_RETRIES, 1); //设置重试次数ret = write(fd, data_wr, len+1);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}// printf("%s, write ok, num: %d\n", __func__, ret);if (data_wr != NULL) {free(data_wr);data_wr = NULL;}return ret;
}int i2c_read_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char addr[2] = { 0 };int ret = -1;ioctl(fd, I2C_SLAVE, slave_addr);ioctl(fd, I2C_TIMEOUT, 1);ioctl(fd, I2C_RETRIES, 1);addr[0] = reg_addr / 0xff; addr[1] = reg_addr % 0xff;  ret = write(fd, addr, 2);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}ret = read(fd, data, len);if (ret < 0) {printf("%s, read failed, ret: 0x%x\n", __func__, ret);return ret;}// printf("%s, read ok, num: %d\n", __func__, ret);return ret;
}int main(void)
{int fd = -1;  //int len = 2;printf("Initializing Raspberry Pi Default Settings for DLPC3436...\n");system("raspi-gpio set 0 op pn");system("raspi-gpio set 1-27 ip pn");sleep(1);system("gpio drive 0 5");system("raspi-gpio set 22 op pn");system("raspi-gpio set 23 op pn");system("raspi-gpio set 0-21 a2 pn");system("raspi-gpio set 25 op dh");fd = open("/dev/i2c-7", O_RDWR);if (fd < 0) {printf("%s, open failed!\n", __func__);return -1;}unsigned char send_data[12] = {0x01,0x01,0x00,0x07,0x38,0x04,0x01,0x02,0x00,0x02,0x00,0x00};//unsigned char rec_data[1] = {0x00};printf("send regisiter data is %d !\n", send_data[0]);printf("Setting DLPC3436 Input Source to Raspberry Pi...\n");i2c_write_bytes(fd, slave_address, 0x16, &send_data[0], 1);  //WriteDisplayImageCurtain i2c_write_bytes(fd, slave_address, 0x05, &send_data[1], 2);   //WriteSourceSelect    //0x01 //i2c_write_bytes(fd, slave_address, 0x60, &send_data[2], 4);   //WriteInputImageSize  4byteprintf("Configuring DLPC3436 Source Settings for Raspberry Pi...\n");//i2c_write_bytes(fd, slave_address, 0xae, &send_data[6], 1);   //WriteActuatorGlobalDacOutputEnable     0xae   //0x01//i2c_write_bytes(fd, slave_address, 0x6d, &send_data[7], 1);   //WriteExternalVideoSourceFormatSelect   0x6d   //0x02//i2c_write_bytes(fd, slave_address, 0x4d, &send_data[8], 1);   //WriteVideoChromaChannelSwapSelect      0x4d   //0x08//i2c_write_bytes(fd, slave_address, 0x6b, &send_data[9], 1);   //WriteParallelVideoControl              0x6B   //0x02//i2c_write_bytes(fd, slave_address, 0x86, &send_data[10], 1);   //WriteColorCoordinateAdjustmentControl 0x86   //0x00//i2c_write_bytes(fd, slave_address, 0x16, &send_data[11], 1);   //ReadFpdLinkConfiguration              0x4c  //i2c_write_bytes(fd, slave_address, 0x16, &send_data[12], 1);   //WriteDelaysleep(1);i2c_write_bytes(fd, slave_address, 0x16, &send_data[11], 1);   //WriteDisplayImageCurtainprintf("write regisiter data successed !\n");system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 01.png");sleep(0.0001);system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 02.png");sleep(0.0001);system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 03.png");/sleep(0.0001);system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 04.png");sleep(0.0001);system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 05.png");//i2c_read_bytes(fd, 0x1b, 0x61, rec_data, 1);//printf("read regisiter data is %d !\n", rec_data[0]);close(fd);return 0;
}

清晰版如下。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>#define slave_address 0x1b#define WriteDisplayImageCurtain    0x16
#define WriteSourceSelect           0x05   int i2c_write_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char *data_wr = NULL;int ret = -1;data_wr = (unsigned char *)malloc(len + 1); //将申请的动态内存的“地址”复制给指针变量data_wrif (!data_wr) {printf("%s, malloc failed!\n", __func__);      return -1;}data_wr[0] = reg_addr;memcpy(&data_wr[1], data, len); //由data所指内存区域复制len个字节到data_wr所指内存区域ioctl(fd, I2C_SLAVE, slave_addr); //设置从机地址ioctl(fd, I2C_TIMEOUT, 1); //设置超时ioctl(fd, I2C_RETRIES, 1); //设置重试次数ret = write(fd, data_wr, len+1);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}// printf("%s, write ok, num: %d\n", __func__, ret);if (data_wr != NULL) {free(data_wr);data_wr = NULL;}return ret;
}int i2c_read_bytes(int fd, unsigned short slave_addr, unsigned short reg_addr, unsigned char *data, int len)
{unsigned char addr[2] = { 0 };int ret = -1;ioctl(fd, I2C_SLAVE, slave_addr);ioctl(fd, I2C_TIMEOUT, 1);ioctl(fd, I2C_RETRIES, 1);addr[0] = reg_addr / 0xff; //取高8位addr[1] = reg_addr % 0xff;  //取低8位ret = write(fd, addr, 2);if (ret < 0) {printf("%s, write failed, ret: 0x%x\n", __func__, ret);return ret;}ret = read(fd, data, len);if (ret < 0) {printf("%s, read failed, ret: 0x%x\n", __func__, ret);return ret;}// printf("%s, read ok, num: %d\n", __func__, ret);return ret;
}int main(void)
{int fd = -1;  printf("Initializing Raspberry Pi Default Settings for DLPC3436...\n");system("raspi-gpio set 0 op pn");system("raspi-gpio set 1-27 ip pn");sleep(1);system("gpio drive 0 5");system("raspi-gpio set 22 op pn");system("raspi-gpio set 23 op pn");system("raspi-gpio set 0-21 a2 pn");system("raspi-gpio set 25 op dh");fd = open("/dev/i2c-7", O_RDWR);if (fd < 0) {printf("%s, open failed!\n", __func__);return -1;}unsigned char send_data[3] = {0x01,0x01,0x00};printf("Setting DLPC3436 Input Source to Raspberry Pi...\n");i2c_write_bytes(fd, slave_address, WriteDisplayImageCurtain , &send_data[0], 1);  i2c_write_bytes(fd, slave_address, WriteSourceSelect, &send_data[1], 2);   sleep(1);i2c_write_bytes(fd, slave_address, WriteDisplayImageCurtain , &send_data[2], 1);   //system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 01.png");//sleep(1);//system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 02.png");//sleep(1);//system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 03.png");//sleep(1);//system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 04.png");//sleep(1);//system("sudo fbi -d /dev/fb0 -T 1 -noverbose -a 05.png");close(fd);return 0;
}

补充:

1.230EVM主控投影的芯片是DLP3436,官网下载的手册有记录每一个寄存器的功能,对应python中的函数。比如WriteDisplayImageCurtain ,在手册中是

所以我想要实现 python中的Summary = WriteDisplayImageCurtain(1,Color.Black),只需要将0X01写入0x16h寄存器即可。此函数只需写入8位,所以len=1。

2.有些函数是需要写入16位,比如WriteSourceSelect,在手册中看不出来

可在python中WriteSourceSelect具体函数中看出

setbits写了两次

def WriteSourceSelect(Source,  ExternalCalibrationEnable):"Selects the source of the image to be displayed."global SummarySummary.Command = "Write Source Select"Summary.Successful = Trueglobal ProtocolDataProtocolData.CommandDestination = 0;try:writebytes=list(struct.pack('B',5))ProtocolData.OpcodeLength = 1;packerinit()value = setbits(Source.value, 3, 0)writebytes.extend(list(struct.pack('B',value)))packerinit()value = setbits(ExternalCalibrationEnable.value, 1, 0)writebytes.extend(list(struct.pack('B',value)))_writecommand(writebytes, ProtocolData)except ValueError as ve:print("Exception Occurred ", ve)Summary.Successful == Falsefinally:return Summary

3.查看i2c总线上占用情况,可使用指令

i2cdump -f -y 7 0x1b

此处使用i2c-7,地址位0x1b

查看i2c地址,可使用指令

i2cdetect -y -a 7

4.运行程序之后,gpio引脚会发生变化,可通过以下指令查看 。

raspi-gpio get

5.强制改变i2c总线上某寄存器地址,可通过如下指令。

i2cset -f -y 7 0x1b 0x16 0x01

(i2c-7,地址0x1b,给0x16寄存器 写0x01 )

树莓派I2C控制DLPDLCR230NPEVM(python改写c)+注意事项相关推荐

  1. Raspberry Pi 4B树莓派 |#入门教程02# 树莓派GPIO控制(Python、C)

    树莓派GPIO编号方式 功能物理引脚 从左到右,从上到下:左边奇数,右边偶数:1-40 通过打开终端窗口并运行命令,可以在Raspberry Pi上访问方便的参考pinout.该工具由GPIO零 Py ...

  2. python控制树莓派led_Python 控制树莓派 GPIO 输出:控制 LED 灯

    树莓派 GPIO 控制输出的入门应该都是从控制 LED 灯开始的吧. 树莓派版本:Model 3B+ 树莓派系统:Raspbian Stretch with desktop and recommend ...

  3. python语音控制手机_python 树莓派语音控制普通台灯教程-Python 实用宝典

    阅读这篇文章前,这两篇文章可能对你会有所帮助: 利用智能音箱语音控制电脑开关机 (必读,否则你可能不知道我在说什么) 先看看效果: 完成这项有趣的实验,你所需要的材料有: 1.电烙铁 2.一个8050 ...

  4. Python rpi_ws281x 树莓派3B+ 控制灯带

    目录 Python rpi_ws281x 树莓派3B+ 控制灯带 python相关库安装 安装rpi_ws281x 代码编写 在文件中导入需要的类 初始化灯带 指定led灯并设置颜色 显示 运行 错误 ...

  5. python arduino i2c1602_Arduino通过I2C控制1602LCD显示屏

    Arduino通过I2C控制1602LCD显示屏 Arduino通过I2C控制1602LCD显示屏 [var1] 对比度太高,实际输出了文字但是无法看到,需要弄螺丝刀电位器,此外出错原因还有地址不对, ...

  6. 树莓派3B上用Python编程获取TSL2561光传感器数据

    在树莓派3B上用Python编程,通过I2C协议,利用TSL2561光照强度传感器获取环境光强 嵌入式萌新一枚,文章有解释不清或者错误的地方希望大佬能在评论区指正,感激不尽! 大概原理: 通过TSL2 ...

  7. [转载] 树莓派并行控制电机_使用由并行端口控制的软盘驱动步进电机的相机摇摄器

    参考链接: Python中的摩尔斯电码翻译器 树莓派并行控制电机 Here's a clever guy to watch, Ashish Derhgawen in New Delhi. He's a ...

  8. 刚闪电入门了树莓派:斩获不止Python,Linux,goLang,还有架构,格局...

    刚闪电入门了树莓派:斩获不止Python,Linux,goLang,还有架构,格局... 引子 如何以闪电的速度入门树莓派 获得了一个自己可掌控的Python程序 goLang说,我是来打酱油的! 我 ...

  9. 树莓派4B开机自启动Python程序,发送WIFI-IP至指定邮箱

    树莓派4B开机自启动Python程序,发送WIFI-IP至指定邮箱 树莓派开机自启动Python并发送IP地址到指定邮箱 环境 用Python发送邮件 获取WIFI的IP地址 整合发送邮件和获取WIF ...

  10. 实例4:树莓派GPIO控制舵机转动

    实例4:树莓派GPIO控制舵机转动 实验目的 通过背景知识学习,了解舵机的外观及基本运动方式. 了解四足机器人mini pupper腿部单个舵机的组成结构. 通过GPIO对舵机进行转动控制,熟悉PWM ...

最新文章

  1. 彻底解决tensorflow:ImportError: Could not find 'cudart64_90.dll' tensorflow安装
  2. mysql ndb 测试_.部署MYSQL集群 --测试
  3. mysql date time类型_数据库datetime是什么类型
  4. python官网怎么改中文-pycharm如何设置成中文
  5. 关中断解决任务间资源共享问题
  6. 怎样在CentOS 7.0上安装和配置VNC服务器
  7. Javascript-7对象:字符串、时间
  8. html 文本横竖切换,(横竖屏切换/强制横屏)CSS3 transform 怎样才能中心旋转?
  9. 使用Drools跟踪输出
  10. Atitit 面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)的区别和联系...
  11. 中南大学计算机学院夏令营2021,baihhh
  12. Hadoop集群环境下网络架构的设计与优化
  13. Oracle match_recognize
  14. python递归的方式打印九九乘法表
  15. Spring--超简单利用quartz实现定时作业
  16. 那些做Android开发必须知道的ADB命令
  17. 详解Autosar Arxml中的CANFD报文及格式
  18. 用c++编程六子棋游戏
  19. 90%程序员是这样写注释的...网友:精辟
  20. 多级放大电路(直接耦合、阻容耦合、变压器耦合、光电耦合)

热门文章

  1. lisp 圆柱螺旋线_AutoCAD.Lisp等距3D螺旋线
  2. 谷歌浏览器设置关闭搜索记录
  3. 400错误,The server cannot or will not process the request due to something that is perceived to be a c
  4. 操作系统基础(八)快表和多级页表
  5. 企业信息与网络通信安全 团队成员简历-叶俊
  6. vue+element_ui纯前端下载csv文件
  7. 《人月神话》经典摘录
  8. 小白IT:如何快速写出一个前端页面(网页),Python中如何使用前端语言什么是?JavaScript?BOMDOM?Bootstrap??
  9. 输入一个数判断一个数是不是质数,如果是质数输出“YES“,否则输出“NO“
  10. 计算机内存条能装几个,电脑能装几个内存条_一般电脑插几个内存条