ATMEGA16讀寫24C02 C51程序
完整代碼下載地址: http://www.51hei.com/f/2402avr.rar
main函數(shù):/*程序功能:ATMEGA16讀寫24C02作者:朱波時(shí)間:2012年1月30日說明:程序運(yùn)行后會(huì)從0開始自動(dòng)計(jì)數(shù)到256(對(duì)字節(jié)操作的結(jié)果)當(dāng)復(fù)位或者斷電時(shí)24C02保存斷電時(shí)的數(shù)據(jù),當(dāng)重新啟動(dòng)后計(jì)數(shù)值會(huì)從斷電時(shí)的值開始計(jì)數(shù)*/#include iom16v.h>#include macros.h>#include"delay.h" #include"display.h"#include"24C02.h"#define uchar unsigned char#define uint unsigned intuint num;//定義變量用于讀取24C02中的數(shù)值,注意必須為uint型void main(){ LCD_init();twi_init();while(1){num=IIC_Read(0x00);//從器件中讀取(0x00是器件地址)num=num+1;//加1num=num%1000;//關(guān)鍵語句,沒有此句則不工作*/IIC_Write(num,0x00);//加1后寫入器件display();}}延時(shí)函數(shù)delay.c#include"delay.h"void delay(unsigned int ms){unsigned int i,j;for(i=0;ims;i++){for(j=0;j1141;j++);}}顯示函數(shù)display.c#include iom16v.h>#include macros.h>#include"display.h"#define uchar unsigned char#define uint unsigned intuchar table1[]="0123456789";uchar table2[]="zhubo-24C02";uchar table3[]="result:";extern uint num;//主函數(shù)中的值void write_com(uchar com){PORTD=~BIT(4);PORTD=~BIT(5);PORTB=com;PORTD|=BIT(6);delay(1);PORTD=~BIT(6);}void write_dat(uchar dat){ PORTD|=BIT(4);PORTD=~BIT(5);PORTB=dat;PORTD|=BIT(6);delay(1);PORTD=~BIT(6);}void LCD_init(){ DDRB=0XFF;DDRD|=BIT(4)|BIT(5)|BIT(6);PORTD=~BIT(6);write_com(0X38);delay(5);write_com(0X01);delay(5);write_com(0X0C);delay(5);write_com(0X06);delay(5);}void display(){uint i;write_com(0X80+0);delay(5);for(i=0;i7;i++){write_dat(table3[i]);delay(5);} //這是在1602液晶中顯示數(shù)值的方法write_com(0X80+8);delay(5);write_dat(table1[num/1000]);delay(5);write_com(0X80+9);delay(5);write_dat(table1[num%1000/100]);delay(5);write_com(0X80+10);delay(5);write_dat(table1[num%100/10]);delay(5);write_com(0X80+11);delay(5);write_dat(table1[num%10]);delay(5);write_com(0X80+0X40);//仿真與實(shí)際1602有區(qū)別delay(5);for(i=0;i11;i++){write_dat(table2[i]);delay(5);}}24C02.c:#include iom16v.h>#include macros.h>#include"24C02.h"#define uchar unsigned char#define uint unsigned int//主機(jī)模式啟動(dòng)狀態(tài)碼#define I2C_START 0x08 //啟動(dòng)總線#define I2C_RESTART 0x10 //重新啟動(dòng)總線//主機(jī)發(fā)送模式狀態(tài)碼#define I2C_MT_SLA_ACK 0x18 //SLA+W寫地址已發(fā)送,收到應(yīng)答位#define I2C_MT_SLA_NACK 0x20 //SLA+W寫地址已發(fā)送,收到非應(yīng)答位#define I2C_MT_DATA_ACK 0x28 //寫入數(shù)據(jù)已發(fā)送,收到應(yīng)答位#define I2C_MT_DATA_NACK 0x30 //寫入數(shù)據(jù)已發(fā)送,收到應(yīng)答位#define I2C_MT_ARB_LOST 0x38 //SLA+W或數(shù)據(jù)仲裁失敗//主機(jī)接收模式狀態(tài)碼#define I2C_MR_ARB_LOST 0x38 //SLA+R或NOT ACK的仲裁失敗#define I2C_MR_SLA_ACK 0x40 //SLA+R已發(fā)送,收到應(yīng)答位#define I2C_MR_SLA_NACK 0x48 //SLA+R已發(fā)送,收到非應(yīng)答位#define I2C_MR_DATA_ACK 0x50 //接收到數(shù)據(jù),應(yīng)答位已返回#define I2C_MR_DATA_NACK 0x58 //接收到數(shù)據(jù),非應(yīng)答位已返回//從機(jī)接收模式狀態(tài)碼#define I2C_SR_SLA_ACK 0x60 //自己的SLA+W已經(jīng)被接收ACK已返回#define I2C_SR_ARB_LOST_SLA_ACK 0x68 //SLA+R/W作為主機(jī)的仲裁失敗,自己的SLA+W已經(jīng)被接收ACK已返回#define I2C_SR_GCALL_ACK 0x70 //接收到廣播地址ACK已返回#define I2C_SR_ARB_LOST_GCALL_ACK 0x78 //SLA+R/W作為主機(jī)的仲裁失敗,接收到廣播地址ACK已返回#define I2C_SR_DATA_ACK 0x80 //以前以自己的SLA+W被尋址,數(shù)據(jù)已經(jīng)被接收ACK已返回#define I2C_SR_DATA_NACK 0x88 //以前以自己的SLA+W被尋址,數(shù)據(jù)已經(jīng)被接收NOT ACK已返回#define I2C_SR_GCALL_DATA_ACK 0x90 //以前以廣播方式被尋址,數(shù)據(jù)已經(jīng)被接收ACK已返回#define I2C_SR_GCALL_DATA_NACK 0x98 //以前以廣播方式被尋址,數(shù)據(jù)已經(jīng)被接收NOT ACK已返回#define I2C_SR_STOP 0xA0 //在以從機(jī)工作時(shí)接收到STOP或重復(fù)START//從機(jī)發(fā)送模式狀態(tài)碼#define I2C_ST_SLA_ACK 0xA8 //自己的SLA+R已經(jīng)被接收ACK已返回#define I2C_ST_ARB_LOST_SLA_ACK 0xB0 //SLA+R/W作為主機(jī)的仲裁失敗,自己的SLA+R已經(jīng)被接收ACK已返回#define I2C_ST_DATA_ACK 0xB8 //TWDR里數(shù)據(jù)已經(jīng)被發(fā)送接收到ACK#define I2C_ST_DATA_NACK 0xC0 //TWDR里數(shù)據(jù)已經(jīng)被發(fā)送接收到NOT ACK#define I2C_ST_LAST_DATA 0xC8 //TWDR的一字節(jié)數(shù)據(jù)已經(jīng)發(fā)送(TWAE='0'),接收到ACK//其他狀態(tài)碼#define I2C_NO_INFO 0xF8 //沒有相關(guān)的狀態(tài)信息,TWINT='0'#define I2C_BUS_ERROR 0x00 //由于非法的START或STOP引起的總線錯(cuò)誤//定義SLA中讀寫控制位極性#define I2C_READ 1#define I2C_WRITE 0#define RD_DEVICE_ADDR 0XA1 //寫的器件地址#define WD_DEVICE_ADDR 0XA0 //讀的器件地址//常用TWI操作(主模式寫和讀)#define Start() (TWCR=(1TWINT)|(1TWSTA)|(1TWEN))#define Stop() (TWCR=(1TWINT)|(1TWEN)|(1TWSTO)) #define Wait() {while(!(TWCR(1TWINT)));}#define TestAck() (TWSR0XF8)#define SetAck (TWCR|=(1TWEA))#define SetNoAck (TWCR=~(1TWEA))#define Twi() (TWCR=(1TWINT)|(1TWEN))//重新啟動(dòng)發(fā)送數(shù)據(jù) #define Write8Bit(x) {TWDR=(x);TWCR=(1TWINT)|(1TWEN);}//裝入SLA_W到TWDR//寄存器,TWINT位清零,啟動(dòng)發(fā)送地址//定義運(yùn)行狀態(tài)返回值極性#define I2C_ERR 0 //錯(cuò)誤#define I2C_CRR 1 //正確//定義TWINT位置位查詢等待時(shí)間#define WAITCOUNT 50 //3.6864M時(shí),此處必須大于60,驗(yàn)證得知小于60,程序均不能正常工作void twi_init()//硬件初始化{TWBR=0X20;//TWBR的值不小于10TWCR=0X04;//使能TWI操作 TWSR=0;//1分頻}uchar IIC_Write(uchar wdata,uchar addr)//字節(jié)寫操作{//按照時(shí)序來寫Start();//開始Wait();//等待if(TestAck()!=I2C_START)//測(cè)試return 1;// 如果出錯(cuò)則返回1Write8Bit(WD_DEVICE_ADDR);//寫器件地址(SLAVE ADDRESS)Wait();//等待if(TestAck()!=I2C_MT_SLA_ACK )//檢驗(yàn)TWI狀態(tài)寄存器,屏蔽return 1;//預(yù)分頻位,如果狀態(tài)字不是SLA+R已發(fā)送,收到應(yīng)答位//轉(zhuǎn)出錯(cuò)處理 ,(SLA針對(duì)的是器件地址)此時(shí)時(shí)序中第一個(gè)ACK結(jié)束Write8Bit(addr);//寫數(shù)據(jù)地址(要存儲(chǔ)到哪個(gè)字節(jié)上BYTE ADDRESS)Wait();//等待if(TestAck()!=I2C_MT_DATA_ACK )//檢驗(yàn)TWI狀態(tài)寄存器,屏蔽return 1;//預(yù)分頻位,如果狀態(tài)字不是寫入數(shù)據(jù)已發(fā)送,收到應(yīng)答位//轉(zhuǎn)出錯(cuò),到此時(shí)序中第二個(gè)ACK結(jié)束Write8Bit(wdata);//寫數(shù)據(jù)(DATA)Wait();//等待if(TestAck()!=I2C_MT_DATA_ACK)//DATA和ADDRESS是EEPROM內(nèi)部的就用return 1; //I2C_MT_DATA_ACKStop();return 0;//運(yùn)行到STOP處都沒有出錯(cuò)就返回0}uchar IIC_Read(uchar addr)//根據(jù)選擇讀時(shí)序來寫的{uchar temp;//定義此變量從單片機(jī)中讀取數(shù)據(jù)//此段與上個(gè)函數(shù)相同Start();Wait();if(TestAck()!=I2C_START)//測(cè)試return 1;//此段與上個(gè)函數(shù)相同Write8Bit(WD_DEVICE_ADDR);//寫器件地址(SLAVE ADDRESS)Wait();if(TestAck()!=I2C_MT_SLA_ACK)//sla是器件外部return 1;//此處時(shí)序下方的第一個(gè)ACK完成Write8Bit(addr);//寫存儲(chǔ)地址(BYTE ADDRESS)Wait();if(TestAck()!=I2C_MT_DATA_ACK)//器件內(nèi)部用I2C_MT_DATA_ACKreturn 1;//此處時(shí)序下方的第二個(gè)ACK完成Start();//根據(jù)時(shí)序又出現(xiàn)了STARTWait();if(TestAck()!=I2C_RESTART)//判斷是否是重復(fù)START出現(xiàn)return 1;//如果出錯(cuò)則返回1Write8Bit(RD_DEVICE_ADDR);//讀器件地址(SLAVE ADDRESS)Wait();if(TestAck()!=I2C_MR_SLA_ACK)//現(xiàn)在是主機(jī)接收所以不是T而是Rreturn 1;//此處時(shí)序下方的第三個(gè)ACK完成Twi();//重新啟動(dòng)TWI總線Wait();if(TestAck()!=I2C_MR_DATA_NACK)//向器件里讀數(shù)據(jù),時(shí)序中為NO ACKreturn 1;//程序到了這里數(shù)據(jù)已經(jīng)到了單片機(jī)里邊了temp=TWDR;//從數(shù)據(jù)寄存器中讀取數(shù)據(jù)Stop();//發(fā)送停止信號(hào)return temp;}以下是接口函數(shù)代碼:delay.h:#ifndef delay_h#define delay_hextern void delay(unsigned int ms);#endifdisplay.h:#define uchar unsigned char#define uint unsigned int#ifndef display_h24C02.h:#define uchar unsigned char#define uint unsigned intextern void twi_init();extern uchar IIC_Write(uchar wdata,uchar addr);extern uchar IIC_Read(uchar addr);#define display_hextern void write_com(uchar com);extern void write_dat(uchar dat);extern void LCD_init();extern void display();extern uchar table[];#endif
評(píng)論