i2c有現(xiàn)成的庫,你在lcd的網站上或者是單片機網上可以下到,然后按照lcd的pdf對它初始話,我給個簡單的幾個函數(shù),可以實現(xiàn)初始化
成都創(chuàng)新互聯(lián)是專業(yè)的鞍山網站建設公司,鞍山接單;提供網站制作、網站設計,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行鞍山網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!
下面3個就是lcd的初始化配置,下面3個函數(shù)是找到的i2c庫代碼,你按照這個lcd的pdf進行對應的修改就行
#define pcf8576 0x70
ISendByte(pcf8576,0x48); //設置背級方式
ISendByte(pcf8576,0x70); //設置閃爍
ISendByte(pcf8576,0x60); //設置器件子地址
你可以把lcd當成一個接口,向這個接口地址發(fā)送數(shù)據就可以讓它進行對應的操作,這個是我寫過的lcd顯示模塊,pcf8576是lcd的地址,這個你可以在lcd的pdf里找到
顯示的話,就是向對應的lcd寄存器寫入數(shù)據,比如要顯示第一個數(shù)字,就是將lcd的顯示數(shù)據里修改,然后發(fā)送顯示數(shù)據到lcd的對應寄存器里,下面的lcdnum就是8576的顯示數(shù)據數(shù)組
void Refresh_LCD()
{
ISendByte(pcf8576,0x60);
ISendStr(pcf8576,0x00,lcdnum,9);
}
void Start_I2c()
{
SDA=1; /*發(fā)送起始條件的數(shù)據信號*/
_Nop();
SCL=1;
_Nop(); /*起始條件建立時間大于4.7us,延時*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*發(fā)送起始信號*/
_Nop(); /* 起始條件鎖定時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*鉗住I2C總線,準備發(fā)送或接收數(shù)據 */
_Nop();
_Nop();
}
/*******************************************************************
結束總線函數(shù)
函數(shù)原型: void Stop_I2c();
功能: 結束I2C總線,即發(fā)送I2C結束條件.
********************************************************************/
void Stop_I2c()
{
SDA=0; /*發(fā)送結束條件的數(shù)據信號*/
_Nop(); /*發(fā)送結束條件的時鐘信號*/
SCL=1; /*結束條件建立時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*發(fā)送I2C總線結束信號*/
_Nop();
_Nop();
_Nop();
_Nop();
}
bit ISendByte(unsigned char sla,unsigned char c)
{
Start_I2c(); /*啟動總線*/
SendByte(sla); /*發(fā)送器件地址*/
if(ack==0)
return(0);
SendByte(c); /*發(fā)送數(shù)據*/
if(ack==0)
return(0);
Stop_I2c(); /*結束總線*/
return(1);
}
在前一小節(jié)中介紹了點亮第一個LED燈,這里我們準備進階嘗試下,輸出第一段PWM波形。(PWM也就是脈寬調制,一種可調占空比的技術,得到的效果就是:如果用示波器測量引腳會發(fā)現(xiàn)有方波輸出,而且高電平、低電平的時間是可調的。)
這里爪爪熊準備寫成一個golang的庫,并開源到github上,后續(xù)更新將直接更新到github中,如果你有興趣可以和我聯(lián)系。 github.com/dpawsbear/bear_rpi_go
我在很多的教程中都看到說樹莓派的PWM(硬件)只有一個GPIO能夠輸出,就是 GPIO1 。這可是不小的打擊,因為我想使用至少四個 PWM ,還是不死心,想通過硬件手冊上找尋蛛絲馬跡,看看究竟怎么回事。
手冊上找尋東西稍等下講述,這里先提供一種方法測試 樹莓派3B 的 PWM 方法:用指令控制硬件PWM。
這里通過指令的方式掌握了基本的pwm設置技巧,決定去翻一下手冊看看到底PWM怎么回事,這里因為沒有 BCM2837 的手冊,根據之前文章引用官網所說, BCM2835 和 BCM2837 應該是一樣的。這里我們直接翻閱 BCM2835 的手冊,直接找到 PWM 章節(jié)。找到了如下圖:
圖中可以看到在博通的命名規(guī)則中 GPIO 12、13、18、19、40、41、45、52、53 均可以作為PWM輸出。但是只有兩路PWM0 PWM1。根據我之前所學知識,不出意外應該是PWM0 和 PWM1可以輸出不一樣的占空比,但是頻率應該是一樣的。因為沒有示波器,暫時不好測試。先找到下面對應圖:
根據以上兩個圖對比可以發(fā)現(xiàn)如下規(guī)律:
對照上面的表可以看出從 BCM2837 中印出來的能夠使用在PWM上的就這幾個了。
為了驗證個人猜想是否正確,這里先直接使用指令的模式,模擬配置下是否能夠正常輸出。
通過上面一系列指令模擬發(fā)現(xiàn),(GPIO1、GPIO26)、(GPIO23、GPIO24)是綁定在一起的,調節(jié)任意一個,另外一個也會發(fā)生變化。也即是PWM0、PWM1雖然輸出了兩路,可以理解成兩路其實都是連在一個輸出口上。這里由于沒有示波器或者邏輯分析儀這類設備(僅有一個LED燈),所以測試很簡陋,下一步是使用示波器這類東西對頻率以及信號穩(wěn)定性進行下測試。
小節(jié):樹莓派具有四路硬件輸出PWM能力,但是四路中只能輸出兩個獨立(占空比獨立)的PWM,同時四路輸出的頻率均是恒定的。
上面大概了解清楚了樹莓派3B的PWM結構,接下來就是探究如何使用Go語言進行設置。
因為拿到了手冊,這里我想直接操作寄存器的方式進行設置,也是順便學習下Go語言處理寄存器的過程。首先需要拿到pwm 系列寄存器的基地址,但是翻了一圈手冊,發(fā)現(xiàn)只有偏移,沒有找到基地址。
經過了一段時間的努力后,決定寫一個 樹莓派3B golang包開源放在github上,只需要寫相關程序進行調用就可以了,以下是相關demo(pwm)(在GPIO.12 上輸出PWM波,放上LED燈會有呼吸燈的效果,具體多少頻率還沒有進行測試)
以下是demo(pwm) 源碼
i2c有其協(xié)議的,我當時從不會到掌握其協(xié)議用了一陣子,就是狂讀協(xié)議和例程
我把當時用非斯卡爾單片機讀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總線協(xié)議,把協(xié)議多讀幾遍慢慢就會了~~要不你把郵箱給我我發(fā)給你.總之很簡單的 不用害怕,學學就會了
網站標題:go語言分析I2c波形,golang i2c
網頁URL:http://chinadenli.net/article10/heijgo.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、、關鍵詞優(yōu)化、營銷型網站建設、企業(yè)網站制作、網站營銷
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)