久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

ATMEGA16讀寫24C02 C51程序

作者:佚名   來源:本站原創   點擊數:  更新時間:2012年03月02日   【字體:



 
完整代碼下載地址: http://www.zg4o1577.cn/f/2402avr.rar

main函數:
/*
程序功能:ATMEGA16讀寫24C02
作者:朱波
時間:2012年1月30日
說明:程序運行后會從0開始自動計數到256(對字節操作的結果)
     當復位或者斷電時24C02保存斷電時的數據,當重新啟動后
計數值會從斷電時的值開始計數
*/
#include <iom16v.h>
#include <macros.h>
#include"delay.h"  
#include"display.h"
#include"24C02.h"
#define  uchar unsigned char
#define  uint  unsigned int
 
 uint num;//定義變量用于讀取24C02中的數值,注意必須為uint型
 
void  main()
{  
     LCD_init();
twi_init();
while(1)
{
    num=IIC_Read(0x00);//從器件中讀取(0x00是器件地址)
    num=num+1;//加1
    num=num%1000;//關鍵語句,沒有此句則不工作*/
IIC_Write(num,0x00);//加1后寫入器件
    display();
}
}
延時函數delay.c
#include"delay.h"
void delay(unsigned int ms)
{
        unsigned int i,j;
for(i=0;i<ms;i++)
  {
  for(j=0;j<1141;j++);
       }
}
顯示函數display.c
#include <iom16v.h>
#include <macros.h>
#include"display.h"
#define  uchar unsigned char
#define  uint  unsigned int

uchar table1[]="0123456789";
uchar table2[]="zhubo-24C02";
uchar table3[]="result:";
extern uint num;//主函數中的值
 
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;i<7;i++)
 {
    write_dat(table3[i]);
delay(5);
 } 
 //這是在1602液晶中顯示數值的方法
  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);//仿真與實際1602有區別
 
 delay(5);
   for(i=0;i<11;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

//主機模式啟動狀態碼
#define I2C_START                       0x08   //啟動總線
#define I2C_RESTART      0x10   //重新啟動總線

//主機發送模式狀態碼
#define I2C_MT_SLA_ACK   0x18   //SLA+W寫地址已發送,收到應答位
#define I2C_MT_SLA_NACK  0x20   //SLA+W寫地址已發送,收到非應答位
#define I2C_MT_DATA_ACK  0x28   //寫入數據已發送,收到應答位
#define I2C_MT_DATA_NACK 0x30   //寫入數據已發送,收到應答位
#define I2C_MT_ARB_LOST  0x38   //SLA+W或數據仲裁失敗

//主機接收模式狀態碼
#define I2C_MR_ARB_LOST  0x38   //SLA+R或NOT ACK的仲裁失敗
#define I2C_MR_SLA_ACK   0x40   //SLA+R已發送,收到應答位
#define I2C_MR_SLA_NACK  0x48   //SLA+R已發送,收到非應答位
#define I2C_MR_DATA_ACK  0x50   //接收到數據,應答位已返回
#define I2C_MR_DATA_NACK 0x58   //接收到數據,非應答位已返回

//從機接收模式狀態碼
#define I2C_SR_SLA_ACK    0x60   //自己的SLA+W已經被接收ACK已返回
#define I2C_SR_ARB_LOST_SLA_ACK  0x68   //SLA+R/W作為主機的仲裁失敗,自己的SLA+W已經被接收ACK已返回
#define I2C_SR_GCALL_ACK   0x70   //接收到廣播地址ACK已返回
#define I2C_SR_ARB_LOST_GCALL_ACK 0x78   //SLA+R/W作為主機的仲裁失敗,接收到廣播地址ACK已返回
#define I2C_SR_DATA_ACK    0x80   //以前以自己的SLA+W被尋址,數據已經被接收ACK已返回
#define I2C_SR_DATA_NACK   0x88   //以前以自己的SLA+W被尋址,數據已經被接收NOT ACK已返回
#define I2C_SR_GCALL_DATA_ACK  0x90   //以前以廣播方式被尋址,數據已經被接收ACK已返回
#define I2C_SR_GCALL_DATA_NACK  0x98   //以前以廣播方式被尋址,數據已經被接收NOT ACK已返回
#define I2C_SR_STOP     0xA0   //在以從機工作時接收到STOP或重復START

//從機發送模式狀態碼
#define I2C_ST_SLA_ACK   0xA8   //自己的SLA+R已經被接收ACK已返回
#define I2C_ST_ARB_LOST_SLA_ACK 0xB0   //SLA+R/W作為主機的仲裁失敗,自己的SLA+R已經被接收ACK已返回
#define I2C_ST_DATA_ACK   0xB8   //TWDR里數據已經被發送接收到ACK
#define I2C_ST_DATA_NACK 0xC0   //TWDR里數據已經被發送接收到NOT ACK
#define I2C_ST_LAST_DATA  0xC8   //TWDR的一字節數據已經發送(TWAE='0'),接收到ACK

//其他狀態碼
#define I2C_NO_INFO   0xF8   //沒有相關的狀態信息,TWINT='0'
#define I2C_BUS_ERROR  0x00   //由于非法的START或STOP引起的總線錯誤

//定義SLA中讀寫控制位極性
#define I2C_READ   1
#define I2C_WRITE  0

#define RD_DEVICE_ADDR                  0XA1   //寫的器件地址
#define WD_DEVICE_ADDR                  0XA0   //讀的器件地址
//常用TWI操作(主模式寫和讀)
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop()  (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO))                   
#define Wait()  {while(!(TWCR&(1<<TWINT)));}
#define TestAck() (TWSR&0XF8)
#define SetAck   (TWCR|=(1<<TWEA))
#define SetNoAck  (TWCR&=~(1<<TWEA))
#define Twi()     (TWCR=(1<<TWINT)|(1<<TWEN))//重新啟動發送數據   
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}//裝入SLA_W到TWDR
//寄存器,TWINT位清零,啟動發送地址
//定義運行狀態返回值極性
#define I2C_ERR   0     //錯誤
#define I2C_CRR   1     //正確

//定義TWINT位置位查詢等待時間
#define WAITCOUNT  50   //3.6864M時,此處必須大于60,驗證得知小于60,程序均不能正常工作

void twi_init()//硬件初始化
{
 TWBR=0X20;//TWBR的值不小于10
TWCR=0X04;//使能TWI操作 
TWSR=0;//1分頻
}

uchar IIC_Write(uchar wdata,uchar addr)//字節寫操作
{
 //按照時序來寫
 Start();//開始
 Wait();//等待
 if(TestAck()!=I2C_START)//測試
 return 1;// 如果出錯則返回1
 
 Write8Bit(WD_DEVICE_ADDR);//寫器件地址(SLAVE ADDRESS)
 Wait();//等待
 if(TestAck()!=I2C_MT_SLA_ACK  )//檢驗TWI狀態寄存器,屏蔽
 return 1;//預分頻位,如果狀態字不是SLA+R已發送,收到應答位
 //轉出錯處理 ,(SLA針對的是器件地址)此時時序中第一個ACK結束
 
 Write8Bit(addr);//寫數據地址(要存儲到哪個字節上BYTE ADDRESS)
 Wait();//等待
 if(TestAck()!=I2C_MT_DATA_ACK )//檢驗TWI狀態寄存器,屏蔽
 return 1;//預分頻位,如果狀態字不是寫入數據已發送,收到應答位
          //轉出錯,到此時序中第二個ACK結束
 Write8Bit(wdata);//寫數據(DATA)
 Wait();//等待
 if(TestAck()!=I2C_MT_DATA_ACK)//DATA和ADDRESS是EEPROM內部的就用
 return 1;   //I2C_MT_DATA_ACK
 
 Stop();
 return 0;//運行到STOP處都沒有出錯就返回0
}


uchar IIC_Read(uchar addr)//根據選擇讀時序來寫的
{
 uchar temp;//定義此變量從單片機中讀取數據
 //此段與上個函數相同
 Start();
 Wait();
 if(TestAck()!=I2C_START)//測試
 return 1;
 //此段與上個函數相同
 Write8Bit(WD_DEVICE_ADDR);//寫器件地址(SLAVE ADDRESS)
 Wait();
 if(TestAck()!=I2C_MT_SLA_ACK)//sla是器件外部
 return 1;//此處時序下方的第一個ACK完成
 
 Write8Bit(addr);//寫存儲地址(BYTE ADDRESS)
 Wait();
 if(TestAck()!=I2C_MT_DATA_ACK)//器件內部用I2C_MT_DATA_ACK
 return 1;//此處時序下方的第二個ACK完成
 
 Start();//根據時序又出現了START
 Wait();
 if(TestAck()!=I2C_RESTART)//判斷是否是重復START出現
 return 1;//如果出錯則返回1
 
 Write8Bit(RD_DEVICE_ADDR);//讀器件地址(SLAVE ADDRESS)
 Wait();
 if(TestAck()!=I2C_MR_SLA_ACK)//現在是主機接收所以不是T而是R
 return 1;//此處時序下方的第三個ACK完成
 
 Twi();//重新啟動TWI總線
 Wait();
 if(TestAck()!=I2C_MR_DATA_NACK)//向器件里讀數據,時序中為NO ACK
 return 1;//程序到了這里數據已經到了單片機里邊了
 
 temp=TWDR;//從數據寄存器中讀取數據
 Stop();//發送停止信號
 return temp;
 }
以下是接口函數代碼:
delay.h:
#ifndef delay_h
#define delay_h
extern void delay(unsigned int ms);
#endif
 display.h:
#define  uchar unsigned char
#define  uint  unsigned int
#ifndef display_h
24C02.h:
#define  uchar unsigned char
#define  uint  unsigned int

extern void twi_init();
extern uchar IIC_Write(uchar wdata,uchar addr);
extern uchar IIC_Read(uchar addr);

#define display_h
extern void write_com(uchar com);
extern void write_dat(uchar dat);
extern void LCD_init();
extern void display();
extern uchar table[];
#endif
關閉窗口

相關文章

主站蜘蛛池模板: 国产精品麻 | 中文字幕电影在线观看 | 黄色一级视频免费 | 九九久久精品 | 欧美日韩精品一区二区三区视频 | 91久久精品 | 日韩www | 久久精品小视频 | 台湾佬久久 | 99福利视频| 亚洲欧美精品在线观看 | 九九视频在线观看视频6 | 偷拍自拍在线观看 | 岛国一区| 欧美在线色视频 | 欧美a在线| 干一干操一操 | 久久999 | 玖玖视频网| 青青草原精品99久久精品66 | 精品久久中文字幕 | 成人免费在线视频 | 一区二区三区中文字幕 | 亚洲久久一区 | 日本天堂一区二区 | 国产一区二区 | 国产综合视频 | 日韩av在线中文字幕 | 日韩一区二区三区av | 美女久久 | 色综合久久久久 | 91精品国产91久久久久久最新 | 国产成人a亚洲精品 | 免费在线观看一区二区 | 国产欧美日韩精品一区二区三区 | 国产精品久久久久久久午夜 | 国产精品九九视频 | 久久av一区二区三区 | 超碰激情| 中文字幕一区二区三区四区五区 | 天天干天天干 |