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

    ATMEGA16讀寫iic(24c02) C語言程序 測試通過

    作者:未知   來源:本站原創   點擊數:  更新時間:2014年04月01日   【字體:

    #include <iom16v.h>
    #include "I2C.h"
    #include "1602.h"
    #include "delay.h"

    /*通過AVR往IIC寫數據,并通過串口把數據讀出顯示出來*/
    //===============================================================
    void uart_init(void)          //UART初始化
    { DDRD = 0x02;
         PORTD = 0x00;

    UCSRA = 0x02; /*無倍速*/
         UCSRB = 0x18; /*允許接收和發送*/
         UCSRC = 0x06; /*8位數據,1位停止位,無校驗*/
         UBRRH = 0x00;
         UBRRL = 12; /*9600*/

    }


    //===============================================================
    void USART_TXD(float data) //發送采用查詢方式
    {
    while( !(UCSRA & BIT(UDRE)) );
    UDR=data;
    while( !(UCSRA & BIT(TXC )) );
    UCSRA|=BIT(TXC);
    }


    void main(void)

    {
    unsigned char i;
    //LCD_init();

    uart_init();//TART初始化
    SEI(); //全局中斷使能

       while(1)
       {/*
    I2C_Write('n',0x00);
    I2C_Write('c',0x01);
    I2C_Write('e',0x02);
    I2C_Write('p',0x03);
    I2C_Write('u',0x04);
    */
    i=I2C_Read(0x00);
    //LCD_write_char(0,0,i);
       USART_TXD(i);
    i=I2C_Read(0x01);
    //LCD_write_data(i);
       USART_TXD(i);
    i=I2C_Read(0x02);
    //LCD_write_data(i);
       USART_TXD(i);
    i=I2C_Read(0x03);
    //LCD_write_data(i);
       USART_TXD(i);
       i=I2C_Read(0x04);
    //LCD_write_data(i);
       USART_TXD(i);
     
       }

    }

    /*上面上主函數部分*/

    #include <macros.h>
    #include "delay.h"

    //I2C 狀態定義
    //MT 主方式傳輸 MR 主方式接受
    #define START    0x08
    #define RE_START   0x10
    #define MT_SLA_ACK   0x18
    #define MT_SLA_NOACK 0x20
    #define MT_DATA_ACK   0x28
    #define MT_DATA_NOACK 0x30
    #define MR_SLA_ACK   0x40
    #define MR_SLA_NOACK 0x48
    #define MR_DATA_ACK   0x50
    #define MR_DATA_NOACK 0x58

    #define RD_DEVICE_ADDR 0xA1   //前4位器件固定,后三位看連線,最后1位是讀寫指令位
    #define WD_DEVICE_ADDR 0xA0

    //常用TWI操作(主模式寫和讀)
    #define Start()    (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))   //啟動I2C
    #define Stop()    (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))   //停止I2C
    #define Wait()    {while(!(TWCR&(1<<TWINT)));}     //等待中斷發生
    #define TestAck()   (TWSR&0xf8)          //觀察返回狀態
    #define SetAck    (TWCR|=(1<<TWEA))        //做出ACK應答
    #define SetNoAck   (TWCR&=~(1<<TWEA))        //做出Not Ack應答
    #define Twi()    (TWCR=(1<<TWINT)|(1<<TWEN))        //啟動I2C
    #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}   //寫數據到TWDR

    unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress);
    unsigned char I2C_Read(unsigned RegAddress);

    /*********************************************
    I2C總線寫一個字節
    返回0:寫成功
    返回1:寫失敗
    **********************************************/
    unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress)
    {

       Start();       //I2C啟動
       Wait();
       if(TestAck()!=START)
       return 1;      //ACK
     
       Write8Bit(WD_DEVICE_ADDR); //寫I2C從器件地址和寫方式
       Wait();
       if(TestAck()!=MT_SLA_ACK)
       return 1;      //ACK
     
       Write8Bit(RegAddress);   //寫器件相應寄存器地址
       Wait();
       if(TestAck()!=MT_DATA_ACK)
       return 1;        //ACK
     
       Write8Bit(Wdata);    //寫數據到器件相應寄存器
       Wait();
       if(TestAck()!=MT_DATA_ACK)
       return 1;        //ACK
     
       Stop();        //I2C停止
        delay_nms(10);     //延時
       return 0;
    }

    /*********************************************
    I2C總線讀一個字節
    返回0:讀成功
    返回1:讀失敗
    **********************************************/

    unsigned char I2C_Read(unsigned RegAddress)

    {
        unsigned char temp;
        Start();//I2C啟動
        Wait();
        if (TestAck()!=START)
           return 1;       //ACK  
      
        Write8Bit(WD_DEVICE_ADDR); //寫I2C從器件地址和寫方式
        Wait();
        if (TestAck()!=MT_SLA_ACK)
           return 1;        //ACK
      
        Write8Bit(RegAddress);   //寫器件相應寄存器地址
        Wait();
        if (TestAck()!=MT_DATA_ACK)
           return 1;
      
        Start();           //I2C重新啟動
        Wait();
        if (TestAck()!=RE_START)
           return 1;
      
        Write8Bit(RD_DEVICE_ADDR); //寫I2C從器件地址和讀方式
        Wait();
        if(TestAck()!=MR_SLA_ACK)
           return 1;       //ACK
      
        Twi();        //啟動主I2C讀方式
        Wait();
        if(TestAck()!=MR_DATA_NOACK)
        return 1;      //ACK
      
        temp=TWDR;//讀取I2C接收數據
           Stop();//I2C停止
        return temp;
          }

    /*以上是IIC.h頭文件部分,需要對照技術文檔好好研究*/

    *-----------------------------------------------------------------------
    延時函數
    編譯器:ICC-AVR v6.31A 日期: 2005-11-24 20:29:57
    目標芯片 : M16
    時鐘: 8.0000Mhz
    作者:archeng504
    -----------------------------------------------------------------------*/
    #ifndef __delay_h
    #define __delay_h
    void delay_nus(unsigned int n);
    void delay_nms(unsigned int n);
    void delay_1us(void);
    void delay_1ms(void) ;

    void delay_1us(void)                 //1us延時函數
    {
       asm("nop");
    }

    void delay_nus(unsigned int n)       //N us延時函數
    {
       unsigned int i=0;
       for (i=0;i<n;i++)
       delay_1us();
    }

    void delay_1ms(void)                 //1ms延時函數
    {
       unsigned int i;
       for (i=0;i<1140;i++);
    }

    void delay_nms(unsigned int n)       //N ms延時函數
    {
       unsigned int i=0;
       for (i=0;i<n;i++)
       delay_1ms();
    }

    #endif
    /*以上是delay.h部分,再加上IIC中自帶的iom16v.h 和macros.h就可以編譯通過*/

    /*注意點:本程序在實驗板ATMEGA16上測試通過,在示波器把SCL,SDA信號線有數據,移值到自己電路上可以放心使用,在ATMEGA32上一樣使用,本人24C02的A2,A1,A0都是接地,若地址不一樣,在程序相應位置改一下就可以,串口上調試單片機的基礎,所以它一定要會用*/

    /*本程序調試軟件環境是ICC6.31*/

    關閉窗口

    相關文章

    亚洲一区二区制服在线|在绩专区欧美自拍日韩|青春娱乐网97超碰人人射|在线观看国产网址你懂的