189 8069 5689

go语言分析I2c波形,golang i2c

使用PIC24F上的bus I2C连接6脚液晶LCD进行显示(主要是SDA, SCL的C语言编程问题)?

i2c有现成的库,你在lcd的网站上或者是单片机网上可以下到,然后按照lcd的pdf对它初始话,我给个简单的几个函数,可以实现初始化

成都创新互联是专业的鞍山网站建设公司,鞍山接单;提供网站制作、网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行鞍山网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

下面3个就是lcd的初始化配置,下面3个函数是找到的i2c库代码,你按照这个lcd的pdf进行对应的修改就行

#define pcf8576 0x70

ISendByte(pcf8576,0x48); //设置背级方式

ISendByte(pcf8576,0x70); //设置闪烁

ISendByte(pcf8576,0x60); //设置器件子地址

你可以把lcd当成一个接口,向这个接口地址发送数据就可以让它进行对应的操作,这个是我写过的lcd显示模块,pcf8576是lcd的地址,这个你可以在lcd的pdf里找到

显示的话,就是向对应的lcd寄存器写入数据,比如要显示第一个数字,就是将lcd的显示数据里修改,然后发送显示数据到lcd的对应寄存器里,下面的lcdnum就是8576的显示数据数组

void Refresh_LCD()

{

ISendByte(pcf8576,0x60);

ISendStr(pcf8576,0x00,lcdnum,9);

}

void Start_I2c()

{

SDA=1; /*发送起始条件的数据信号*/

_Nop();

SCL=1;

_Nop(); /*起始条件建立时间大于4.7us,延时*/

_Nop();

_Nop();

_Nop();

_Nop();

SDA=0; /*发送起始信号*/

_Nop(); /* 起始条件锁定时间大于4μs*/

_Nop();

_Nop();

_Nop();

_Nop();

SCL=0; /*钳住I2C总线,准备发送或接收数据 */

_Nop();

_Nop();

}

/*******************************************************************

结束总线函数

函数原型: void Stop_I2c();

功能: 结束I2C总线,即发送I2C结束条件.

********************************************************************/

void Stop_I2c()

{

SDA=0; /*发送结束条件的数据信号*/

_Nop(); /*发送结束条件的时钟信号*/

SCL=1; /*结束条件建立时间大于4μs*/

_Nop();

_Nop();

_Nop();

_Nop();

_Nop();

SDA=1; /*发送I2C总线结束信号*/

_Nop();

_Nop();

_Nop();

_Nop();

}

bit ISendByte(unsigned char sla,unsigned char c)

{

Start_I2c(); /*启动总线*/

SendByte(sla); /*发送器件地址*/

if(ack==0)

return(0);

SendByte(c); /*发送数据*/

if(ack==0)

return(0);

Stop_I2c(); /*结束总线*/

return(1);

}

【原创】树莓派3B开发Go语言(四)-自写库实现pwm输出

在前一小节中介绍了点亮第一个LED灯,这里我们准备进阶尝试下,输出第一段PWM波形。(PWM也就是脉宽调制,一种可调占空比的技术,得到的效果就是:如果用示波器测量引脚会发现有方波输出,而且高电平、低电平的时间是可调的。)

这里爪爪熊准备写成一个golang的库,并开源到github上,后续更新将直接更新到github中,如果你有兴趣可以和我联系。 github.com/dpawsbear/bear_rpi_go

我在很多的教程中都看到说树莓派的PWM(硬件)只有一个GPIO能够输出,就是 GPIO1 。这可是不小的打击,因为我想使用至少四个 PWM ,还是不死心,想通过硬件手册上找寻蛛丝马迹,看看究竟怎么回事。

手册上找寻东西稍等下讲述,这里先提供一种方法测试 树莓派3B 的 PWM 方法:用指令控制硬件PWM。

这里通过指令的方式掌握了基本的pwm设置技巧,决定去翻一下手册看看到底PWM怎么回事,这里因为没有 BCM2837 的手册,根据之前文章引用官网所说, BCM2835 和 BCM2837 应该是一样的。这里我们直接翻阅 BCM2835 的手册,直接找到 PWM 章节。找到了如下图:

图中可以看到在博通的命名规则中 GPIO 12、13、18、19、40、41、45、52、53 均可以作为PWM输出。但是只有两路PWM0 PWM1。根据我之前所学知识,不出意外应该是PWM0 和 PWM1可以输出不一样的占空比,但是频率应该是一样的。因为没有示波器,暂时不好测试。先找到下面对应图:

根据以上两个图对比可以发现如下规律:

对照上面的表可以看出从 BCM2837 中印出来的能够使用在PWM上的就这几个了。

为了验证个人猜想是否正确,这里先直接使用指令的模式,模拟配置下是否能够正常输出。

通过上面一系列指令模拟发现,(GPIO1、GPIO26)、(GPIO23、GPIO24)是绑定在一起的,调节任意一个,另外一个也会发生变化。也即是PWM0、PWM1虽然输出了两路,可以理解成两路其实都是连在一个输出口上。这里由于没有示波器或者逻辑分析仪这类设备(仅有一个LED灯),所以测试很简陋,下一步是使用示波器这类东西对频率以及信号稳定性进行下测试。

小节:树莓派具有四路硬件输出PWM能力,但是四路中只能输出两个独立(占空比独立)的PWM,同时四路输出的频率均是恒定的。

上面大概了解清楚了树莓派3B的PWM结构,接下来就是探究如何使用Go语言进行设置。

因为拿到了手册,这里我想直接操作寄存器的方式进行设置,也是顺便学习下Go语言处理寄存器的过程。首先需要拿到pwm 系列寄存器的基地址,但是翻了一圈手册,发现只有偏移,没有找到基地址。

经过了一段时间的努力后,决定写一个 树莓派3B golang包开源放在github上,只需要写相关程序进行调用就可以了,以下是相关demo(pwm)(在GPIO.12 上输出PWM波,放上LED灯会有呼吸灯的效果,具体多少频率还没有进行测试)

以下是demo(pwm) 源码

怎么从I2C总线读数据

i2c有其协议的,我当时从不会到掌握其协议用了一阵子,就是狂读协议和例程

我把当时用非斯卡尔单片机读i2c mems传感器的历程写在下面

#include hidef.h

#include "derivative.h"

#define IIC_SDA_CTL PTCDD_PTCDD1

#define IIC_SDA_DAT PTCD_PTCD1

#define IIC_SCL_CTL PTCDD_PTCDD0

#define IIC_SCL_DAT PTCD_PTCD0

#define IIC_MST_HI 0

#define IIC_MST_LO 1

void IIC_Start(void);

void IIC_Restart(void);

void IIC_Stop(void);

byte IIC_SendByte(byte);

byte IIC_Read(byte *, byte);

byte IIC_Write(byte *, byte);

void IIC_Delay(void);

void IIC_Delay(void)

{

byte i;

for (i=0;i8;i++) {}

}

//==============================================================

// Master generates a START condition on IIC bus

//==============================================================

void IIC_Start(void)

{

IIC_SDA_CTL = IIC_MST_HI;

IIC_SCL_CTL = IIC_MST_HI;

IIC_Delay();

IIC_SDA_CTL = IIC_MST_LO;

IIC_SDA_DAT = 0;

IIC_Delay();

IIC_SCL_CTL = IIC_MST_LO;

IIC_SCL_DAT = 0;

IIC_Delay();

}

//==============================================================

// Master generates a RESTART condition on IIC bus

//==============================================================

void IIC_Restart(void)

{

IIC_SDA_CTL = IIC_MST_HI; //SDA back to high while SCL remain in low

IIC_Delay();

IIC_SCL_CTL = IIC_MST_HI; //SCL back to high, bus idle now

IIC_Delay();

IIC_SDA_CTL = IIC_MST_LO; //RESTART condition occur

IIC_Delay();

IIC_SCL_CTL = IIC_MST_LO; //SCL to low for standby

IIC_Delay();

}

//==============================================================

// Master generates a STOP condition on IIC bus

//==============================================================

void IIC_Stop(void)

{

IIC_SDA_CTL = IIC_MST_LO; //make sure SDA is low

IIC_Delay();

IIC_SCL_CTL = IIC_MST_HI; //I2C_SCL_CTL go to high first

IIC_Delay();

IIC_SDA_CTL = IIC_MST_HI; //I2C_SDA_CTL have low-high transition while SCL is high

IIC_Delay();

}

//==============================================================

// Master send out a byte of data and return with ACK/NACK

// return with 0x00 if ACK received

// return with 0xff if NACK received

//==============================================================

byte IIC_SendByte(byte outDat)

{

byte bit;

//send out 8-bit data

for (bit=0;bit8;bit++) {

if (outDat0x80)

IIC_SDA_CTL = IIC_MST_HI;

else

IIC_SDA_CTL = IIC_MST_LO;

IIC_Delay();

IIC_SCL_CTL = IIC_MST_HI;

IIC_Delay();

IIC_SCL_CTL = IIC_MST_LO;

outDat = 1;

}

//check for the ACK/NACK

IIC_SDA_CTL = IIC_MST_HI; //master release SDA

IIC_Delay();

IIC_SCL_CTL = IIC_MST_HI; //master send a clock

IIC_Delay();

if (IIC_SDA_DAT) bit = 0xff; //NACK

else bit = 0; //ACK

IIC_SCL_CTL = IIC_MST_LO;

IIC_Delay();

return(bit);

}

//==============================================================

// Master write a string of bytes through IIC us

// Return with 0x00 if successful

// Return with 0xff if failed

//==============================================================

byte IIC_Write(byte *buff, byte total)

{

while (total) {

if (IIC_SendByte(*buff++)) //get NACK after data byte out

return(0xff); //abort

total--;

//__RESET_WATCHDOG(); //needed only for EEPROM byte-program

}

return(0);

}

//==============================================================

// Master read a byte of data and set ACK/NACK

// return with data read

//==============================================================

byte IIC_ReadByte(byte ackFlag)

{

byte bit, dat;

IIC_SDA_CTL = IIC_MST_HI; //make sure master release SDA

//read 8 bits sof data

for (bit=0;bit8;bit++) {

dat = 1;

IIC_SCL_CTL = IIC_MST_HI;

IIC_Delay();

if (IIC_SDA_DAT) //read back data

dat |= 0x01;

IIC_SCL_CTL = IIC_MST_LO;

IIC_Delay();

}

//echo with ACK/NACK

if (ackFlag==0)

IIC_SDA_CTL = IIC_MST_LO; //echo back ACK

else

IIC_SDA_CTL = IIC_MST_HI; //echo back NACK

IIC_Delay();

IIC_SCL_CTL = IIC_MST_HI;

IIC_Delay();

IIC_SCL_CTL = IIC_MST_LO;

IIC_Delay();

return(dat);

}

//==============================================================

// Master read a string of data bytes through IIC us

//==============================================================

byte IIC_Read(byte *buff, byte total)

{

byte count;

if (total==0) return(0);

if (total==1) { //read one byte only

buff[0] = IIC_ReadByte(1); //NACK after read

return(1);

}

else { //read more than one bytes

count = 0;

while(total1) {

IIC_Delay();

buff[count++] = IIC_ReadByte(0); //ACK after read

total--;

__RESET_WATCHDOG();

}

IIC_Delay();

buff[count++] = IIC_ReadByte(1);

return(count);

}

}

然后你去网上搜索iic总线协议,把协议多读几遍慢慢就会了~~要不你把邮箱给我我发给你.总之很简单的 不用害怕,学学就会了


文章标题:go语言分析I2c波形,golang i2c
路径分享:http://cdxtjz.cn/article/heijgo.html

其他资讯