使用AVR單片機內部的TWI功能,并采用中斷工作模式,可以很好的使用Atmega系列的內部資源,并提高程序的穩定性;- #include <BCD.h>
- unsigned char i2c_sla;
- unsigned char i2c_addrh,i2c_addrl;
- unsigned char i2c_wr;
- unsigned char i2c_sub_flag;
- unsigned char i2c_num;
- unsigned char *i2c_buf;
- unsigned char i2c_end;
- /***********************************************************************************************************************************************************************
- 函數名稱:interrupt [TWI] void twi_isr(void)
- 函數功能:i2c底層中斷處理函數(時鐘SD2201和AT24C256共同的)
- ***********************************************************************************************************************************************************************/
- interrupt [TWI] void twi_isr(void)
- {
- unsigned char i2c_sta,tmp = 0;
- i2c_sta = TWSR;
- switch(i2c_sta)
- {
- case 0x08:
- if(i2c_sub_flag == 1)
- {
- TWDR = i2c_sla&0xfe;
- }
- else
- {
- TWDR = i2c_sla;
- }
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- break;
- case 0x10:
- TWDR = i2c_sla;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- //i2c_sub_flag = 1;
- break;
- case 0x18:
- if(i2c_sub_flag == 0)
- {
- if(i2c_num > 0)
- {
- TWDR = *i2c_buf;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- i2c_buf++;
- i2c_num--;
- }
- else
- {
- //TWCR &= 0xdf;
- //TWCR |= 0x90;
- TWCR = 0x95;
- i2c_end = 1;
- }
- }
- if(i2c_sub_flag == 1)
- {
- TWDR = i2c_addrh;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- i2c_sub_flag = 2;
- }
- break;
- case 0x28:
- if(i2c_sub_flag == 3)
- {
- if(i2c_wr == 0)
- {
- if(i2c_num > 0)
- {
-
- TWDR = *i2c_buf;
- i2c_buf++;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- i2c_num--;
- }
- else
- {
- //TWCR &= 0xdf;
- //TWCR |= 0x90;
- TWCR = 0x95;
- i2c_end = 1;
- }
- }
- }
- if(i2c_sub_flag == 2)
- {
- TWDR = i2c_addrl;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- i2c_sub_flag = 3;
- }
-
- if(i2c_sub_flag == 3)
- {
- if(i2c_wr == 1)
- {
- //TWCR &= 0xef;
- //TWCR |= 0xa0;
- TWCR = 0xa5;
- }
- }
- if(i2c_sub_flag == 0)
- {
- if(i2c_num > 0)
- {
- TWDR = *i2c_buf;
- //TWCR &= 0xcf;
- //TWCR |= 0x80;
- TWCR = 0x85;
- i2c_buf++;
- i2c_num--;
- }
- else
- {
- //TWCR &= 0xdf;
- //TWCR |= 0x90;
- TWCR = 0x95;
- i2c_end = 1;
- }
- }
- break;
- case 0x20:
- case 0x30:
- case 0x48:
- i2c_end = 0xff;
- //TWCR &= 0xfe;
- break;
- case 0x38:
- TWCR &= 0xed;
- TWCR |= 0xa4;
- i2c_end = 0xfe;
- //TWCR &= 0xfe;
- break;
- case 0x40:
- //TWCR &= 0xcf;
- //TWCR |= 0xc0;
- TWCR = 0xc5;
- break;
- case 0x50:
- *i2c_buf = TWDR;
- i2c_buf++;
- i2c_num--;
- if(i2c_num == 0)
- {
- //TWCR &= 0x8f;
- //TWCR |= 0x80;
- TWCR = 0x85;
- }
- else
- {
- //TWCR &= 0xcf;
- //TWCR |= 0xc0;
- TWCR = 0xc5;
- }
- break;
- case 0x58:
- tmp = TWDR;
- //TWCR &= 0xdf;
- //TWCR |= 0x90;
- TWCR = 0x95;
- i2c_end = 1;
- break;
- default:
- TWCR &= 0xfe;
- break;
- }
- }
- /***********************************************************************************************************************************************************************
- 函數名稱:void tran_dat(unsigned char *a,unsigned char num,unsigned char fx)
- 函數功能:i2c傳輸數據是由MSB開始LSB結束,而SD2201的數據傳輸是由LSB開始MSB結束,此函數負責數據做此轉換的
- 函數參數:unsigned char *a 數據的啟始指針,
- unsigned char num 數據的字節個數
- unsigned char fx 時鐘寫和讀的標志位, 1-寫,0-讀
- ***********************************************************************************************************************************************************************/
- void tran_dat(unsigned char *a,unsigned char num,unsigned char fx)
- {
- unsigned char j,k,dat;
- for(j = 0;j < num;j++)
- {
- dat = *a;
- if(fx == 1)
- {
- *a = bin2bcd(dat);
- }
-
- dat = *a;
- *a = 0;
- *a |= dat & 0x01;
- for(k = 1;k < 8;k++)
- {
- *a <<= 1;
- dat >>= 1;
- *a |= dat & 0x01;
- }
- dat = *a;
- if(fx == 0)
- {
- if((j == 4)&&(num == 7))
- {
- dat &= 0x3f;
- }
- if((j == 0)&&(num == 3))
- {
- dat &= 0x3f;
- }
- *a = bcd2bin(dat);
- }
- a++;
- }
- }
- /***********************************************************************************************************************************************************************
- 函數名稱:unsigned char i2c_w_n(unsigned char sla,unsigned char *s,unsigned char num)
- 函數功能:無子地址寫入N字節數據
- 函數參數:unsigned char sla 器件地址
- unsigned char *s 寫入數據緩沖區指針
- unsigned char num 寫入數據個數
- ***********************************************************************************************************************************************************************/
- unsigned char i2c_w_n(unsigned char sla,unsigned char *s,unsigned char num)
- {
- i2c_sla = sla;
- i2c_buf = s;
- i2c_num = num;
- i2c_sub_flag = 0;
- i2c_end = 0;
- TWCR=0xa5;
- while(i2c_end == 0);
- if(i2c_end == 1)
- {
- delay_ms(10);
- return(1);
- }
- else
- {
- return(0);
- }
- }
- /***********************************************************************************************************************************************************************
- 函數名稱:unsigned char i2c_rec_n(unsigned char sla,unsigned char *s,unsigned char num)
- 函數功能:無子地址讀出N字節數據
- 函數參數:unsigned char sla 器件地址
- unsigned char *s 讀出數據緩沖區指針
- unsigned char num 讀出數據個數
- ***********************************************************************************************************************************************************************/
- unsigned char i2c_rec_n(unsigned char sla,unsigned char *s,unsigned char num)
- {
- i2c_sla = sla + 1;
- i2c_buf = s;
- i2c_num = num;
- i2c_sub_flag = 0;
- i2c_end = 0;
- TWCR=0xa5;
- while(i2c_end == 0);
- if(i2c_end == 1)
- {
- return(1);
- }
- else
- {
- return(0);
- }
-
- }
- /***********************************************************************************************************************************************************************
- 函數名稱:unsigned char i2c_w_subn(unsigned char sla,unsigned char ah,unsigned char al,unsigned char *s,unsigned char num)
- 函數功能:有子地址寫入N字節數據
- 函數參數:unsigned char sla 器件地址
- unsigned char ah 器件子地址高字節
- unsigned char al 器件子地址低字節
- unsigned char *s 寫入數據緩沖區指針
- unsigned char num 寫入數據個數
- ***********************************************************************************************************************************************************************/
- unsigned char i2c_w_subn(unsigned char sla,unsigned char ah,unsigned char al,unsigned char *s,unsigned char num)
- {
- i2c_sla = sla;
- i2c_buf = s;
- i2c_num = num;
- i2c_addrh = ah;
- i2c_addrl = al;
- i2c_wr = 0;
- i2c_sub_flag = 1;
- i2c_end = 0;
- TWCR=0xa5;
- while(i2c_end == 0);
- if(i2c_end == 1)
- {
- delay_ms(10);
- return(1);
- }
- else
- {
- return(0);
- }
- }
- /***********************************************************************************************************************************************************************
- 函數名稱:unsigned char i2c_rec_subn(unsigned char sla,unsigned char ah,unsigned char al,unsigned char *s,unsigned char num)
- 函數功能:無子地址讀出N字節數據
- 函數參數:unsigned char sla 器件地址
- unsigned char ah 器件子地址高字節
- unsigned char al 器件子地址低字節
- unsigned char *s 讀出數據緩沖區指針
- unsigned char num 讀出數據個數
- ***********************************************************************************************************************************************************************/
- unsigned char i2c_rec_subn(unsigned char sla,unsigned char ah,unsigned char al,unsigned char *s,unsigned char num)
- {
- i2c_sla = sla + 1;
- i2c_buf = s;
- i2c_num = num;
- i2c_addrh = ah;
- i2c_addrl = al;
- i2c_wr = 1;
- i2c_sub_flag = 1;
- i2c_end = 0;
- TWCR=0xa5;
- while(i2c_end == 0);
- if(i2c_end == 1)
- {
- return(1);
- }
- else
- {
- return(0);
- }
- }
復制代碼
|