硬體I2C(TWI)讀寫PCF8563和24CXX程式
//ICC-AVR application builder : 2010-3-5 13:51:50 // Target : M88 // Crystal: 8.0000Mhz #include <iom88v.h> #include <macros.h> #include <eeprom.h> //I2C(TWI)基本指令 #define I2C_START() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWSTA) #define I2C_STOP() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWSTO) #define I2C_ACK() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWEA) #define I2C_NAK() TWCR = BIT(TWINT)|BIT(TWEN) #define I2C_CHECK_STATUS(X) {while(!(TWCR&BIT(TWINT))); if((TWSR&0xF8)!=(X)) return 0;} #define I2C_WRITE(X) TWDR = (X) #define I2C_READ(X) (X) = TWDR //TWSR&0xF8 狀態碼 #define START 0x08 #define RE_START 0x10 #define MT_SLA_ACK 0x18 #define MT_SLA_NAK 0x20 #define MT_DATA_ACK 0x28 #define MT_DATA_NAK 0x30 #define SLA_DATA_FAIL 0x38 #define MR_SLA_ACK 0x40 #define MR_SLA_NAK 0x48 #define MR_DATA_ACK 0x50 #define MR_DATA_NAK 0x58 //器件地址及引數 #define SLA_R_24C64 0xA1 #define SLA_W_24C64 0xA0 #define PAGE_SIZE_24C64 32 #define NUM_PAGE_24C64 256 #define SLA_R_PCF8563 0xA3 #define SLA_W_PCF8563 0xA2 #define PAGE_SIZE_PCF8563 16 #define NUM_PAGE_PCF8563 1 //毫秒級延時 void delay_ms(unsigned int x) { int i,j; for(j=0;j<x;j++) for(i=0;i<1141;i++); } /************************************************************************ I2C主機寫N位元組資料到從器件 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明: SLA_W: 從器件寫地址 ADDR: 從器件內部寫資料起始地址 N: 寫資料位元組數 DAT: 源資料起始地址 ************************************************************************/ unsigned char i2c_write_n_bytes(unsigned char SLA_W, unsigned int ADDR, unsigned int N, unsigned char *DAT) { unsigned int i; I2C_START(); I2C_CHECK_STATUS(START); I2C_WRITE(SLA_W); I2C_NAK(); I2C_CHECK_STATUS(MT_SLA_ACK); if(SLA_W!=SLA_W_PCF8563) { I2C_WRITE((unsigned char)ADDR>>8); I2C_NAK(); I2C_CHECK_STATUS(MT_DATA_ACK); } I2C_WRITE((unsigned char)ADDR); I2C_NAK(); I2C_CHECK_STATUS(MT_DATA_ACK); for(i=0;i<N;i++) { I2C_WRITE(DAT); I2C_NAK(); I2C_CHECK_STATUS(MT_DATA_ACK); } I2C_STOP(); return 1; } /************************************************************************ I2C主機從從器件讀N位元組資料 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明: SLA_R: 從器件讀地址 ADDR: 從器件內部讀資料起始地址 N: 讀資料位元組數 DAT: 目標資料起始地址 ************************************************************************/ unsigned char i2c_read_n_bytes(unsigned char SLA_R, unsigned int ADDR, unsigned int N, unsigned char *DAT) { unsigned int i; I2C_START(); I2C_CHECK_STATUS(START); I2C_WRITE((SLA_R)-1); I2C_NAK(); I2C_CHECK_STATUS(MT_SLA_ACK); if(SLA_R!=SLA_R_PCF8563) { I2C_WRITE((unsigned char)ADDR>>8); I2C_NAK(); I2C_CHECK_STATUS(MT_DATA_ACK); } I2C_WRITE((unsigned char)ADDR); I2C_NAK(); I2C_CHECK_STATUS(MT_DATA_ACK); I2C_START(); I2C_CHECK_STATUS(RE_START); I2C_WRITE(SLA_R); I2C_NAK(); I2C_CHECK_STATUS(MR_SLA_ACK); if(N>1) { for(i=0;i<N-1;i++) { I2C_ACK(); I2C_CHECK_STATUS(MR_DATA_ACK); I2C_READ(DAT); } } I2C_NAK(); I2C_CHECK_STATUS(MR_DATA_NAK); DAT[N-1]=TWDR; I2C_STOP(); return 1; } /************************************************************************ I2C主機檢測從器件忙 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明: SLA_W: 從器件寫地址 器件忙返回 1,否則返回 0,用於判斷EEPROM是否程式設計完成 ************************************************************************/ unsigned char i2c_check_busy(unsigned char SLA_W) { unsigned char retv=0; I2C_START(); I2C_CHECK_STATUS(START); I2C_WRITE(SLA_W); I2C_NAK(); while(!(TWCR&BIT(TWINT))); if((TWSR&0xF8)!=MT_SLA_ACK) retv=1; I2C_STOP(); return retv; } /************************************************************************ I2C主機寫N位元組資料到從器件(EEPROM) 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明: SLA_W: 從器件寫地址 PAGE_SIZE: EEPROM頁大小(單位:位元組) NUM_PAGE: EEPROM總頁數 ADDR: 從器件內部寫資料起始地址 N: 寫資料位元組數 DAT: 源資料起始地址 ************************************************************************/ void SEEPROM_write_n_bytes(unsigned char SLA_W,unsigned int PAGE_SIZE,unsigned int NUM_PAGE, unsigned int ADDR,unsigned int N,unsigned char *DAT) { unsigned int PAGE,END_PAGE,NBYTES[2],i; END_PAGE=(ADDR+N)/PAGE_SIZE; if(END_PAGE>NUM_PAGE-1) { //not enough memory return; } PAGE=ADDR/PAGE_SIZE; NBYTES[0]=(PAGE+1)*PAGE_SIZE-ADDR; NBYTES[1]=(ADDR+N)-(END_PAGE*PAGE_SIZE); if(NBYTES[0]) { i2c_write_n_bytes(SLA_W,ADDR,NBYTES[0],DAT); //delay_ms(10);//模擬時用延時代替器件忙檢測 while(i2c_check_busy(SLA_W));//器件忙檢測 } if(END_PAGE>PAGE) { i=0; while(END_PAGE>++PAGE) { i2c_write_n_bytes(SLA_W,(PAGE*PAGE_SIZE),PAGE_SIZE,(DAT+NBYTES[0]+(i++)*PAGE_SIZE)); //delay_ms(10);//模擬時用延時代替器件忙檢測 while(i2c_check_busy(SLA_W));//器件忙檢測 } if(NBYTES[1]) { i2c_write_n_bytes(SLA_W,(PAGE*PAGE_SIZE),NBYTES[1],(DAT+NBYTES[0]+i*PAGE_SIZE)); //delay_ms(10);//模擬時用延時代替器件忙檢測 while(i2c_check_busy(SLA_W));//器件忙檢測 } } } /************************************************************************ I2C主機從從器件(EEPROM)讀N位元組資料 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明: SLA_R: 從器件讀地址 PAGE_SIZE: EEPROM頁大小(單位:位元組) NUM_PAGE: EEPROM總頁數 ADDR: 從器件內部讀資料起始地址 N: 讀資料位元組數 DAT: 目標資料起始地址 ************************************************************************/ void SEEPROM_read_n_bytes(unsigned char SLA_R,unsigned int PAGE_SIZE,unsigned int NUM_PAGE, unsigned int ADDR,unsigned int N,unsigned char *DAT) { unsigned int PAGE,END_PAGE,NBYTES[2],i; END_PAGE=(ADDR+N)/PAGE_SIZE; if(END_PAGE>NUM_PAGE-1) { //not enough memory return; } PAGE=ADDR/PAGE_SIZE; NBYTES[0]=(PAGE+1)*PAGE_SIZE-ADDR; NBYTES[1]=(ADDR+N)-(END_PAGE*PAGE_SIZE); if(NBYTES[0]) { i2c_read_n_bytes(SLA_R,ADDR,NBYTES[0],DAT); } if(END_PAGE>PAGE) { i=0; while(END_PAGE>++PAGE) { i2c_read_n_bytes(SLA_R,(PAGE*PAGE_SIZE),PAGE_SIZE,(DAT+NBYTES[0]+(i++)*PAGE_SIZE)); } if(NBYTES[1]) { i2c_read_n_bytes(SLA_R,(PAGE*PAGE_SIZE),NBYTES[1],(DAT+NBYTES[0]+i*PAGE_SIZE)); } } } //PCF8563時鐘停止指令 void PCF8563_stop(void) { unsigned char stopcode=0x20; i2c_write_n_bytes(SLA_W_PCF8563,0,1,&stopcode); } //PCF8563時鐘啟動指令 void PCF8563_start(void) { unsigned char startcode=0x00; i2c_write_n_bytes(SLA_W_PCF8563,0,1,&startcode); } /************************************************************************ PCF8563時鐘設定 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明:(BCD碼) yy: 年(0x00到0x99) mm: 月(0x01到0x12) dd: 日(0x01到0x31) hh: 時(0x00到0x23) mi: 分(0x00到0x59) ss: 秒(0x00到0x59) da: 星期(0x01到0x07) ************************************************************************/ void PCF8563_set(unsigned char yy,unsigned char mm,unsigned char dd, unsigned char da,unsigned char hh,unsigned char mi,unsigned char ss) { unsigned char time[7]; time[6]=yy; //年 time[5]=mm;//月 time[4]=da; //星期 time[3]=dd; //日 time[2]=hh;//時 time[1]=mi;//分 time[0]=ss;//秒 PCF8563_stop(); i2c_write_n_bytes(SLA_W_PCF8563,2,7,time); PCF8563_start(); } /************************************************************************ PCF8563時鐘讀取 程式設計:許工 QQ11520389 時間:2010.03.05 引數說明:(BCD碼) time: 存放讀出時間的陣列名 time[6]: 年(0x00到0x99) time[5]: 月(0x01到0x12) time[3]: 日(0x01到0x31) time[2]: 時(0x00到0x23) time[1]: 分(0x00到0x59) time[0]: 秒(0x00到0x59) time[4]: 星期(0x01到0x07) ************************************************************************/ void PCF8563_read(unsigned char *time) { i2c_read_n_bytes(SLA_R_PCF8563,2,7,time); //time[6] //年 time[5] &= 0x1F;//月 time[4] &= 0x07;//星期 time[3] &= 0x3F;//日 time[2] &= 0x3F;//時 time[1] &= 0x7F;//分 time[0] &= 0x7F;//秒 } void main(void) { unsigned char dat[132]; unsigned int i; DDRD|=3;//RED ON PORTD|=1; DDRC&=~(BIT(PC4)|BIT(PC5));//Pull up the pin SDA and SCL PORTC|=BIT(PC4)|BIT(PC5); TWCR=0; TWBR=12; //set bit rate TWSR=0; //set prescale /* PCF8563_set(0x10,0x03,0x04,0x04,0x11,0x25,0x45); delay_ms(1000); PCF8563_read(dat); //*/ //* for(i=0;i<132;i++) dat=i; for(i=0;i<2;i++) SEEPROM_write_n_bytes(SLA_W_24C64,PAGE_SIZE_24C64,NUM_PAGE_24C64,i*66+4,66,dat); //*/ //* for(i=0;i<132;i++) dat=255; SEEPROM_read_n_bytes(SLA_R_24C64,PAGE_SIZE_24C64,NUM_PAGE_24C64,4,132,dat); //*/ EEPROM_WRITE(0, dat); PORTD&=~1; PORTD|=2;//GREEN ON }
相關推薦
硬體I2C(TWI)讀寫PCF8563和24CXX程式
//ICC-AVR application builder : 2010-3-5 13:51:50 // Target : M88 // Crystal: 8.0000Mhz #include <iom88v.h> #include <macro
CYQ.Data(V5)讀寫分離使用方法 (如何配置與對應的效果)
nbsp bsp add sla 表現 sys catch 配置 exception 之前寫過一篇關於CYQ.Data 關於讀寫分離的使用心得。但在測試時,出現過各種的意外表現,未能達到預期效果。然後經過"路過秋天"這幾天的調優以後。各種使用環境均已達到預期效果。 今天在這
字符(串)讀寫
target null feo uva tchar spa ret ufs 一個 UVa 272,Tex Quotes: 輸入一段話,將引號由" ‘‘換成`` ‘‘輸出。 fgetc(fin); getchar(); fgets(buf,maxn,fin); 從打開
NOIP複賽複習(四)讀寫外掛與高精度模板
讀入輸出掛 讀入輸出掛就是逐個字元地讀入資料,從而讓讀入更加快速。輸出掛的原理也是一樣的,都是通過將輸出數字變成輸出字元以加快速度。當然輸入輸出外掛一般用在大量輸入輸出的情況下,這樣價效比才高一些,否則得不償失。 void Rd(int &res){ &nbs
Java併發(8)- 讀寫鎖中的效能之王:StampedLock
在上一篇《你真的懂ReentrantReadWriteLock嗎?》中我給大家留了一個引子,一個更高效同時可以避免寫飢餓的讀寫鎖---StampedLock。StampedLock實現了不僅多個讀不互相阻塞,同時在讀操作時不會阻塞寫操作。 為什麼StampedLock這麼神奇?能夠達到這種效果,它的核心思想在
Java併發——鎖框架(三)讀寫鎖
1. 讀寫鎖機制——ReadWriteLock介面 讀寫鎖適用於對資料結構頻繁讀而較少修改的場景。舉個栗子,你可以建立一個線上詞典供多條讀執行緒併發讀取,然而單條寫執行緒可能會不時新增新的定義或更新已有的定義。一個資源可以被多個執行緒同時讀,或者被一個執行緒寫,但是不能同時存在讀和寫執行緒。&n
python資料儲存系列教程——python(pandas)讀寫csv檔案
全棧工程師開發手冊 (作者:欒鵬) CSV檔案的規範 1、使用回車換行(兩個字元)作為行分隔符,最後一行資料可以沒有這兩個字元。 2、標題行是否需要,要雙方顯示約定 3、每行記錄的欄位數要相同,使用逗號分隔。逗號是預設使用的值
Java多執行緒程式設計-(15)-讀寫鎖ReentrantReadWriteLock深入分析
上兩篇: 一、前言 上兩篇的內容中已經介紹到了鎖的實現主要有ReentrantLock和ReentrantReadWriteLock。 ReentrantLock是重入鎖,顧名思義就是支援重進入的鎖,他表示該鎖能夠支援一個執行緒對資源的重複加鎖
mysql讀寫分離(三)--- 讀寫分離實現
現在的mysql讀寫分離方案有很多,在這裡筆者列舉出幾種自己使用過的方案: 1.spring實現route不同的資料來源,來達到讀寫分離的目的。 主要原理是根據service或者dao方法做切面,然後根據規範方法名字首來切換不同的資料來源,實現讀寫分離,好處,速度
Redis教程(二)- 讀寫分離
場景 我們為了適應大流量訪問,提高Redis讀寫效率,不能讓訪問洪峰到來時將讀壓力放在一臺伺服器上。所以我們需要提供讀寫分離。由一臺Master伺服器進行寫,同時提供讀的能力。再按需規劃N臺Slave從伺服器提供只讀能力,Master伺服器一旦有寫、更新、
EF通用數據層封裝類(支持讀寫分離,一主多從)
dto cte 功能 pes getc mes 工廠 好的 靈活 淺談orm 記得四年前在學校第一次接觸到 Ling to Sql,那時候瞬間發現不用手寫sql語句是多麽的方便,後面慢慢的接觸了許多orm框架,像 EF,Dapper,Hibernate,ServiceSta
課堂測試四(文件讀寫)
upd select tag art main cor color -s ioe 學生信息管理系統 (本程序以文本方式存儲數據,不通過數組,直接對文件進行操作) 學生類 Student.java 1 public class Student { 2 priva
Python3基礎之(十 五)讀寫檔案1
一、\n 換行命令 定義 text 為字串, 並檢視使用 \n 和不適用 \n 的區別: >>> text='this is first line,this is second line,this is third line' >>> prin
Python3基礎之(十 七)讀寫檔案3
一、讀取檔案內容 file.read() 上一節我們講了,寫檔案用的是'w'和'a',那麼今天來看看讀取檔案怎麼做 使用 file.read() 能夠讀取到文字的所有內容. if __name__=='__main__': file=open('my file.txt',
Python3基礎之(十 六)讀寫檔案2
我們先儲存一個已經有3行文字的 “my file.txt” 檔案, 檔案的內容如下: This is my first test. This is the second line. This the third 然後使用新增文字的方式給這個檔案新增一行 “This is ap
java指定編碼的按行讀寫txt檔案(幾種讀寫方式的比較)
輸入輸出的幾種形式 1.FileReader,FileWriter File r = new File("temp.txt") FileReader f = new FileReader(name);//讀取檔案name BufferedReader b = new Buf
深入Mysql鎖機制(二)讀鎖和寫鎖
深入Mysql鎖機制(二)讀鎖和寫鎖 這篇文章主要來介紹一下MySQL資料庫中的表級鎖。 本文提到的讀鎖和寫鎖都是MySQL資料庫的MyISAM引擎支援的表鎖的。而對於行級鎖的共享讀鎖和互斥寫鎖請閱讀MySQL中的共享鎖與排他鎖。我習慣在描述表鎖的時候按照讀寫來區分,在表
【人生苦短,我用python!】幾行python處理檔案裡面的重複內容(包括了讀寫檔案,過濾重複!)
The beauty of python 1 https://blog.csdn.net/dengyaolongacmblog/article/details/38016905 置頂 2014年07月21日 15:28:18 yaolongdeng 閱讀數:2189 標籤:
java輸入輸出14:IO流(位元組流讀寫中文)
位元組流讀取中文的問題 位元組流在讀中文的時候有可能會讀到半個中文,造成亂碼。 位元組流寫出中文的問題 位元組流直接操作位元組,所以寫出中文必須將字串轉換成位元組陣列。寫出回車換行write("\r\n
shp系列(一)——利用C++進行shp檔案的讀(開啟)與寫(建立)開言
部落格背景和目的 最近在用C++寫一個底層的東西,需要讀取和建立shp檔案。雖然接觸shp檔案已經幾年了,但是對於shp檔案內到底包含什麼東西一直是一知半解。以前使用shp檔案都是利用軟體(如ArcGIS)直接開啟,儲存;建立檔案則需要專門利用ArcToolBox等建立圖形。 網