DS3231(IIC)+OLED12864(IIC) 串接的問題
本帖最後由 KaoChin 於 2015-11-28 12:18 編輯我想做一個簡單的實驗
只是把及時時鐘(RTC) DS3231 的數據,傳到 OLED12864 做成一個時鐘
藉此瞭解串接兩個 IIC 的程式技巧
板子為 MEGA 2560
OLED12664 使用的函數庫是 Adafruit_ssd1306syp
當然,遇到了一些問題,讀取RTC的動作,造成 OLED 無法繼續正常工作我想大致上的原因在於 記憶體位置的讀寫
所以我寫了一個程式用來 debug
程式規劃如下
int i;
loop 每一週期 i 就會增加 1
每個週期都會在 OLED 與 serial monitor 輸出 ith
並且在 i >5 時 開始讀取 RTC
並在 OLED 與 serial monitor 輸出 "ith"
程式如下
(只呈現 loop 的部分)
void loop()
{
i=i+1;
display.update();
Serial.print("i=");Serial.println(i);
//delay(1000);
display.clear();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(i, DEC);display.println("th");
if (i>255) i=0;
delay(100);
if (i>5){
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
//AWire.requestFrom(DS3231_I2C_ADDRESS, 1);
//Bminute=Clock.getMinute();
//CWire.endTransmission();
display.println();
display.println("WIRE test");
Serial.println("WIREtest");
}
}
其中
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
//A Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
//B minute=Clock.getMinute();
//C Wire.endTransmission();
是讀取 RTC 的程式
執行結果1.
如果 A B C 三行程式,其中的一行"沒有"被 comment
那麼,OLED 的輸出在 i>5 之後將會停止
而 serial monitor 會一直輸出 ,i 會大於 5 一直繼續加上去,而 "WIRE test"這行字也會一直出現在 serial monitor2.
如果 A B C 三行程式,其中的一"有"被 comment
那麼,OLED 與 serial monitor 會一起一樣的正常輸出
換句話說,讀取RTC的動作,造成 OLED 無法繼續正常工作
曾經試著在 if 的 loop
1.關掉 iic 再 打開 iic 可是沒用
2.做 display.initialize(); (OLED 的初始化,他會重置相關記憶體,程式在最後) 也沒用
所以我在想,是不是讀取記憶體的指標位置變了,使得 OLED 無法運作
請問有人有經驗,方法,或建議 解決這個問題嗎?
感謝您的回覆
以下為display.initialize() 程式碼 (當然有宣告display 為 Adafruit_ssd1306syp 類別 )
ool Adafruit_ssd1306syp::initialize()
{
//setup the pin mode
pinMode(m_sda,OUTPUT);
pinMode(m_scl,OUTPUT);
//malloc the framebuffer.
//malloc(記憶體大小)
//m_pFramebuffer = (unsigned char*)malloc(SSD1306_FBSIZE);
//將 malloc(SSD1306_FBSIZE) 轉成 unsigned char "指標" 放在 m_pFramebuffer
m_pFramebuffer = (unsigned char*)malloc(SSD1306_FBSIZE);
if(m_pFramebuffer == 0){
return false;
}
//void *memset(void *s, int c, size_t n);
//memset 設定位元組中的位元值,
//設定的方式從s 開始將n 個位元組設定成為c 的位元值並回傳s,
//開始將n 個位元組設定成為c 的位元值並回傳s,經常運用的範圍是在將位元組的位元值清為0。
memset(m_pFramebuffer,0,SSD1306_FBSIZE);//clear it.
//write command to the screen registers.
writeCommand(SSD1306_CMD_DISPLAY_OFF);//display off
writeCommand(0x00);//Set Memory Addressing Mode
writeCommand(0x10);//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
writeCommand(0x40);//Set Page Start Address for Page Addressing Mode,0-7
writeCommand(0xB0);//Set COM Output Scan Direction
writeCommand(0x81);//---set low column address
writeCommand(0xCF);//---set high column address
writeCommand(0xA1);//--set start line address
writeCommand(0xA6);//--set contrast control register
writeCommand(0xA8);
writeCommand(0x3F);//--set segment re-map 0 to 127
writeCommand(0xC8);//--set normal display
writeCommand(0xD3);//--set multiplex ratio(1 to 64)
writeCommand(0x00);//
writeCommand(0xD5);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
writeCommand(0x80);//-set display offset
writeCommand(0xD9);//-not offset
writeCommand(0xF1);//--set display clock divide ratio/oscillator frequency
writeCommand(0xDA);//--set divide ratio
writeCommand(0x12);//--set pre-charge period
writeCommand(0xDB);//
writeCommand(0x40);//--set com pins hardware configuration
writeCommand(0x8D);//--set vcomh
writeCommand(0x14);//0x20,0.77xVcc
writeCommand(0xAF);//--set DC-DC enable
writeCommand(SSD1306_CMD_DISPLAY_ON);//--turn on oled panel
delay(10);//wait for the screen loaded.
return true; 沒看到 Clock.getMinute(); 是怎麼寫的
不過, 先改成這看看
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
Wire.endTransmission(); // 移到這邊
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
minute=Clock.getMinute();
也就是把 ABC 變成 CAB 感謝樓上的建議
今天早上想了一下,還有一個可能的原因是
一開始先讓 OLED 跑, RTC 不跑
系統只有一個 IIC device 動作(RTC 可以視為不存在)。。。板子內建的上拉電位夠力
但是,RTC 加入後,系統變成兩個 device
由於 OLED 串接於 RTC 之後,OLED 上拉電位不夠
所以,OLED 就無法動作了
等下去買兩個 10K Ohm 電阻來試試! 筆記一下,以上的方法都沒用 @@ 本帖最後由 超新手 於 2015-11-30 10:53 編輯
請問一下
如果改成 CAB 的執行結果會怎樣?也是不會一直執行嗎?
因為你沒把 Clock.getMinute(); 內容 PO 出來
它應該是類似
while(Wire.available()) {
Wire.read();
.....
} 請問一下
如果改成 CAB 的執行結果會怎樣?也是不會一直執行嗎?
因為你沒把 Clock.getMinute(); 內容 PO ...
超新手 發表於 2015-11-30 10:46 http://www.robofun.net/forum/images/common/back.gif
不能執行事實上
ABC 只要存在任何一條,就無法執行
跟 Clock.getMinute() 內容沒有關係 我是說, 我程式順序改成 CAB
你可以看一下 Wire 範例 SFRRanger_reader
其實程式應該要寫成
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
.........
Wire.available())
reading = Wire.read(); 改過了,都沒用,就算只有以下三行(依順序,我一開始就是這樣寫的,後來才換順序看看),也是不能跑
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x01);
Wire.endTransmission(); 剛剛查了Adafruit_ssd1306syp的 library
如果你也是同一個libray的話
https://github.com/Miyeah/Arduin ... Adafruit_ssd1306syp
它是用 i/o 去模擬 i2c,
但是 Wire 是用 ic 本身硬體的 i2c
切來切去會不正常, 應該不算反常...
頁:
[1]