|
本帖最後由 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);
- //A Wire.requestFrom(DS3231_I2C_ADDRESS, 1);
- //B minute=Clock.getMinute();
- //C Wire.endTransmission();
- display.println();
- display.println("WIRE test");
- Serial.println("WIRE test");
- }
- }
複製代碼
其中
- 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;
複製代碼 |
|