您当前的位置:五五电子网电子知识单片机-工控设备AVR单片机ATMEGA16读写iic(24c02) C语言程序 测试通过 正文
ATMEGA16读写iic(24c02) C语言程序 测试通过

ATMEGA16读写iic(24c02) C语言程序 测试通过

点击数:7858 次   录入时间:03-04 12:02:19   整理:http://www.55dianzi.com   AVR单片机

#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*/




本文关键字:程序  C语言  AVR单片机单片机-工控设备 - AVR单片机