AVR TWI读写范例程序(AT24C02)

发布者:山宝宝最新更新时间:2015-03-11 来源: 51hei关键字:AVR  TWI  读写范  AT24C02 手机看文章 扫描二维码
随时随地手机看文章
本程序简单的示范了如何使用ATMEGA16的TWI 读写AT24C02 IIC EEPROM

    TWI协议
      (即IIC协议,请认真参考IIC协议的内容,否则根本就不能掌握)
    一主多从的应用,M16作主机
      (M16做从机和多主多从的应用不多,请自行参考相关文档)
 中断模式
     (因为AVR的速度很高,而IIC的速度相对较低,
      采用查询模式会长时间独占CPU,令CPU的利用率明显下降。
      特别是IIC速度受环境影响只能低速通讯时,对系统的实时性产生严重的影响。
      查询模式可以参考其它文档和软件模拟IIC的文档)
     AT24C02/04/08的操作特点
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器
*/

#include
#include
#include
#include
//时钟定为外部晶振7.3728MHz,F_CPU=7372800
#include
//定义了各种模式下的状态码列表(TWSR已屏蔽预分频位),本文后面附上中文描述

//管脚定义
#define  pinSCL    0     //PC0 SCL
#define  pinSDA    1     //PC1 SDA
//为保险起见,最好在SCL/SDA接上1~10K的外部上拉电阻到VCC。

#define fSCL    100000    //TWI时钟为100KHz
//预分频系数=1(TWPS=0)
#if F_CPU < fSCL*36
  #define TWBR_SET    10;     //TWBR必须大于等于10
#else
  #define TWBR_SET    (F_CPU/fSCL-16)/2; //计算TWBR值
#endif

#define TW_ACT    (1< //TWCR只能IN/OUT,直接赋值比逻辑运算(|= &=)更节省空间

#define SLA_24CXX   0xA0    //24Cxx系列的厂商器件地址(高四位)
#define ADDR_24C02   0x00
// AT24C02的地址线A2/1/0全部接地,SLAW=0xA0+0x00<<1+0x00,SLAR=0xA0+0x00<<1+0x01

//TWI_操作状态
#define TW_BUSY    0
#define TW_OK    1
#define TW_FAIL    2
//TWI_读写命令状态
#define OP_BUSY    0
#define OP_RUN    1


//TWI读写操作公共步骤
#define ST_FAIL    0 //出错状态
#define ST_START   1 //START状态检查
#define ST_SLAW    2 //SLAW状态检查
#define ST_WADDR   3 //ADDR状态检查
//TWI读操作步骤
#define ST_RESTART   4 //RESTART状态检查
#define ST_SLAR    5 //SLAR状态检查
#define ST_RDATA   6 //读取数据状态检查,循环n字节
//TWI写操作步骤
#define ST_WDATA   7 //写数据状态检查,循环n字节

#define FAIL_MAX   20 //重试次数最大值


//定义全局变量
unsigned char ORGDATA[8]=
    {0xAA,0xA5,0x55,0x5A,0x01,0x02,0x03,0x04}; //原始数据
unsigned char CMPDATA[8];      //比较数据
unsigned char BUFFER[256];      //缓冲区,可以装载整个AC24C02的数据

struct str_TWI         //TWI数据结构
{
    volatile unsigned char STATUS;    //TWI_操作状态
    unsigned char SLA;      //从设备的器件地址
    unsigned int ADDR;      //从设备的数据地址
    unsigned char *pBUF;      //数据缓冲区指针
    unsigned int DATALEN;     //数据长度
    unsigned char STATE;      //TWI读写操作步骤
    unsigned char FAILCNT;     //失败重试次数
};

struct str_TWI strTWI;       //TWI的数据结构变量

//仿真时在watch窗口,监控这些全局变量。


//AT24C02的读写函数(包括随机读,连续读,字节写,页写)
//根据sla的最低位决定(由中断程序中判断)
//bit0=1 TW_READ  读
//bit0=0 TW_WRITE 写
//  sla   器件地址(不能搞错)
// addr  EEPROM地址(0~1023)
// *ptr  读写数据缓冲区
// len   读数据长度(1~1024),写数据长度(1 or 8 or 16)
//  返回值  是否能执行当前操作
unsigned char TWI_RW(unsigned char sla,unsigned int addr,unsigned char *ptr,unsigned int len)
{
    unsigned char i;
    if (strTWI.STATUS==TW_BUSY)
    {//TWI忙,不能进行操作
        return OP_BUSY;
    }
    strTWI.STATUS=TW_BUSY;
    i=(addr>>8)<<1;
    i&=0x06;         //考虑了24C04/08的EEPROM地址高位放在SLA里面
    strTWI.SLA=sla+i;
    strTWI.ADDR=addr;
    strTWI.pBUF=ptr;
    strTWI.DATALEN=len;
    strTWI.STATE=ST_START;
    strTWI.FAILCNT=0;
    TWCR=(1<     return OP_RUN;
}

/*
TWI中断函数
 这个函数流程只是考虑了器件地址后有一个字节数据(命令)地址的IIC器件
 (大部分IIC接口器件都是这种类型,常见的例如AT24C01/02/04/08/16,DS1307,DS1721等)
 对于有两个字节数据地址的IIC器件(例如AT24C32/64/128/256等大容量EEPROM),请稍作改动
 
//根据strTWI.SLA的最低位决定
//bit0=1 TW_READ  读
//bit0=0 TW_WRITE 写

 虽然中断服务程序很长,但每次只执行一个 case,所以耗时并不长。
*/
SIGNAL(SIG_2WIRE_SERIAL)
{//IIC中断
    unsigned char action,state,status;
    action=strTWI.SLA&TW_READ;     //取操作模式
    state=strTWI.STATE;
    status=TWSR&0xF8;       //屏蔽预分频位
    if ((status>=0x60)||(status==0x00))
    {//总线错误或从机模式引发的中断,不予处理
        return;
    }
    switch(state)
    {
    case ST_START: //START状态检查
        if(status==TW_START)
        {//发送start信号成功
            TWDR=strTWI.SLA&0xFE;    //发送器件地址写SLAW
            TWCR=TW_ACT;             //触发下一步动作,同时清start发送标志
        }
        else
        {//发送start信号出错
            state=ST_FAIL;
        }
        break;
    case ST_SLAW: //SLAW状态检查
        if(status==TW_MT_SLA_ACK)
        {//发送器件地址成功
            TWDR=strTWI.ADDR;     //发送eeprom地址
            TWCR=TW_ACT;             //触发下一步动作
        }
        else
        {//发送器件地址出错
            state=ST_FAIL;
        }
        break;
    case ST_WADDR: //ADDR状态检查
        if(status==TW_MT_DATA_ACK)
        {//发送eeprom地址成功
            if (action==TW_READ)
            {//读操作模式
                TWCR=(1<             }
            else
            {//写操作模式
                TWDR=*strTWI.pBUF++;          //写第一个字节
                strTWI.DATALEN--;
                state=ST_WDATA-1;    //下一步将跳到WDATA分支
                TWCR=TW_ACT;            //触发下一步动作
            }
        }
        else
        {//发送eeprom地址出错
            state=ST_FAIL;
        }
        break;
    case ST_RESTART: //RESTART状态检查,只有读操作模式才能跳到这里
        if(status==TW_REP_START)
        {//发送restart信号成功
            TWDR=strTWI.SLA;     //发器件地址读SLAR
            TWCR=TW_ACT;             //触发下一步动作,同时清start发送标志
        }
        else
        {//重发start信号出错
            state=ST_FAIL;
        }
        break;
    case ST_SLAR: //SLAR状态检查,只有读操作模式才能跳到这里
        if(status==TW_MR_SLA_ACK)
        {//发送器件地址成功
            if (strTWI.DATALEN--)
            {//多个数据
                TWCR=(1<             }
            else
            {//只有一个数据
                TWCR=TW_ACT;     //设定NAK,触发下一步动作
            }
        }
        else
        {//发送器件地址出错
            state=ST_FAIL;
        }
        break;
    case ST_RDATA: //读取数据状态检查,只有读操作模式才能跳到这里
        state--;        //循环,直到读完指定长度数据
        if(status==TW_MR_DATA_ACK)
        {//读取数据成功,但不是最后一个数据
            *strTWI.pBUF++=TWDR;
            if (strTWI.DATALEN--)
            {//还有多个数据
                TWCR=(1<             }
            else
            {//准备读最后一个数据
                TWCR=TW_ACT;     //设定NAK,触发下一步动作
            }
        }
        else if(status==TW_MR_DATA_NACK)
        {//已经读完最后一个数据
            *strTWI.pBUF++=TWDR;
            TWCR=(1<             strTWI.STATUS=TW_OK;
        }
        else
        {//读取数据出错
            state=ST_FAIL;
        }
        break;
    case ST_WDATA: //写数据状态检查,只有写操作模式才能跳到这里
        state--;        //循环,直到写完指定长度数据
        if(status==TW_MT_DATA_ACK)
        {//写数据成功
            if (strTWI.DATALEN)
            {//还要写
                TWDR=*strTWI.pBUF++;
                strTWI.DATALEN--;
                TWCR=TW_ACT;            //触发下一步动作
            }
            else
            {//写够了
                TWCR=(1<                 strTWI.STATUS=TW_OK;
                //启动写命令后需要10ms(最大)的编程时间才能真正的把数据记录下来
                //编程期间器件不响应任何命令
            }
        }
        else
        {//写数据失败
            state=ST_FAIL;
        }
        break;
    default:
        //错误状态
        state=ST_FAIL;
        break;
    }

    if (state==ST_FAIL)
    {//错误处理
        strTWI.FAILCNT++;
        if (strTWI.FAILCNT         {//重试次数未超出最大值,
            TWCR=(1<         }
        else
        {//否则停止
            TWCR=(1<             strTWI.STATUS=TW_FAIL;
        }
    }
    state++;
    strTWI.STATE=state;       //保存状态
}[page]

int main(void)
{
    unsigned char i;
    //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
    PORTA=0xFF;         //不用的管脚使能内部上拉电阻。
    PORTB=0xFF;
    PORTC=0xFF;         //SCL,SDA使能了内部的10K上拉电阻
    PORTD=0xFF;

    //TWI初始化
    TWSR=0x00;         //预分频=0^4=1
    TWBR=TWBR_SET;
    TWAR=0x00;         //主机模式,该地址无效
    TWCR=0x00;         //关闭TWI模块
    sei();          //使能全局中断
    strTWI.STATUS=TW_OK;

    TWI_RW(SLA_24CXX+(ADDR_24C02<<1)+TW_WRITE,0x10,&ORGDATA[0],8);
    //从0x10地址开始写入8个字节数据
    while(strTWI.STATUS==TW_BUSY);    //等待操作完成
    if (strTWI.STATUS==TW_FAIL)
    {
        //操作失败?
    }
    _delay_ms(10);        //延时等待编程完成
    while(1)
    {
        i=TWI_RW(SLA_24CXX+(ADDR_24C02<<1)+TW_READ,0x10,&CMPDATA[0],8);
        //从0x10地址开始读出8个字节数据
        while(strTWI.STATUS==TW_BUSY);   //等待操作完成
        //如果不加等待,则需要检测返回值i才能知道当前操作是否执行了
        // 0 OP_BUSY 之前的操作没完成,没执行当前操作
        // 1 OP_RUN  当前操作执行中
        if (strTWI.STATUS==TW_FAIL)
        {
            //操作失败?
        }
        //读取成功,对比ORGDATA和CMPDATA的数据

        i=TWI_RW(SLA_24CXX+(ADDR_24C02<<1)+TW_READ,0x00,&BUFFER[0],256);
        //从0x00地址开始读出256个字节数据(整个ATC24C02)
        while(strTWI.STATUS==TW_BUSY);   //等待操作完成
    };
}
/*
两线串行接口总线定义
 两线接口TWI很适合于典型的处理器应用。
 TWI协议允许系统设计者只用两根双向传输线就可以将128个不同的设备互连到一起。
 这两根线一是时钟SCL,一是数据SDA。外部硬件只需要两个上拉电阻,每根线上一个。
 所有连接到总线上的设备都(必须)有自己的地址。
 注意:就是说不能有两个相同地址的设备
 TWI协议解决了总线仲裁的问题。
 
 所有 TWI 兼容的器件的总线驱动都是漏极开路或集电极开路的。这样就实现了对接口操作非常关键的线与功能。
 TWI器件输出为"0”时,TWI总线会产生低电平。
 当所有的TWI器件输出为三态时,总线会输出高电平,允许上拉电阻将电压拉高。
 注意:为保证所有的总线操作,凡是与TWI 总线连接的AVR 器件必须上电。
 
 与总线连接的器件数目受如下条件限制:
 总线电容要低于400pF,而且可以用7 位从机地址进行寻址。
 两个不同的规范,一种是总线速度低于100 kHz,而另外一种是总线速度高达400 kHz。
 
SCL和SDA引脚
 SCL与SDA为MCU的 TWI接口引脚。
 引脚的输出驱动器包含一个波形斜率限制器以满足TWI 规范。
 引脚的输入部分包括尖峰抑制单元以去除小于50ns 的毛刺。
 当相应的端口设置为SCL与SDA引脚时,可以使能I/O口内部的10K上拉电阻,这样可省掉外部的上拉电阻
注意:如果要作高速通讯或者从机数量较多,最好还是外接合适的上拉电阻
 
比特率发生器单元
 TWI工作于主机模式时,比特率发生器控制时钟信号SCL的周期。
 具体由TWI状态寄存器TWSR的预分频系数以及比特率寄存器TWBR设定。
 当TWI工作在从机模式时,不需要对比特率或预分频进行设定,但从机的CPU时钟频率必须大于TWI时钟线SCL频率的16倍。
注意,从机可能会延长SCL 低电平的时间,从而降低TWI 总线的平均时钟周期。
 SCL的频率根据以下的公式产生:
  fSCL=fCPU/((16+2(TWBR)(4^TWPS))
 TWBR = TWI比特率寄存器的数值
 TWPS = TWI状态寄存器预分频的数值
Note:TWI 工作在主机模式时,TWBR 值应该不小于10,否则主机会在SDA 与 SCL 产生错误输出作为提示信号。
 问题出现于TWI 工作在主机模式下,向从机发送Start + SLA + R/W 的时候(不需要真的有从机与总线连接)。
 
控制单元
 控制单元监听TWI 总线,并根据 TWI 控制寄存器TWCR 的设置作出相应的响应。
 当TWI总线上产生需要应用程序干预处理的事件时,TWI 中断标志位TWINT 置位。
 在下一个时钟周期, TWI 状态寄存器TWSR 被表示这个事件的状态码字所更新。
 在其它时间里,TWSR 的内容为一个表示无事件发生的特殊状态字。
 一旦TWINT 标志位置"1”,时钟线SCL 即被拉低,暂停TWI 总线上的数据传输,让用户程序处理事件。
 在下列状况出现时, TWINT 标志位置位:
 ? 在TWI 传送完START/REPEATED START 信号之后
 ? 在TWI 传送完SLA+R/W 数据之后
 ? 在TWI 传送完地址字节之后
 ? 在TWI 总线仲裁失败之后
 ? 在TWI 被主机寻址之后( 广播方式或从机地址匹配)
 ? 在TWI 接收到一个数据字节之后
 ? 作为从机工作时, TWI 接收到STOP 或REPEATED START 信号之后
 ? 由于非法的START 或STOP 信号造成总线错误时
 
TWI 寄存器说明
 
TWI 比特率寄存器- TWBR
 ? Bits 7..0 – TWI 比特率寄存器
  TWBR 为比特率发生器分频因子。
  比特率发生器是一个分频器,在主机模式下产生SCL时钟频率。
  比特率计算公式请见前面的[比特率发生器单元]
  
TWI 控制寄存器- TWCR
 TWCR 用来控制TWI操作。
 它用来使能TWI,通过施加START到总线上来启动主机访问,产生接收器应答,产生STOP 状态,以及在写入数据到TWDR 寄存器时控制总线的暂停等。
 这个寄存器还可以给出在TWDR 无法访问期间,试图将数据写入到TWDR 而引起的写入冲突信息。
 ? Bit 7 – TWINT: TWI 中断标志
  当TWI 完成当前工作,希望应用程序介入时TWINT 置位。
  若SREG 的I 标志以及TWCR寄存器的TWIE 标志也置位,则MCU 执行TWI 中断例程。
  当TWINT 置位时, SCL信号的低电平被延长。
  TWINT 标志的清零必须通过软件写"1” 来完成。
  执行中断时硬件不会自动将其改写为"0”。
  要注意的是,只要这一位被清零,TWI 立即开始工作。
  因此,在清零TWINT 之前一定要首先完成对地址寄存器TWAR,状态寄存器TWSR,以及数据寄存器TWDR 的访问。
 ? Bit 6 – TWEA: 使能TWI 应答
  TWEA 标志控制应答脉冲的产生。
  若TWEA 置位,出现如下条件时接口发出ACK 脉冲:
  1. 器件的从机地址与主机发出的地址相符合
  2. TWAR 的TWGCE 置位时接收到广播呼叫
  3. 在主机/ 从机接收模式下接收到一个字节的数据
  将TWEA 清零可以使器件暂时脱离总线。
  置位后器件重新恢复地址识别。 
 ? Bit 5 – TWSTA: TWI START 状态标志
  当CPU 希望自己成为总线上的主机时需要置位TWSTA。
  TWI 硬件检测总线是否可用。
  若总线空闲,接口就在总线上产生START 状态。
  若总线忙,接口就一直等待,直到检测到一个STOP 状态 ,然后产生START 以声明自己希望成为主机。
  发送START之后软件必须清零TWSTA。
 ? Bit 4 – TWST TWI STOP 状态标志
  在主机模式下,如果置位TWSTO,TWI 接口将在总线上产生STOP 状态,然后TWSTO自动清零。
  在从机模式下,置位TWSTO 可以使接口从错误状态恢复到未被寻址的状态。
  此时总线上不会有STOP 状态产生,但TWI 返回一个定义好的未被寻址的从机模式且释放SCL 与SDA 为高阻态。
 ? Bit 3 – TWWC: TWI 写碰撞标志
  当TWINT 为低时写数据寄存器TWDR 将置位TWWC。
  当TWINT 为高时,每一次对TWDR 的写访问都将更新此标志。
 ? Bit 2 – TWEN: TWI 使能
  TWEN 位用于使能TWI操作与激活TWI接口。
  当TWEN位被写为"1”时,TWI引脚将I/O引脚切换到SCL 与SDA 引脚,使能波形斜率限制器与尖峰滤波器。
  如果该位清零, TWI接口模块将被关闭,所有TWI 传输将被终止。
 ? Bit 0 – TWIE: 使能TWI 中断
  当SREG 的I 以及TWIE 置位时,只要TWINT 为"1”, TWI 中断就激活。
  
TWI 状态寄存器- TWSR
 ? Bits 7..3 – TWS: TWI 状态
  这5位用来反映TWI 逻辑和总线的状态。
  不同的状态代码将会在后面的部分描述。
  注意从TWSR 读出的值包括5 位状态值与2 位预分频值。
  检测状态位时设计者应屏蔽预分频位为"0”。这使状态检测独立于预分频器设置。
 ? Bits 1..0 – TWPS: TWI 预分频位
  这两位可读/ 写,用于控制比特率预分频因子。
  预分频系数为4的n次方
  计算比特率的公式见前面的[比特率发生器单元]
  
TWI 数据寄存器- TWDR
 在发送模式, TWDR 包含了要发送的字节;
 在接收模式, TWDR 包含了接收到的数据。
 当TWI 接口没有进行移位工作(TWINT 置位) 时这个寄存器是可写的。
 在第一次中断发生之前用户不能够初始化数据寄存器。
 只要TWINT 置位,TWDR 的数据就是稳定的。
 在数据移出时,总线上的数据同时移入寄存器。
 TWDR 总是包含了总线上出现的最后一个字节,除非MCU 是从掉电或省电模式被TWI 中断唤醒。此时TWDR 的内容没有定义。
 总线仲裁失败时,主机将切换为从机,但总线上出现的数据不会丢失。
 ACK 的处理由 TWI逻辑自动管理, CPU 不能直接访问ACK。
 ? Bits 7..0 – TWD: TWI 数据寄存器
  根据状态的不同,其内容为要发送的下一个字节,或是接收到的数据。
 
TWI(从机) 地址寄存器-TWAR
 TWAR 的高7 位为从机地址。
 工作于从机模式时,TWI 将根据这个地址进行响应。
 主机模式不需要此地址。
 在多主机系统中, TWAR需要进行设置以便其他主机访问自己。
 TWAR 的LSB 用于识别广播地址 (0x00)。
 器件内有一个地址比较器。一旦接收到的地址和本机地址一致,芯片就请求中断。
 ? Bits 7..1 – TWA: TWI 从机地址寄存器
  其值为从机地址。
 ? Bit 0 – TWGCE: 使能TWI 广播识别
  置位后MCU 可以识别TWI 总线广播。
 
使用TWI
 AVR的TWI接口是面向字节和基于中断的。
 所有的总线事件,如接收到一个字节或发送了一个START 信号等,都会产生一个TWI 中断。
 由于TWI 接口是基于中断的,因此TWI接口在字节发送和接收过程中,不需要应用程序的干预。
 TWCR寄存器的TWI中断允许位[TWIE]和全局中断允许位[I]一起决定了应用程序是否响应TWINT标志位产生的中断请求。
 如果TWIE 被清零,应用程序只能采用轮询TWINT 标志位的方法来检测TWI 总线状态。
 当TWINT 标志位置"1” 时,表示TWI 接口完成了当前的操作,等待应用程序的响应。
 在这种情况下,TWI 状态寄存器TWSR 包含了表明当前TWI 总线状态的值。
 应用程序可以读取TWCR 的状态码,判别此时的状态是否正确,并通过设置TWCR 与TWDR 寄存器,决定在下一个TWI 总线周期TWI 接口应该如何工作。 
 
各种模式下的状态码列表(TWSR已屏蔽预分频位)
twi.h里面有定义,现附上中文描述
 
主机发送状态码
#define TW_START    0x08 //START已发送
#define TW_REP_START   0x10 //重复START已发送
#define TW_MT_SLA_ACK   0x18 //SLA+W 已发送收到ACK
#define TW_MT_SLA_NACK   0x20 //SLA+W 已发送接收到NOT ACK
#define TW_MT_DATA_ACK   0x28 //数据已发送接收到ACK
#define TW_MT_DATA_NACK   0x30 //数据已发送接收到NOT ACK
#define TW_MT_ARB_LOST   0x38 //SLA+W 或数据的仲裁失败
 
从发送状态码
#define TW_ST_SLA_ACK   0xA8 //自己的SLA+R 已经被接收ACK 已返回
#define TW_ST_ARB_LOST_SLA_ACK 0xB0 //SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收ACK 已返回
#define TW_ST_DATA_ACK   0xB8 //TWDR 里数据已经发送接收到ACK
#define TW_ST_DATA_NACK   0xC0 //TWDR 里数据已经发送接收到NOT ACK
#define TW_ST_LAST_DATA   0xC8 //TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK
 
AT24C02/04/08 IIC接口EEPROM的特点
(不同公司的24系列EEPROM特性有部分不同,请参考数据手册)
 1 AT24C02/04/08 是一个2K/4K/8K位串行CMOS E2PROM 内部含有256/512/1024 个8位字节
 2 AT24C02有一个8 字节页写缓冲器,AT24C04/08/16 有一个16字节页写缓冲器
 3 通过器件地址输入端A0,A1,A2可以实现将最多
  8个24C02器件
  4个24C04器件
  2个24C08器件

关键字:AVR  TWI  读写范  AT24C02 引用地址:AVR TWI读写范例程序(AT24C02)

上一篇:AVR 单片机 位操作
下一篇:AVR定时器0完全资料

推荐阅读最新更新时间:2024-03-16 13:54

AVR的INT外部中断和PCINT中断之区别与使用
INT外部中断是几乎所有通用单片机,嵌入机中都会带有的,早期的51系列和arm系列也都有,然而大多数因为设计原因,多只有带两个INT,最近别人提到了一个“所有端口都可以外部中断”这样的说法,因为表示存疑,因此找了些资料,也就找到了avr328p自带的PCINT引脚功能 INT外部中断和AVR和PCINT具体区别如下: 差别1. INT限制在了两个端口上面,而PCINT则是所有接口都具备。 差别2. INT具有上沿,下沿,低电平,高电平触发这几种模式,而PCINT只有测量电平的变化这一个模式。 差别3. INT可以了解具体是哪个口触发的,而PCINT不行。 差别4. PCINT不会直接跳转入指定的程序,用
[单片机]
<font color='red'>AVR</font>的INT外部中断和PCINT中断之区别与使用
51单片机和AVR单片机比较
1 TQFP 薄型四方扁平封装 LQFP 1.4mm 2 51单片机的I/O端口大部分是准双向口,在复位期间全部输出高电平,对端口的输入和输出操作也试直接通过I/O端口的地址进行的。avr的I/O端口为标准双向口,在复位期间所有端口处于没有上拉电阻的输入状态(高阻态,管脚电平完全由外部电路决定),这在强调复位状态的场合是很有用的。AVR的每个端口对应三个地址,即DDRX、PORTX和PINX。 DDRX为端口方向寄存器,当DDRX的某一位置1时,相应端口的引脚作为输出使用;当DDRX的某一位清0 时,对应端口的引脚作为输入使用。PORTX为端口数据寄存器,当引脚为输出使用,PORTX的数据由相应引脚输出;当引脚作为输入使用
[单片机]
AVR串口发送程序
ATMega32 频率: 8.0MHz 编译器:CodeVisionAVR 1.24.8c 串口发送程序 */ #i nclude mega32.h #i nclude delay.h #i nclude stdio.h #define uchar unsigned char // 0~255 #define uint unsigned int // 0~65535 #define _SPK PORTB.2 #define _LED PORTB.3 #define CLI() #asm( cli ) #define SEI() #asm( sei ) /**//*
[单片机]
ucos在AVR ATmega32上的移植(一)
前面介绍了基本的调度原理,现在把它应用到ucos的移植上来,如果你还不明白调度,就别急于移植,因为对堆栈的一丝差错都会造成系统崩溃,而你也很难找到原因之所在。 先看一下ucos的程序结构 进过整理,工程这样组成: 我们主要是对ucos移植中的三个文件进行修改。 1.OS_CPU.H 更改的地方,我用汉语标注 /* ********************************************************************************************************* * uC/OS-II *
[单片机]
ucos在<font color='red'>AVR</font> ATmega32上的移植(一)
一种AVR单片机的快速工频干扰滤除算法
工频干扰广泛存在各种工业现场中,其产生的途径主要包括输电馈线、照明设备、发动机以及各种电子仪器设备等。一般可以通过滤波电路消除工频干扰,但这必将增加硬件结构的复杂程度。实际上,还可以采用数字信号处理的相关算法,通过软件滤波器滤除工频干扰。软件滤波算法的采用,无疑会在简化电路结构的同时,使系统的硬件资源得到更加充分的利用,并达到降低产品成本的要求。 AVR 单片机是Atmel 公司生产的8位精简指令集(RISC)单片机。与同类单片机相比,在运算速度、外设资源、灵活性等方面性能均衡,性价比较高。 AVR 单片机适合C语言开发,Mega 系列AVR 单片机还有一个内部硬件乘法器单元。这些特点都为软件滤波器的实现提供了极大的便利。
[单片机]
一种<font color='red'>AVR</font>单片机的快速工频干扰滤除算法
AVR单片机控制发光二极管
点亮ARV单片机开发板上的一个LED灯 原理图: 分析:上面的截图就是单片机和LED灯的连接原理图,其中J6是一个排阻,起到限流的作用,防止LED电流过大而烧坏。 排阻的内部就是一组并联的电阻: bubuko.com,布布扣 提示: 算一下这个排阻的电阻的大小,二极管的工作电流是3mA,工作电压时1.7V,VCC的电压时5V。所以电阻上的电流是3mA,电压是3.3V,所以电阻的阻值是1.1KΩ。 因为所有的二极管都是通过一个限流电阻共阳极的,所以只需要在Q端给一个低电平就能点亮这个发光二极管。Q端的电平通过一个573锁存器受控于D端的电平高低,也就是单片机的PB端口。这样我们就能通过写程序控制PB端口的高低
[单片机]
<font color='red'>AVR</font>单片机控制发光二极管
5. avr定时器/计数器1 快速PWM输出 (比较输出--快速PWM模式)
快速PWM 模式(WGM13:0 = 5、6、 7、14 或15) 可用来产生高频的PWM 波形。快速PWM模式与其他PWM模式的不同之处是其单边斜坡工作方式。计数器从BOTTOM计到TOP,然后立即回到BOTTOM 重新开始。对于普通的比较输出模式,输出比较引脚OC1x在TCNT1 与OCR1x 匹配时置位,在TOP 时清零;对于反向比较输出模式,OCR1x 的动作正好相反。由于使用了单边斜坡模式,快速PWM 模式的工作频率比使用双斜坡的相位修正PWM 模式高一倍。此高频操作特性使得快速PWM 模式十分适合于功率调节,整流和DAC应用。高频可以减小外部元器件( 电感,电容) 的物理尺寸,从而降低系统成本。 工作于快速PWM 模式
[单片机]
爱特梅尔的AVR微控制器集成射频发送器功能
爱特梅尔公司(Atmel® Corporation)宣布推出首个ATA874x单芯片UHF ASK/FSK RF发送器系列。这一全新AVR®产品线具有业界领先的射频 (RF) 性能,并可在免授权的ISM频带(868 到 928 MHz、433 MHz和 315 MHz) 运作。ATA874x系列瞄准工业和消费领域的多元化专有无线应用,如计量、报警系统和家居控制应用设备等。 爱特梅尔是智能计量和家居自动化市场的知名厂商,一直提供出色的无线IEEE 802.15.4 和 ZigBee®产品;如今更采取更多的举措,以满足专有无线市场领域各种多元化的需求。 ATA874x系列器件包含一个低功率AVR CPU和一个高效
[网络通信]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved