AVR单片机及其开发环境

这篇具有很好参考价值的文章主要介绍了AVR单片机及其开发环境。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内容包括AVRStudio及WinAVR介绍,软件下载地址,编译环境设置,IAR for AVR的使用,AVR单片机的介绍。紫色文字是超链接,点击自动跳转至相关博文。持续更新,原创不易!

目录:

一、AVRStudio及WinAVR简介

1、使用AVR GCC做为编译器

2、选择仿真调试平台

3、选择Device,设置Frequency,代码优化选项Optimization,输出hex文件

4、设置包含文件(头文件)路径

5、设置库文件路径

6、设置工具链路径(不使用AVR Toolchain)

二、Avr Studio和Winavr下载地址

三、Avr Studio和Winavr编译环境设置

四、IAR for AVR的使用(CC2530开发套件zigbee开发板)

1、出现“IAR AVR unknown or ambiguous symbol.main” 

2、处于调试状态,但是不能在C语言上单步运行,也不能设置断点

3、IAR For AVR软件的精确延时

4、IAR中加入编译所需库的头文件

五、AVR JTAG ICE MKII仿真器

六、AVR寄存器定义

七、AVR移位算法详细解释(1<<X)


一、AVRStudio及WinAVR简介

AVRStudio 是ATMEL 官方针对AVR 系列单片机推出的集成开发环境,它集开发调试于一体,有很好的用户界面,很好的稳定性。AVRSdudio 是免费的。AVRStudio 本身可以开发汇编程序,如果希望使用C语言开发,则需要安装C编译器(WinAVR 等)。
WinAVR 是GNU 组织推出的AVR 单片机的gcc 编译器,该编译器的编译效率极高。gcc 编译器是开源的,是免费的。使用gcc 编译器,可以掌握标准c 的语法等,为学习Linux 等奠定基础。

二、Avr Studio和Winavr下载地址

AVRStudio 最新版本的官方下载地址:Smart | Connected | Secure | Microchip Technology 

WinAVR 最新版本的官方下载地址:WinAVR - Browse Files at SourceForge.net

三、Avr Studio和Winavr编译环境设置

1、使用AVR GCC做为编译器

2、选择仿真调试平台 

3、选择Device,设置Frequency,代码优化选项Optimization,输出hex文件

4、设置包含文件(头文件)路径 

avr studio,单片机(汇编与C代码)、PLC,AVR

5、设置库文件路径 

6、设置工具链路径(不使用AVR Toolchain) 

avr studio,单片机(汇编与C代码)、PLC,AVR
如此便可使用winavr作为c编译器,不会出现avr-objcopy: '****.elf': No such file的错误。

四、IAR for AVR的使用(CC2530开发套件zigbee开发板)

1、出现“IAR AVR unknown or ambiguous symbol.main” 

project==>options==>linker,format设置成debug。 

IAR下必须进入DEBUG模式才能进行调试,如果不连接开发工具的话,断点也是不行的

2、处于调试状态,但是不能在C语言上单步运行,也不能设置断点

project==>options==>C/C++Compiler,将Generate debug information打上勾。

3、IAR For AVR软件的精确延时

不浪费中断的情况下的精确延时当然是软件自带的单周期的空操作,比如_nop_();

在IAR for AVR中的库函数#include"intrinsics.h"里面有个单周期的延时函数__delay_cycles();(相当于_nop_();),

如果__delay_cycles(100)就是100个mclk的周期延时。

然后就是下面的操作了:

#ifndef __delay_h
#define __delay_h
#include"intrinsics.h"
#define xtal  8       //这里就是你要使用的晶振的频率(单位NHZ)
#define delay_us(x) __delay_cycles((unsigned  long)(x*xtal))
#define delay_ms(x) __delay_cycles((unsigned  long)(x*xtal*1000))
#define delay_s(x)  __delay_cycles((unsigned  long)(x*xtal*1000000))
#endif

3)就是在你用到延时的函数里面调用#include"Delay.h"(这里是不区分大小写的,哈,不用担心这个)

这就在不浪费中断情况下的软件延时,当然你要非得精确,那非得定时计数器不可了

补充一下:

我用的是IAR for AVR,别的软件什么的似乎也有延时函数,如果没有可以用下面的这个延时(听说也是相当准的,在8MHZ晶振下,不管是外接还是内部晶振,哈都一样):

//------------------------------------------------------------------------------
//延时函数

void  delay_ms(uint k)
{
  uint  i,j;
  for(i=0;i
    for(j=0;j<1140;j++);
}

还有一个:差点忘记(这个不知道是那个哥们想到的,也可以改变晶振的~~~都贴出来,反正没事干):

//------------------------------------------------------------------------------
//延时1ms的函数,没有参数传递

 

void  delay_1ms()
{
  uint i;
  for(i=1;i<(uint)(xtal*143-2);i++)
    ;
}

//------------------------------------------------------------------------------
//延时nms的函数,有参数传递

void  delay_nms(uint n)
{
  uint i=0;
  while(i
  {
    delay_1ms();
    i++;
  }
}

4、IAR中加入编译所需库的头文件

工程名右击->options->C/C++ compiler->Preprocessor中填入头文件所在的目录即可,$PROJ_DIR$表示工程所在目录,\..\工程所在目录的上一层目录。设置后详见图片。

avr studio,单片机(汇编与C代码)、PLC,AVR

五、AVR JTAG ICE MKII仿真器

avr studio,单片机(汇编与C代码)、PLC,AVR

注意:此处的VTref需要接VCC。

六、AVR寄存器定义

#include "iom16v.h"

#include "macros.h"

void initialize()
{
    // DDRx端口方向寄存器,PORTx数据寄存器,PINx输入引脚寄存器
    // DDRxn相应位为1,引脚为输出否则为输入
    // PORTxn为1时,上拉电阻使能
    DDRA = 0x00;
}

void init_adc()
{
    // ADMUX
    // -----------------------------------------------------------------
    // | REFS1 | REFS0 | ADLAR |  MUX4 |  MUX3 |  MUX2 |  MUX1 |  MUX0 |
    // -----------------------------------------------------------------
    // REFS1 REFS0: 00,使用AREF,内部参考电压关闭
    //              01,AVCC、AREF引脚外加滤波电容
    //                 10,保留
    //                 11,2.56V片内基准电压,AREF引脚外加滤波电容
    // ADLAR: ADC转换结果左对齐
    //  MUX4 ~  MUX0   单端输入  正差分输入   负差分输入   增益
    // 00000 ~ 00111  ADC0~ADC7
    //   01000                   ADC0         ADC0         10x
    //   01001                   ADC1         ADC0         10x
    //   01010                   ADC0         ADC0        200x                  
    //   01011                   ADC1         ADC0        200x
    //   01100                   ADC2         ADC2         10x
    //   01101                   ADC3         ADC2         10x
    //   01110                   ADC2         ADC2        200x
    //   01111                   ADC3         ADC2        200x
    //   10000                   ADC0         ADC1          1x
    //   10001                   ADC1         ADC1          1x
    //   10010                   ADC2         ADC1          1x
    //   10011                   ADC3         ADC1          1x
    //   10100                   ADC4         ADC1          1x
    //   10101                   ADC5         ADC1          1x
    //   10110                   ADC6         ADC1          1x
    //   10111                   ADC7         ADC1          1x
    //   11000                   ADC0         ADC2          1x
    //   11001                   ADC1         ADC2          1x
    //   11010                   ADC2         ADC2          1x
    //   11011                   ADC3         ADC2          1x
    //   11100                   ADC4         ADC2          1x
    //   11101                   ADC5         ADC2          1x
    //   11110       1.23V(VBG)
    //   11111        0V(GND)                                                                                                                                    
     ADMUX = 0;

    // ADCSRA
    // -----------------------------------------------------------------
    // |  ADEN |  ADSC |  ADFR |  ADIF |  ADIE | ADPS2 | ADPS1 | ADPS0 |
    // -----------------------------------------------------------------
    // ADEN:ADC使能,转换过程中禁止ADC则立即中止转换。
    // ADSC:ADC开始转换。在转换过程中ADSC为1直到转换结束。
    // ADFR:是否工作在连续模式,该位写0,停止连续转换模式。
    // ADIF:ADC中断标志。中断服务硬件清零。
    // ADIE:ADC中断使能
    // ADSP2 ~ ADSP0:ADC预分频选择  000:2分频,001到111为2到128分频
    //               ADC在50~200KHz时钟时能获得最大精度
    ADCSRA = 0;

    // ADCC & ADCH
    // ADC转换结果寄存器,差分通道结果以2的补码形式表示,ADC数据必须读过
    // ADCH后才可进行数据更新。对于精度小于8位的左对齐数据可只读ADCH。
    // 数据右对齐(ADLAR = 0)
    // ADCH-------------------------------------------------------------
    // |   -   |   -   |   -   |   -   |   -   |   -   |  ADC9 |  ADC8 |
    // -----------------------------------------------------------------
    // ADCL-------------------------------------------------------------
    // |  ADC7 |  ADC6 |  ADC5 |  ADC4 |  ADC3 |  ADC2 |  ADC1 |  ADC0 |
    // -----------------------------------------------------------------
    //
}

void init_timer()
{
    //SFIOR
    // -----------------------------------------------------------------
    // |  TSM  |   -   |   -   |   -   |  ACME |  PUD  |  PSR0 | PSR321|
    // -----------------------------------------------------------------
    // TSM: T/C同步模式。置位时,PSR0和PSR321保持其数据直到被更新或TSM被清零
    // PSR0:T/C0预分频器复位,置位时使预频器复位,直到为0时表示复位完成
    // PSR321: T/C3、2、1预分频繁器复位,此位读总为0
    // ACME: 模拟比较器使能
    // PUD:所有端口上拉电阻禁止,置1为禁止
    SFIOR = 0;
}
void init_timer0()
{
    //TCCR0 T/C0控制寄存器
    // -----------------------------------------------------------------
    // |  FOC0 | WGM00 | COM01 | COM00 | WGM01 |  CS02 |  CS01 |  CS00 |
    // -----------------------------------------------------------------
    // FOC0:强制输出比较启动
    // WGM01, WGM00: 工作模式选择
    //              00:普通模式,01:PWM相位修正,
    //              10:比较匹配时清除计数器模式(CTC模式),11:快速PWM
    // COM01, COM00:比较匹配时的输出模式
    //          WGMxx为普通模式或CTC模式时
    //              00:OC0未连接,
    //              01:OC0取反,
    //              10:OC0清零,
    //              11:OC0置位
    //          WGMxx为相位修正PWM模式
    //              00:OC0未连接,
    //              01:保留,
    //              10:升序匹配时清零OC0;降序匹配时置位OC0,
    //              11:升序匹配时置位OC0;降序匹配时清零OC0
    //          WGMxx为快速PWM模式
    //              00:OC0未连接
    //              01:保留
    //              10:匹配时OC0清零;计数到TOP时OC0置位
    //              11:匹配时OC0置位;计数到TOP时OC0清零
    // CS02,CS01,CS00:T/C0时钟预分频选择
    //              000:无时钟,T/C不工作     001:1/1
    //              010:1/8     011:1/32     100:1/64
    //              101:1/128   110:1/256    111:1/1024
    TCCR0 = 0;

    //TCNT0 T/C0计数寄存器,8位
    //OCR0 输出比较寄存器,8位

    //TIMSK T/C中断屏蔽寄存器
    // -----------------------------------------------------------------
    // | OCIE2 | TOIE2 | TICIE1| OCIE1A| OCIE1B| TOIE1 | OCIE0 | TOIE0 |
    // -----------------------------------------------------------------
    // OCIE2:T/C2输出比较匹配中断使能
    // TOIE2:T/C2溢出中断使能
    // TICIE1:T/C1输入捕捉中断使能
    // OCIE1A:T/C1输出比较A匹配中断使能
    // OCIE1B:T/C1输出比较B匹配中断使能
    // TOIE1:T/C1溢出中断使能
    // OCIE0:T/C0输出比较匹配中断使能
    // TOIE0:T/C0溢出中断使能
    TIMSK = 0;

    //ETIMSK T/C扩展中断屏蔽寄存器
    // -----------------------------------------------------------------
    // |   -   |   -   | TICIE3| OCIE3A| OCIE3B| TOIE3 | OCIE3C| OCIE1C|
    // -----------------------------------------------------------------
    // TICIE3:T/C3输入捕捉中断使能
    // OCIE3A:T/C3输出比较A匹配中断使能
    // OCIE3B:T/C3输出比较B匹配中断使能
    // TOIE3:T/C3溢出中断使能
    // OCIE3C:T/C3输出比较C匹配中断使能
    // OCIE1C:T/C1输出比较C匹配中断使能
    ETIMSK = 0;
   
    //TIFR T/C中断标志寄存器
    // -----------------------------------------------------------------
    // |  OCF2 |  TOV2 |  ICF1 | OCF1A | OCF1B |  TOV1 |  OCF0 |  TOV0 |
    // -----------------------------------------------------------------
    // OCF2:T/C2输出比较匹配标志
    // TOV2:T/C2溢出标志
    // ICF1:T/C1输入捕捉标志位
    // OCF1A:T/C1输出比较A匹配标志位
    // OCF1B:T/C1输出比较B匹配标志位
    // TOV1:T/C1溢出标志
    // OCF0:T/C0输出比较匹配标志
    // TOV0:T/C0溢出标志

    //ETIFR 扩展的T/C中断标志寄存器
    // -----------------------------------------------------------------
    // |   -   |   -   |  ICF3 | OCF3A | OCF3B |  TOV3 | OCF3C | OCF1C |
    // -----------------------------------------------------------------
    // ICF3:T/C3输入捕捉匹配标志位
    // OCF3A:T/C3输出比较A匹配标志位
    // OCF3B:T/C3输出比较B匹配标志位
    // TOV3:T/C3溢出标志位
    // OCF3C:T/C3输出比较C匹配标志位
    // OCF1C:T/C1输出比较C匹配标志位

    //ASSR T/C0异步状态寄存器
    // -----------------------------------------------------------------
    // |   -   |   -   |   -   |   -   |  AS0  | TCN0UB| OCR0UB| TCR0UB|
    // -----------------------------------------------------------------
    // AS0:T/C0使用外部时钟
    // TCN0UB:TCNT0更新中,写TCNT0时将置位,为0时表明TCNT0可以写入新值
    // OCR0UB:OCR0更新中,写OCR0时将置位,为0表明OCR0可以写入新值
    // TCR0UB:TCCR0更新中,写TCCR0时将置位,为0表明TCCR0可以写入新值
    ASSR = 0;
}

void init_timer2()
{   
    //TCCR2 T/C2控制寄存器
    // -----------------------------------------------------------------
    // |  FOC2 | WGM20 | COM21 | COM20 | WGM21 |  CS22 |  CS21 |  CS20 |
    // -----------------------------------------------------------------
    // FOC2:强制输出比较启动
    // WGM21, WGM20: 工作模式选择
    //              00:普通模式,01:PWM相位修正,
    //              10:比较匹配时清除计数器模式(CTC模式),11:快速PWM
    // COM21, COM20:比较匹配时的输出模式
    //          WGMxx为普通模式或CTC模式时
    //              00:OC0未连接,
    //              01:OC0取反,
    //              10:OC0清零,
    //              11:OC0置位
    //          WGMxx为相位修正PWM模式
    //              00:OC0未连接,
    //              01:保留,
    //              10:升序匹配时清零OC0;降序匹配时置位OC0,
    //              11:升序匹配时置位OC0;降序匹配时清零OC0
    //          WGMxx为快速PWM模式
    //              00:OC0未连接
    //              01:保留
    //              10:匹配时OC0清零;计数到TOP时OC0置位
    //              11:匹配时OC0置位;计数到TOP时OC0清零
    // CS22,CS21,CS20:T/C0时钟预分频选择
    //              000:无时钟,T/C不工作     001:1/1
    //              010:1/8     011:1/32     100:1/64
    //              101:1/128   110:1/256    111:1/1024
    TCCR2 = 0;

    //TCNT2 T/C2计数寄存器,8位
    //OCR2 T/C2比较寄存器,8位
}

void init_timer1()
{
    //TCCR1A T/C1控制寄存器A
    // -----------------------------------------------------------------
    // | COM1A1| COM1A0| COM1B1| COM1B0| COM1C1| COM1C0| WGM11 | WGM10 |
    // -----------------------------------------------------------------
    //TCCR1B T/C1控制寄存器B
    // -----------------------------------------------------------------
    // | ICNC1 | ICES1 |   -   | WGM13 | WGM12 |  CS12 |  CS11 |  CS10 |
    // -----------------------------------------------------------------
    //TCCR1C T/C1控制寄存器C
    // -----------------------------------------------------------------
    // | FOC1A | FOC1B | FOC1C |   -   |   -   |   -   |   -   |   -   |
    // -----------------------------------------------------------------
    // COM1A1,COM1A0:通道A的比较输出模式
    // COM1B1,COM1B0:通道B的比较输出模式
    // COM1C1,COM1C0:通道C的比较输出模式
    // WGM13,WGM12,WGM11,WGM10:波型发生模式:
    //              比较输出模式(CTC模式),非PWM
    //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01  比较匹配时OC1A/OC1B/OC1C电平取反
    //                  10  比较匹配时清零OC1A/OC1B/OC1C(输出低电平)
    //                  11  比较匹配时置位OC1A/OC1B/OC1C(输出高电平)
    //              比较输出模式(CTC模式),快速PWM
    //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01  WGM13为0时同上,为1时比较匹配时 OC1A电平取反,OC1B/OC1C保留
    //                  10  比较匹配时OC1A/OC1B/OC1C清零,在TOP时OC1A/OC1B/OC1C置位
    //                  11  比较匹配时OC1A/OC1B/OC1C置位,在TOP时OC1A/OC1B/OC1C清零
    //              比较输出模式(CTC模式),相位修正及相频修正PWM
    //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    //                  01  WGM13为0:同上,为1时比较匹配时 OC1A电平取反,OC1B/OC1C保留
    //                  10  升序计数匹配时将OC1A/OC1B/OC1C清零,降序计数匹配时将OC1A/OC1B/OC1C置位
    //                  11  升序计数匹配时将OC1A/OC1B/OC1C置位,降序计数匹配时将OC1A/OC1B/OC1C清零
    //
    //   模式 WGM1x   工作模式说明     TOP   OCR1x更新时刻  TOVn置位时刻
    //     0   0000       普通模式    0xFFFF        立即            MAX
    //     1   0001   8位相位修正PWM  0x00FF         TOP         BOTTOM
    //     2   0010   9位相位修正PWM  0x01FF         TOP         BOTTOM
    //     3   0011  10位相位修正PWM  0x03FF         TOP         BOTTOM
    //     4   0100              CTC   OCRnA        立即            MAX
    //     5   0101       8位快速PWM  0x00FF         TOP            TOP
    //     6   0110       9位快速PWM  0x01FF         TOP            TOP
    //     7   0111      10位快速PWM  0x03FF         TOP            TOP
    //     8   1000  相位频率修正PWM    ICRn      BOTTOM         BOTTOM
    //     9   1001  相位频率修正PWM   OCRnA      BOTTOM         BOTTOM
    //    10   1010      相位修正PWM    ICRn         TOP         BOTTOM
    //    11   1011      相位修正PWM   OCRnA         TOP         BOTTOM
    //    12   1100              CTC    ICRn        立即            MAX
    //    13   1101             保留      -          -               -
    //    14   1110          快速PWM    ICRn         TOP            TOP
    //    15   1111          快速PWM   OCRnA         TOP            TOP
    // ICNC1:使能/禁止输入捕捉噪声抑制器
    // ICES1:输入捕获触发沿选择,0为下降沿触发,1为上升沿触发
    // CS12,CS11,CS10:T/C0时钟预分频选择
    //              000:无时钟,T/C不工作     001:1/1
    //              010:1/8     011:1/64     100:1/256
    //              101:1/1024  110:外部T1脚下降沿驱动    111:外部T1脚上升沿驱动
    // FOC1A,FOC1B,FOC1C:强制输出比较通道A,B,C
    TCCR1A = TCCR1B = TCCR1C = 0;

    //TCNT1H,TCNT1L 定时/计数器1
    //OCR1AH,OCR1AL 输出比较寄存器1A
    //OCR1BH,OCR1BL 输出比较寄存器1B
    //OCR1CH,OCR1CL 输出比较寄存器1C

    //ICR1H,ICR1L 输入捕捉寄存器1
}

void init_timer3()
{
    //TCCR3A T/C3控制寄存器A
    // -----------------------------------------------------------------
    // | COM3A1| COM3A0| COM3B1| COM3B0| COM3C1| COM3C0| WGM31 | WGM30 |
    // -----------------------------------------------------------------
    //TCCR3B T/C3控制寄存器B
    // -----------------------------------------------------------------
    // | ICNC3 | ICES3 |   -   | WGM33 | WGM32 |  CS32 |  CS31 |  CS30 |
    // -----------------------------------------------------------------
    //TCCR3C T/C3控制寄存器C
    // -----------------------------------------------------------------
    // | FOC3A | FOC3B | FOC3C |   -   |   -   |   -   |   -   |   -   |
    // -----------------------------------------------------------------
    // COM3A1,COM3A0:通道A的比较输出模式
    // COM3B1,COM3B0:通道B的比较输出模式
    // COM3C1,COM3C0:通道C的比较输出模式
    // WGM33,WGM32,WGM31,WGM30:波型发生模式:
    //              比较输出模式(CTC模式),非PWM
    //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    //                  01  比较匹配时OC3A/OC3B/OC3C电平取反
    //                  10  比较匹配时清零OC3A/OC3B/OC3C(输出低电平)
    //                  11  比较匹配时置位OC3A/OC3B/OC3C(输出高电平)
    //              比较输出模式(CTC模式),快速PWM
    //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    //                  01  WGM13为0时同上,为1时比较匹配时 OC3A电平取反,OC3B/OC3C保留
    //                  10  比较匹配时OC3A/OC3B/OC3C清零,在TOP时OC3A/OC3B/OC3C置位
    //                  11  比较匹配时OC3A/OC3B/OC3C置位,在TOP时OC3A/OC3B/OC3C清零
    //              比较输出模式(CTC模式),相位修正及相频修正PWM
    //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    //                  01  WGM13为0:同上,为1时比较匹配时 OC3A电平取反,OC3B/OC3C保留
    //                  10  升序计数匹配时将OC3A/OC3B/OC3C清零,降序计数匹配时将OC3A/OC3B/OC3C置位
    //                  11  升序计数匹配时将OC3A/OC3B/OC3C置位,降序计数匹配时将OC3A/OC3B/OC3C清零
    //
    //   模式 WGM3x   工作模式说明     TOP   OCR1x更新时刻  TOVn置位时刻
    //     0   0000       普通模式    0xFFFF        立即            MAX
    //     1   0001   8位相位修正PWM  0x00FF         TOP         BOTTOM
    //     2   0010   9位相位修正PWM  0x01FF         TOP         BOTTOM
    //     3   0011  10位相位修正PWM  0x03FF         TOP         BOTTOM
    //     4   0100              CTC   OCRnA        立即            MAX
    //     5   0101       8位快速PWM  0x00FF         TOP            TOP
    //     6   0110       9位快速PWM  0x01FF         TOP            TOP
    //     7   0111      10位快速PWM  0x03FF         TOP            TOP
    //     8   1000  相位频率修正PWM    ICRn      BOTTOM         BOTTOM
    //     9   1001  相位频率修正PWM   OCRnA      BOTTOM         BOTTOM
    //    10   1010      相位修正PWM    ICRn         TOP         BOTTOM
    //    11   1011      相位修正PWM   OCRnA         TOP         BOTTOM
    //    12   1100              CTC    ICRn        立即            MAX
    //    13   1101             保留      -          -               -
    //    14   1110          快速PWM    ICRn         TOP            TOP
    //    15   1111          快速PWM   OCRnA         TOP            TOP
    // ICNC3:使能/禁止输入捕捉噪声抑制器
    // ICES3:输入捕获触发沿选择,0为下降沿触发,1为上升沿触发
    // CS32,CS31,CS30:T/C0时钟预分频选择
    //              000:无时钟,T/C不工作     001:1/1
    //              010:1/8     011:1/64     100:1/256
    //              101:1/1024  110:外部T1脚下降沿驱动    111:外部T1脚上升沿驱动
    // FOC3A,FOC3B,FOC3C:强制输出比较通道A,B,C
    TCCR3A = TCCR3B = TCCR3C = 0;

    //TCNT3H,TCNT3L 定时/计数器3

    //OCR3AH,OCR3AL 输出比较寄存器3A
    //OCR3BH,OCR3BL 输出比较寄存器3B
    //OCR3CH,OCR3CL 输出比较寄存器3C

    //ICR3H,ICR3L 输入捕捉寄存器3
}

void init_uart(void)
{
    //UDRn USART I/O数据寄存器, 不可用读修改写命令操作, 否则会改变FIFO状态

    //UCSRnA USART控制和状态寄存器A
    // -----------------------------------------------------------------
    // |  RXCn |  TXCn | UDREn |  FEn  |  DORn |  UPEn |  U2Xn | MPCMn |
    // -----------------------------------------------------------------
    // RXCn:USART接收结束标志
    // TXCn:USART发送结束标志,写1可清除
    // UDREn:USART数据寄存器为空标志,只有该标志为1才数据才可写入UDR0
    // FEn:帧错误,未正确收到停止位
    // DORn:数据过速
    // UPEn:奇偶效验错误
    // U2Xn:倍速发送,仅对异步操作有影响
    // MPCMn:多处理器通讯模式

    //UCSRnB USART控制和状态寄存器B
    // -----------------------------------------------------------------
    // | RXCIEn| TXCIEn| UDRIEn| RXENn | TXENn | UCSZn2| RXB8n | TXB8n |
    // -----------------------------------------------------------------
    // RXCIEn:接收结束中断使能
    // TXCIEn:发送结束中断使能
    // UDRIEn:USART数据寄存器空中使能
    // RXENn:接收使能
    // TXENn:发送使能
    // UCSZn2:字符长度,具体见下面
    // RXB8n:接收数据位8
    // TXB8n:发送数据位8

    //UCSRxC USART控制和状态寄存器C
    // -----------------------------------------------------------------
    // |   -   | UMSELn| UPMn1 | UPMn0 | USBSn | UCSZn1| UCXZn0| UCPOLn|
    // -----------------------------------------------------------------
    // UMSELn:模式选择,0为异步操作,1为同步操作
    // UPMn1,UPMn0:奇偶效验模式,00禁止,01保留,10偶效验,11奇校验
    // USBSn:停止位选择,0为1位停止位,1为2位停止位
    // UCSZn2,UCSZn0:字符长度,000为5位, 001为 6位,010为7位, 011为8位
    //                         100为保留,101为保留,110为保留,111为9位
    // UCPOLn:时钟极性,(异步模式应清零)
    //                              UCPOL0   发送数据位置   接收数据位置
    //                                0        XCK0上升沿    XCK0下降沿
    //                                1        XCK0下降沿    XCK0上升沿

    //UBRRnL和UBRRnH USART波特率寄存器, UBRRnH15:12为保留位:
    // -----------------------------------------------------------------
    // |   -   |   -   |   -   |   -   | BIT11 | BIT10 | BIT09 | BIT08 |
    // -----------------------------------------------------------------
    // -----------------------------------------------------------------
    // | BIT07 | BIT06 | BIT05 | BIT04 | BIT03 | BIT02 | BIT01 | BIT00 |
    // -----------------------------------------------------------------

}   

void init_spi(void)
{
    //SPCR SPI控制寄存器
    // -----------------------------------------------------------------
    // |  SPIE |  SPE  |  DORD |  MSTR |  CPOL |  CPHA |  SPR1 | SPR0  |
    // -----------------------------------------------------------------
    // SPIE:SPI中断使能
    // SPE:SPI使能
    // DORD:数据次序,为1时LSB先发送
    // MSTR:是否主机模式,若为主机模式,SS引脚配置为输入,但被拉低则MSTR被清零
    // SPSR的SPIF位置位。用户必须重新设置MSTR位进入主机模式。
    // CPOL:时钟极性,为1时表示空闲时SCK为高电平,否则为低电平。
    // CPHA:时钟相位,为0时为时钟的起始沿采样数据,否则为终止沿采样数据
    // SPR1,SPR0:SPI时钟速率选择:00  1/4, 01  1/16, 10  1/64, 11  1/128

    //SPSR SPI状态寄存器
    // -----------------------------------------------------------------
    // |  SPIF |  WCOL |   -   |   -   |   -   |   -   |   -   | SPI2X |
    // -----------------------------------------------------------------
    // SPIF:SPI中断标志,串行发送结束后此位置位,对于查询方式,可先读SPSR,紧着
    //       访问SPDR来对SPIF位清零。
    // WCOL:写冲突标志,可通过先读SPSR,紧接着访问SPDR来清零。
    // SPI2X:SPI倍速,若为主机,SCK最高频率可达CPU频率一半,从机则只能保证为1/4
   
    //SPDR SPI数据寄存器
    // -----------------------------------------------------------------
    // |  MSB  |       |       |       |       |       |       |  LSB  |
    // -----------------------------------------------------------------
    // SPDR为可读写寄存器,写则将启动数据传输,读则读取接收缓冲器
}   

void init_twi(void)
{
    //TWBR TWI比特率寄存器
    // -----------------------------------------------------------------
    // |  BIT7 |  BIT6 |  BIT5 |  BIT4 |  BIT3 |  BIT2 |  BIT1 |  BIT0 |
    // -----------------------------------------------------------------
    // SCL频率 = CUP时钟频率/(16 + 2 * TWBR * 4 ^ TWPS)
    // TWBR值应该不小于10, TWPS为预分频值

    //TWCR TWI控制寄存器
    // -----------------------------------------------------------------
    // | TWINT |  TWEA | TWSTA | TWSTO |  TWWC |  TWEN |   -   |  TWIE |
    // -----------------------------------------------------------------
    // TWINT:TWI中断标志,TWINT标志必须由软件写1清除, 即使在中断服务程序中硬件也不会自动清除
    //        在清除TWI标志前一定要首先完成对TWAR TWSR TWDR的访问, 此位清零后TWI立即开始工作。
    // TWEA:使能TWI应答,此位控制应答脉冲的产生。
    // TWSTA:START状态位,自己想成为主机时置此位,发送START后软件必须清零TWSTA。
    // TWSTO:STOP状态位。主模式下,置此位将在总线上产生STOP状态,后TWSTO自动清零;从机模式下
    //        置此位可使接口从错误状态恢复到未被寻址的状态,此时总线上不会产生STOP状态。
    // TWWC:TWI写冲突标志。每次写TWDR时都将更新此标志。
    // TWEN:TWI使能位。置1时TWI引脚将从IO引脚切换到SCL和SDA引脚。
    // TWIE:TWI中断使能。
   
    //TWSR TWI状态寄存器
    // -----------------------------------------------------------------
    // |  TWS7 |  TWS6 |  TWS5 |  TWS4 |  TWS3 |   -   | TWPS1 | TWPS0 |
    // -----------------------------------------------------------------
    // TWS7~TWS3:TWI状态
    // TWPS1~TWPS0:TWI预分频值。00:1; 01:1/4; 10:1/16; 11:1/64。
   
    //TWDR TWI数据寄存器
    // -----------------------------------------------------------------
    // |  BIT7 |  BIT6 |  BIT5 |  BIT4 |  BIT3 |  BIT2 |  BIT1 |  BIT0 |
    // -----------------------------------------------------------------
    // 发送模式,TWDR中包含了要发送的字节,接收模式TWDR包含了接收到的数据。
    // 只要TWINT置位,TWDR的数据就是稳定的。

    //TWAR TWI从机地址寄存器
    // -----------------------------------------------------------------
    // |  TWA6 |  TWA5 |  TWA4 |  TWA3 |  TWA2 |  TWA1 |  TWA0 | TWGCE |
    // -----------------------------------------------------------------
    // TWA6~TWA0:TWI从机地址寄存器
    // TWGCE:使能TWI广播识别
}

    //GICR 通用中断控制寄存器
    // -----------------------------------------------------------------
    // |  INT1 |  INT0 |  INT2 |   -   |   -   |   -   | IVSEL |  IVCE |
    // -----------------------------------------------------------------
    // INT1:使能外部中断1请求
    // INT0:使能外部中断0请求
    // INT2:使能外部中断2请求
    // IVSEL:中断向量选择,为0时中断向量位于FLASH起始地址,为1时位于BOOT区起始地址
    // IVCE:中断向量修改使能。改变IVSEL时IVCE必须置位。

    //MCUCR MCU控制寄存器
    // -----------------------------------------------------------------
    // |  SM2  |   SE  |  SM1  |  SM0  | ISC11 | ISC10 | ISC01 | ISC00 |
    // -----------------------------------------------------------------
    // SM2, SM1, SM0:000:空闲模式  
    //                001:ADC噪声抑制模式
    //                010:掉电模式
    //                011:省电模式
    //                100:保留
    //                101:保留
    //                110:Standby模式
    //                111:扩展Standby模式
    //SE:休眠使能
    //ISC11, ISC10: 00:INT1为低电平时产生中断请求
    //               01:INT1引脚上任意的逻辑电平变化都将引发中断
    //               10:INT1的下降沿产生异步中断请求
    //               11:INT1的上升沿产生异步中断请求
    //ISC01, ISC00:  00:INT0为低电平时产生中断请求
    //               01:INT0引脚上任意的逻辑电平变化都将引发中断
    //               10:INT0的下降沿产生异步中断请求
    //               11:INT0的上升沿产生异步中断请求

    //MCUCSR MCU控制和状态寄存器
    // -----------------------------------------------------------------
    // |  JTD  |   -   |   -   |  JTRF |  WDRF |  BORF | FXTRF |  PORF |
    // -----------------------------------------------------------------
    // JTD:
    // JTRF:JTAG复位标志
    // WDRF:看门狗复位标志
    // BORF:掉电检测复位标志
    // EXTRF:外部复位标志
    // PORF:上电复位标志

    //WDTCR 看门狗定时器控制寄存器
    // -----------------------------------------------------------------
    // |   -   |   -   |   -   |  WDCE |  WDE  |  WDP2 |  WDP1 |  WDP0 |
    // -----------------------------------------------------------------
    // WDCE:看门狗修改使能,清零WDE位时必须先置位WDCE位,否则不能禁止看门狗
    // WDE:看门狗使能,只有WDCE为1时WDE才能清零
    // WDP2~WDP0:看门狗定时器预分频值   WDT振荡周期  VCC=3V时溢出时间  VCC=5V时溢出时间
    //                            000:     16K            14.8ms            14.0ms
    //                            001:     32K            29.6ms            28.1ms
    //                            010:     64K            59.1ms            56.2ms
    //                            011:    128K             0.12s             0.11s
    //                            100:    256K             0.24s             0.22s
    //                            101:    512K             0.47s             0.45s
    //                            110:   1024K             0.95s             0.9s
    //                            111:   2048K             1.9s              1.8s

    //EEARH/EEARL EEPROM地址寄存器
    //EEARH
    // -----------------------------------------------------------------
    // |   -   |   -   |   -   |   -   | EEAR11| EEAR10| EEAR9 | EEAR8 |
    // -----------------------------------------------------------------
    //EEARL
    // -----------------------------------------------------------------
    // | EEAR7 | EEAR6 | EEAR5 | EEAR4 | EEAR3 | EEAR2 | EEAR1 | EEAR0 |
    // -----------------------------------------------------------------
    //EEPROM地址,在访问EEPROM前必须为其赋予正确的数据

    //EEDR EEPROM数据寄存器   
    // -----------------------------------------------------------------
    // |  MSB  |  ...  |  ...  |  ...  |  ...  |  ...  |  ...  |  LSB  |
    // -----------------------------------------------------------------
   
    //EECR EEPROM控制寄存器
    // -----------------------------------------------------------------
    // |   -   |   -   |   -   |   -   | EERIE | EEMWE |  EEWE |  EERE |
    // -----------------------------------------------------------------
    //EERIE:EEPROM就绪中断使能
    //EEMWE:EEPROM主机写使能,当此位为1时,在4个时钟内EEWE置位,数据将写入EEPROM
    //          EEMWE置位4个时钟后硬件将其清零
    //EEWE:EEPROM写使能
    //EERE:EEPROM读使能。当EEPROM地址设置好后,需置位EERE以便将数据读入EEAR
    //EEPROM写时序:
    //a等待EEWE位为0
    //b等待SPMCSR的SPMEN位为0,此步只在软件包含引导程序,且允许CPU对Flash编程时才有用
    //c将新的EEPROM地址写入EEAR
    //d将新的EEPROM数据写入EEDR
    //e对EECR的EEMWE位写1,同时清零EEWE位
    //f在置位EEMWE位的4个周期内置位EEWE位

七、AVR移位算法详细解释(1<<X)

很多初学者都会被移位算法迷惑,移位算法形如(1<<X)这样的形式,高手写程序时,习惯用移位算法来写出各个寄存器的使用。比如下面一段是AVR 的USART 的初始化代码。​​​​​​​

UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UCSR0B = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); // RXCIE=1;TXCIE=1;UDREIE=0;RXEN=1;TXEN=1

这样的写法对高手是福,这些代码里面说明了操作了寄存器的哪些位,能够看出它的操作的意义;对新手确是祸害,因为新手看不懂这样的程序。


回到开始的地方,解释一下,什么是移位算法:

如:A = (1<<2),1写成二进制就是0000 0001,这个一左移2位就是0000 0100,所以得到的数A为0000 0100,即0x04。

再如:B = (2<<4),2写成二进制就是0000 0010,这个一左移4位就是0010 0000,所以得到的数B为0010 0000,即0x20。

上面两个移位算法都是正确的,第一种写法,表示第三位为1其余都是0的数,数的时候是从0数起的,再比如(1<<0)表示的是0000 0001,(1<<7)表示的是1000 0000,但是第二种写法没有没有这种意义,移位也用于乘除法,左移一位乘以2,右移移位除以2,上面的第二种写法2左移四位得到的数是2×2×2×2×2=32,也就是上面的0x20。


我们再来看上面的这句话:UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

UCSRC是一个和串口通讯有关的一个八位寄存器,他的每一位都有特殊的定义,我们通过查数据手册可以看到,如下的内容。

avr studio,单片机(汇编与C代码)、PLC,AVR

我们在程序中包含的头文件iom16v.h类似的文件会有#define URSEL 7 这样的定义,1<<URSEL即是位7,1<<UCSZ1选择位2,1<<UCSZ0选择位1,整句话UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);的效果就是让UCSRC的位七,位二,位一为高,其他都为低,然后在数据手册里面你可以看到各个位的作用。UCSRC = (1<<7)|(1<<2)|(1<<1) 即UCSRC = 1000 0110。文章来源地址https://www.toymoban.com/news/detail-741669.html


到了这里,关于AVR单片机及其开发环境的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Atmel Studio开发Arduino的ATmega328P单片机

    摘要 :我们知道Arduino开发板常用的芯片是Atmel公司生产的AVR微控制器系列。最常见的是ATmega328P,被广泛用于Arduino Uno开发板。其他常用的AVR芯片包括ATmega2560和ATmega32U4。使用Arduino平台开发AVR的单片机非常方便。Arduino IDE提供了一个非常简洁、易于使用的开发环境,使编写和上

    2024年02月05日
    浏览(42)
  • 为STC32单片机搭建开发环境

            自去年起,STC推出了51内核的32位单片机,但是单纯的51内核已经驾驭不了32位总线了。因此STC32单片机才用的是251内核,多了一个2,使得底层指令从111条扩充到了268条,这或许意味着以后的STC单片机会有更广大的想象空间?         也因此,STC32的开发环境与传统

    2024年02月08日
    浏览(94)
  • 辉芒微(FMD)单片机开发环境搭建

    为了节省成本,最近使用一款辉芒微的MCU,在此之前其实我都不知道这个公司,而且不管是官网还是网上其他相关的资料都不是很多,所以也是折腾了一番才把环境搭好,于是这里就出一篇博客,记录一下整个开发环境的搭建。 关于辉芒微的产品以及工具,可以自行到官网查

    2024年01月23日
    浏览(54)
  • HT32合泰单片机开发环境搭建和配置教程

    HT32合泰(Holtek)单片机开发环境搭建安装教程 最近在准备合泰杯的比赛,在看合泰官方的PPT和数据手册学习,顺便做个合泰单片机的开发环境搭建教程。 合泰杯比赛发放的开发板是ESK32-30501,用的单片机是HT32F52352。 合泰杯官网地址:https://url.zeruns.tech/S7xu8 合泰官方HT32F52352授课

    2024年02月02日
    浏览(41)
  • 一、灵动mm32单片机_开发环境的搭建(Keil)

    略。 (1)这里以MM32F0130单片机为例。 (2)进入灵动微电子官网。上海灵动微电子股份有限公司 (3)点击“支持”→“KEILPacl”。 (3)点击下载Pack包。 (4)下载后,解压下载的压缩包,找到对应的Pack包,双击安装即可。 (1)点击“支持”→“评估开发板”。 (2)选择对应的开发板。 (3)点

    2024年02月08日
    浏览(51)
  • 51单片机开发环境搭建 - VS Code 从编写到烧录

    我安装并测试成功的环境: 操作系统:Windows 10 (22H2) 单片机:STC89C52RC Python version: 3.7.6 在这之前,给51单片机写程序是用 Keil 5(编写+编译)、STC-ISP(烧录),由于切换应用比较麻烦,并且不够美观,所以尝试使用熟悉的 Visual Studio Code 来完成这些操作。 stcgal 是用来向STC单片

    2023年04月24日
    浏览(62)
  • 51单片机(STC8) -- 开发环境搭建(Keil C51)

    STC8H3K系列芯片概述 文章中所用的芯片选型为STC8H3K64S4,后续STC8案例均以该芯片展开 内核 • 超高速 8051 内核(1T),比传统 8051 约快 12 倍以上,指令代码完全兼容传统8051 • 21个中断源,4 级中断优先级 • 支持在线仿真 工作电压 • 1.9V~5.5V 工作温度 • -40℃~85℃ Flash 存储

    2024年01月25日
    浏览(52)
  • 在VSCode平台上使用Embedded IDE搭建单片机开发环境

    本文介绍了如何在VSCode平台上通过Embedded IDE插件搭建单片机开发环境,包括软件安装、插件配置、编译器安装和项目构建等步骤。

    2023年04月08日
    浏览(63)
  • 单片机(一):VScode+SDCC+Make的Windows下51(CH552)单片开发环境搭建

    CH552芯片是一款兼容 MCS51 指令集的增强型 E8051 内核单片机。CH552既然是51单片机,按照以前的惯例都是用Keil来进行开发。但是本次决定抛弃Keil的开发环境,主要原因是Keil为商业软件,普通用户难以支撑,并且Keil软件本身的界面丑、编辑器不智能等,这导致软件的使用体验非

    2024年02月01日
    浏览(114)
  • 零基础 Ubuntu 20.04.01 下搭建51单片机开发环境[开源编译器SDCC]

    原创首发于CSDN,转载请注明出处,谢谢! 个人初步学习51单片机的时,所能接触到的教程基本都是在Windows环境下使用Keil开发。诚然,Keil确实是一款强大的开发软件,但博主个人受限于以下因素: 个人使用的是苹果电脑 MacBook Air; 所装的VM虚拟机里已经安装了 Ubuntu 20.04.01。

    2023年04月24日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包