• 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<


    一、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、设置包含文件(头文件)路径 

    5、设置库文件路径 

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

    如此便可使用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的周期延时。

    然后就是下面的操作了:

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

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

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

    补充一下:

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

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

    1. void  delay_ms(uint k)
    2. {
    3.   uint  i,j;
    4.   for(i=0;i
    5.     for(j=0;j<1140;j++);
    6. }

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

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

     

    1. void  delay_1ms()
    2. {
    3.   uint i;
    4.   for(i=1;i<(uint)(xtal*143-2);i++)
    5.     ;
    6. }

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

    1. void  delay_nms(uint n)
    2. {
    3.   uint i=0;
    4.   while(i
    5.   {
    6.     delay_1ms();
    7.     i++;
    8.   }
    9. }

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

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

    五、AVR JTAG ICE MKII仿真器

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

    六、AVR寄存器定义

    1. #include "iom16v.h"
    2. #include "macros.h"
    3. void initialize()
    4. {
    5.     // DDRx端口方向寄存器,PORTx数据寄存器,PINx输入引脚寄存器
    6.     // DDRxn相应位为1,引脚为输出否则为输入
    7.     // PORTxn为1时,上拉电阻使能
    8.     DDRA = 0x00;
    9. }
    10. void init_adc()
    11. {
    12.     // ADMUX
    13.     // -----------------------------------------------------------------
    14.     // | REFS1 | REFS0 | ADLAR |  MUX4 |  MUX3 |  MUX2 |  MUX1 |  MUX0 |
    15.     // -----------------------------------------------------------------
    16.     // REFS1 REFS0: 00,使用AREF,内部参考电压关闭
    17.     //              01,AVCC、AREF引脚外加滤波电容
    18.     //                 10,保留
    19.     //                 11,2.56V片内基准电压,AREF引脚外加滤波电容
    20.     // ADLAR: ADC转换结果左对齐
    21.     //  MUX4 ~  MUX0   单端输入  正差分输入   负差分输入   增益
    22.     // 00000 ~ 00111  ADC0~ADC7
    23.     //   01000                   ADC0         ADC0         10x
    24.     //   01001                   ADC1         ADC0         10x
    25.     //   01010                   ADC0         ADC0        200x                  
    26.     //   01011                   ADC1         ADC0        200x
    27.     //   01100                   ADC2         ADC2         10x
    28.     //   01101                   ADC3         ADC2         10x
    29.     //   01110                   ADC2         ADC2        200x
    30.     //   01111                   ADC3         ADC2        200x
    31.     //   10000                   ADC0         ADC1          1x
    32.     //   10001                   ADC1         ADC1          1x
    33.     //   10010                   ADC2         ADC1          1x
    34.     //   10011                   ADC3         ADC1          1x
    35.     //   10100                   ADC4         ADC1          1x
    36.     //   10101                   ADC5         ADC1          1x
    37.     //   10110                   ADC6         ADC1          1x
    38.     //   10111                   ADC7         ADC1          1x
    39.     //   11000                   ADC0         ADC2          1x
    40.     //   11001                   ADC1         ADC2          1x
    41.     //   11010                   ADC2         ADC2          1x
    42.     //   11011                   ADC3         ADC2          1x
    43.     //   11100                   ADC4         ADC2          1x
    44.     //   11101                   ADC5         ADC2          1x
    45.     //   11110       1.23V(VBG)
    46.     //   11111        0V(GND)                                                                                                                                    
    47.      ADMUX = 0;
    48.     // ADCSRA
    49.     // -----------------------------------------------------------------
    50.     // |  ADEN |  ADSC |  ADFR |  ADIF |  ADIE | ADPS2 | ADPS1 | ADPS0 |
    51.     // -----------------------------------------------------------------
    52.     // ADEN:ADC使能,转换过程中禁止ADC则立即中止转换。
    53.     // ADSC:ADC开始转换。在转换过程中ADSC为1直到转换结束。
    54.     // ADFR:是否工作在连续模式,该位写0,停止连续转换模式。
    55.     // ADIF:ADC中断标志。中断服务硬件清零。
    56.     // ADIE:ADC中断使能
    57.     // ADSP2 ~ ADSP0:ADC预分频选择  000:2分频,001到111为2到128分频
    58.     //               ADC在50~200KHz时钟时能获得最大精度
    59.     ADCSRA = 0;
    60.     // ADCC & ADCH
    61.     // ADC转换结果寄存器,差分通道结果以2的补码形式表示,ADC数据必须读过
    62.     // ADCH后才可进行数据更新。对于精度小于8位的左对齐数据可只读ADCH。
    63.     // 数据右对齐(ADLAR = 0)
    64.     // ADCH-------------------------------------------------------------
    65.     // |   -   |   -   |   -   |   -   |   -   |   -   |  ADC9 |  ADC8 |
    66.     // -----------------------------------------------------------------
    67.     // ADCL-------------------------------------------------------------
    68.     // |  ADC7 |  ADC6 |  ADC5 |  ADC4 |  ADC3 |  ADC2 |  ADC1 |  ADC0 |
    69.     // -----------------------------------------------------------------
    70.     //
    71. }
    72. void init_timer()
    73. {
    74.     //SFIOR
    75.     // -----------------------------------------------------------------
    76.     // |  TSM  |   -   |   -   |   -   |  ACME |  PUD  |  PSR0 | PSR321|
    77.     // -----------------------------------------------------------------
    78.     // TSM: T/C同步模式。置位时,PSR0和PSR321保持其数据直到被更新或TSM被清零
    79.     // PSR0:T/C0预分频器复位,置位时使预频器复位,直到为0时表示复位完成
    80.     // PSR321: T/C3、2、1预分频繁器复位,此位读总为0
    81.     // ACME: 模拟比较器使能
    82.     // PUD:所有端口上拉电阻禁止,置1为禁止
    83.     SFIOR = 0;
    84. }
    85. void init_timer0()
    86. {
    87.     //TCCR0 T/C0控制寄存器
    88.     // -----------------------------------------------------------------
    89.     // |  FOC0 | WGM00 | COM01 | COM00 | WGM01 |  CS02 |  CS01 |  CS00 |
    90.     // -----------------------------------------------------------------
    91.     // FOC0:强制输出比较启动
    92.     // WGM01, WGM00: 工作模式选择
    93.     //              00:普通模式,01:PWM相位修正,
    94.     //              10:比较匹配时清除计数器模式(CTC模式),11:快速PWM
    95.     // COM01, COM00:比较匹配时的输出模式
    96.     //          WGMxx为普通模式或CTC模式时
    97.     //              00:OC0未连接,
    98.     //              01:OC0取反,
    99.     //              10:OC0清零,
    100.     //              11:OC0置位
    101.     //          WGMxx为相位修正PWM模式
    102.     //              00:OC0未连接,
    103.     //              01:保留,
    104.     //              10:升序匹配时清零OC0;降序匹配时置位OC0,
    105.     //              11:升序匹配时置位OC0;降序匹配时清零OC0
    106.     //          WGMxx为快速PWM模式
    107.     //              00:OC0未连接
    108.     //              01:保留
    109.     //              10:匹配时OC0清零;计数到TOP时OC0置位
    110.     //              11:匹配时OC0置位;计数到TOP时OC0清零
    111.     // CS02,CS01,CS00:T/C0时钟预分频选择
    112.     //              000:无时钟,T/C不工作     001:1/1
    113.     //              010:1/8     011:1/32     100:1/64
    114.     //              101:1/128   110:1/256    111:1/1024
    115.     TCCR0 = 0;
    116.     //TCNT0 T/C0计数寄存器,8位
    117.     //OCR0 输出比较寄存器,8位
    118.     //TIMSK T/C中断屏蔽寄存器
    119.     // -----------------------------------------------------------------
    120.     // | OCIE2 | TOIE2 | TICIE1| OCIE1A| OCIE1B| TOIE1 | OCIE0 | TOIE0 |
    121.     // -----------------------------------------------------------------
    122.     // OCIE2:T/C2输出比较匹配中断使能
    123.     // TOIE2:T/C2溢出中断使能
    124.     // TICIE1:T/C1输入捕捉中断使能
    125.     // OCIE1A:T/C1输出比较A匹配中断使能
    126.     // OCIE1B:T/C1输出比较B匹配中断使能
    127.     // TOIE1:T/C1溢出中断使能
    128.     // OCIE0:T/C0输出比较匹配中断使能
    129.     // TOIE0:T/C0溢出中断使能
    130.     TIMSK = 0;
    131.     //ETIMSK T/C扩展中断屏蔽寄存器
    132.     // -----------------------------------------------------------------
    133.     // |   -   |   -   | TICIE3| OCIE3A| OCIE3B| TOIE3 | OCIE3C| OCIE1C|
    134.     // -----------------------------------------------------------------
    135.     // TICIE3:T/C3输入捕捉中断使能
    136.     // OCIE3A:T/C3输出比较A匹配中断使能
    137.     // OCIE3B:T/C3输出比较B匹配中断使能
    138.     // TOIE3:T/C3溢出中断使能
    139.     // OCIE3C:T/C3输出比较C匹配中断使能
    140.     // OCIE1C:T/C1输出比较C匹配中断使能
    141.     ETIMSK = 0;
    142.    
    143.     //TIFR T/C中断标志寄存器
    144.     // -----------------------------------------------------------------
    145.     // |  OCF2 |  TOV2 |  ICF1 | OCF1A | OCF1B |  TOV1 |  OCF0 |  TOV0 |
    146.     // -----------------------------------------------------------------
    147.     // OCF2:T/C2输出比较匹配标志
    148.     // TOV2:T/C2溢出标志
    149.     // ICF1:T/C1输入捕捉标志位
    150.     // OCF1A:T/C1输出比较A匹配标志位
    151.     // OCF1B:T/C1输出比较B匹配标志位
    152.     // TOV1:T/C1溢出标志
    153.     // OCF0:T/C0输出比较匹配标志
    154.     // TOV0:T/C0溢出标志
    155.     //ETIFR 扩展的T/C中断标志寄存器
    156.     // -----------------------------------------------------------------
    157.     // |   -   |   -   |  ICF3 | OCF3A | OCF3B |  TOV3 | OCF3C | OCF1C |
    158.     // -----------------------------------------------------------------
    159.     // ICF3:T/C3输入捕捉匹配标志位
    160.     // OCF3A:T/C3输出比较A匹配标志位
    161.     // OCF3B:T/C3输出比较B匹配标志位
    162.     // TOV3:T/C3溢出标志位
    163.     // OCF3C:T/C3输出比较C匹配标志位
    164.     // OCF1C:T/C1输出比较C匹配标志位
    165.     //ASSR T/C0异步状态寄存器
    166.     // -----------------------------------------------------------------
    167.     // |   -   |   -   |   -   |   -   |  AS0  | TCN0UB| OCR0UB| TCR0UB|
    168.     // -----------------------------------------------------------------
    169.     // AS0:T/C0使用外部时钟
    170.     // TCN0UB:TCNT0更新中,写TCNT0时将置位,为0时表明TCNT0可以写入新值
    171.     // OCR0UB:OCR0更新中,写OCR0时将置位,为0表明OCR0可以写入新值
    172.     // TCR0UB:TCCR0更新中,写TCCR0时将置位,为0表明TCCR0可以写入新值
    173.     ASSR = 0;
    174. }
    175. void init_timer2()
    176. {   
    177.     //TCCR2 T/C2控制寄存器
    178.     // -----------------------------------------------------------------
    179.     // |  FOC2 | WGM20 | COM21 | COM20 | WGM21 |  CS22 |  CS21 |  CS20 |
    180.     // -----------------------------------------------------------------
    181.     // FOC2:强制输出比较启动
    182.     // WGM21, WGM20: 工作模式选择
    183.     //              00:普通模式,01:PWM相位修正,
    184.     //              10:比较匹配时清除计数器模式(CTC模式),11:快速PWM
    185.     // COM21, COM20:比较匹配时的输出模式
    186.     //          WGMxx为普通模式或CTC模式时
    187.     //              00:OC0未连接,
    188.     //              01:OC0取反,
    189.     //              10:OC0清零,
    190.     //              11:OC0置位
    191.     //          WGMxx为相位修正PWM模式
    192.     //              00:OC0未连接,
    193.     //              01:保留,
    194.     //              10:升序匹配时清零OC0;降序匹配时置位OC0,
    195.     //              11:升序匹配时置位OC0;降序匹配时清零OC0
    196.     //          WGMxx为快速PWM模式
    197.     //              00:OC0未连接
    198.     //              01:保留
    199.     //              10:匹配时OC0清零;计数到TOP时OC0置位
    200.     //              11:匹配时OC0置位;计数到TOP时OC0清零
    201.     // CS22,CS21,CS20:T/C0时钟预分频选择
    202.     //              000:无时钟,T/C不工作     001:1/1
    203.     //              010:1/8     011:1/32     100:1/64
    204.     //              101:1/128   110:1/256    111:1/1024
    205.     TCCR2 = 0;
    206.     //TCNT2 T/C2计数寄存器,8位
    207.     //OCR2 T/C2比较寄存器,8位
    208. }
    209. void init_timer1()
    210. {
    211.     //TCCR1A T/C1控制寄存器A
    212.     // -----------------------------------------------------------------
    213.     // | COM1A1| COM1A0| COM1B1| COM1B0| COM1C1| COM1C0| WGM11 | WGM10 |
    214.     // -----------------------------------------------------------------
    215.     //TCCR1B T/C1控制寄存器B
    216.     // -----------------------------------------------------------------
    217.     // | ICNC1 | ICES1 |   -   | WGM13 | WGM12 |  CS12 |  CS11 |  CS10 |
    218.     // -----------------------------------------------------------------
    219.     //TCCR1C T/C1控制寄存器C
    220.     // -----------------------------------------------------------------
    221.     // | FOC1A | FOC1B | FOC1C |   -   |   -   |   -   |   -   |   -   |
    222.     // -----------------------------------------------------------------
    223.     // COM1A1,COM1A0:通道A的比较输出模式
    224.     // COM1B1,COM1B0:通道B的比较输出模式
    225.     // COM1C1,COM1C0:通道C的比较输出模式
    226.     // WGM13,WGM12,WGM11,WGM10:波型发生模式:
    227.     //              比较输出模式(CTC模式),非PWM
    228.     //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    229.     //                  01  比较匹配时OC1A/OC1B/OC1C电平取反
    230.     //                  10  比较匹配时清零OC1A/OC1B/OC1C(输出低电平)
    231.     //                  11  比较匹配时置位OC1A/OC1B/OC1C(输出高电平)
    232.     //              比较输出模式(CTC模式),快速PWM
    233.     //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    234.     //                  01  WGM13为0时同上,为1时比较匹配时 OC1A电平取反,OC1B/OC1C保留
    235.     //                  10  比较匹配时OC1A/OC1B/OC1C清零,在TOP时OC1A/OC1B/OC1C置位
    236.     //                  11  比较匹配时OC1A/OC1B/OC1C置位,在TOP时OC1A/OC1B/OC1C清零
    237.     //              比较输出模式(CTC模式),相位修正及相频修正PWM
    238.     //                  00  普通端口操作,OC1A/OC1B/OC1C未连接
    239.     //                  01  WGM13为0:同上,为1时比较匹配时 OC1A电平取反,OC1B/OC1C保留
    240.     //                  10  升序计数匹配时将OC1A/OC1B/OC1C清零,降序计数匹配时将OC1A/OC1B/OC1C置位
    241.     //                  11  升序计数匹配时将OC1A/OC1B/OC1C置位,降序计数匹配时将OC1A/OC1B/OC1C清零
    242.     //
    243.     //   模式 WGM1x   工作模式说明     TOP   OCR1x更新时刻  TOVn置位时刻
    244.     //     0   0000       普通模式    0xFFFF        立即            MAX
    245.     //     1   0001   8位相位修正PWM  0x00FF         TOP         BOTTOM
    246.     //     2   0010   9位相位修正PWM  0x01FF         TOP         BOTTOM
    247.     //     3   0011  10位相位修正PWM  0x03FF         TOP         BOTTOM
    248.     //     4   0100              CTC   OCRnA        立即            MAX
    249.     //     5   0101       8位快速PWM  0x00FF         TOP            TOP
    250.     //     6   0110       9位快速PWM  0x01FF         TOP            TOP
    251.     //     7   0111      10位快速PWM  0x03FF         TOP            TOP
    252.     //     8   1000  相位频率修正PWM    ICRn      BOTTOM         BOTTOM
    253.     //     9   1001  相位频率修正PWM   OCRnA      BOTTOM         BOTTOM
    254.     //    10   1010      相位修正PWM    ICRn         TOP         BOTTOM
    255.     //    11   1011      相位修正PWM   OCRnA         TOP         BOTTOM
    256.     //    12   1100              CTC    ICRn        立即            MAX
    257.     //    13   1101             保留      -          -               -
    258.     //    14   1110          快速PWM    ICRn         TOP            TOP
    259.     //    15   1111          快速PWM   OCRnA         TOP            TOP
    260.     // ICNC1:使能/禁止输入捕捉噪声抑制器
    261.     // ICES1:输入捕获触发沿选择,0为下降沿触发,1为上升沿触发
    262.     // CS12,CS11,CS10:T/C0时钟预分频选择
    263.     //              000:无时钟,T/C不工作     001:1/1
    264.     //              010:1/8     011:1/64     100:1/256
    265.     //              101:1/1024  110:外部T1脚下降沿驱动    111:外部T1脚上升沿驱动
    266.     // FOC1A,FOC1B,FOC1C:强制输出比较通道A,B,C
    267.     TCCR1A = TCCR1B = TCCR1C = 0;
    268.     //TCNT1H,TCNT1L 定时/计数器1
    269.     //OCR1AH,OCR1AL 输出比较寄存器1A
    270.     //OCR1BH,OCR1BL 输出比较寄存器1B
    271.     //OCR1CH,OCR1CL 输出比较寄存器1C
    272.     //ICR1H,ICR1L 输入捕捉寄存器1
    273. }
    274. void init_timer3()
    275. {
    276.     //TCCR3A T/C3控制寄存器A
    277.     // -----------------------------------------------------------------
    278.     // | COM3A1| COM3A0| COM3B1| COM3B0| COM3C1| COM3C0| WGM31 | WGM30 |
    279.     // -----------------------------------------------------------------
    280.     //TCCR3B T/C3控制寄存器B
    281.     // -----------------------------------------------------------------
    282.     // | ICNC3 | ICES3 |   -   | WGM33 | WGM32 |  CS32 |  CS31 |  CS30 |
    283.     // -----------------------------------------------------------------
    284.     //TCCR3C T/C3控制寄存器C
    285.     // -----------------------------------------------------------------
    286.     // | FOC3A | FOC3B | FOC3C |   -   |   -   |   -   |   -   |   -   |
    287.     // -----------------------------------------------------------------
    288.     // COM3A1,COM3A0:通道A的比较输出模式
    289.     // COM3B1,COM3B0:通道B的比较输出模式
    290.     // COM3C1,COM3C0:通道C的比较输出模式
    291.     // WGM33,WGM32,WGM31,WGM30:波型发生模式:
    292.     //              比较输出模式(CTC模式),非PWM
    293.     //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    294.     //                  01  比较匹配时OC3A/OC3B/OC3C电平取反
    295.     //                  10  比较匹配时清零OC3A/OC3B/OC3C(输出低电平)
    296.     //                  11  比较匹配时置位OC3A/OC3B/OC3C(输出高电平)
    297.     //              比较输出模式(CTC模式),快速PWM
    298.     //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    299.     //                  01  WGM13为0时同上,为1时比较匹配时 OC3A电平取反,OC3B/OC3C保留
    300.     //                  10  比较匹配时OC3A/OC3B/OC3C清零,在TOP时OC3A/OC3B/OC3C置位
    301.     //                  11  比较匹配时OC3A/OC3B/OC3C置位,在TOP时OC3A/OC3B/OC3C清零
    302.     //              比较输出模式(CTC模式),相位修正及相频修正PWM
    303.     //                  00  普通端口操作,OC3A/OC3B/OC3C未连接
    304.     //                  01  WGM13为0:同上,为1时比较匹配时 OC3A电平取反,OC3B/OC3C保留
    305.     //                  10  升序计数匹配时将OC3A/OC3B/OC3C清零,降序计数匹配时将OC3A/OC3B/OC3C置位
    306.     //                  11  升序计数匹配时将OC3A/OC3B/OC3C置位,降序计数匹配时将OC3A/OC3B/OC3C清零
    307.     //
    308.     //   模式 WGM3x   工作模式说明     TOP   OCR1x更新时刻  TOVn置位时刻
    309.     //     0   0000       普通模式    0xFFFF        立即            MAX
    310.     //     1   0001   8位相位修正PWM  0x00FF         TOP         BOTTOM
    311.     //     2   0010   9位相位修正PWM  0x01FF         TOP         BOTTOM
    312.     //     3   0011  10位相位修正PWM  0x03FF         TOP         BOTTOM
    313.     //     4   0100              CTC   OCRnA        立即            MAX
    314.     //     5   0101       8位快速PWM  0x00FF         TOP            TOP
    315.     //     6   0110       9位快速PWM  0x01FF         TOP            TOP
    316.     //     7   0111      10位快速PWM  0x03FF         TOP            TOP
    317.     //     8   1000  相位频率修正PWM    ICRn      BOTTOM         BOTTOM
    318.     //     9   1001  相位频率修正PWM   OCRnA      BOTTOM         BOTTOM
    319.     //    10   1010      相位修正PWM    ICRn         TOP         BOTTOM
    320.     //    11   1011      相位修正PWM   OCRnA         TOP         BOTTOM
    321.     //    12   1100              CTC    ICRn        立即            MAX
    322.     //    13   1101             保留      -          -               -
    323.     //    14   1110          快速PWM    ICRn         TOP            TOP
    324.     //    15   1111          快速PWM   OCRnA         TOP            TOP
    325.     // ICNC3:使能/禁止输入捕捉噪声抑制器
    326.     // ICES3:输入捕获触发沿选择,0为下降沿触发,1为上升沿触发
    327.     // CS32,CS31,CS30:T/C0时钟预分频选择
    328.     //              000:无时钟,T/C不工作     001:1/1
    329.     //              010:1/8     011:1/64     100:1/256
    330.     //              101:1/1024  110:外部T1脚下降沿驱动    111:外部T1脚上升沿驱动
    331.     // FOC3A,FOC3B,FOC3C:强制输出比较通道A,B,C
    332.     TCCR3A = TCCR3B = TCCR3C = 0;
    333.     //TCNT3H,TCNT3L 定时/计数器3
    334.     //OCR3AH,OCR3AL 输出比较寄存器3A
    335.     //OCR3BH,OCR3BL 输出比较寄存器3B
    336.     //OCR3CH,OCR3CL 输出比较寄存器3C
    337.     //ICR3H,ICR3L 输入捕捉寄存器3
    338. }
    339. void init_uart(void)
    340. {
    341.     //UDRn USART I/O数据寄存器, 不可用读修改写命令操作, 否则会改变FIFO状态
    342.     //UCSRnA USART控制和状态寄存器A
    343.     // -----------------------------------------------------------------
    344.     // |  RXCn |  TXCn | UDREn |  FEn  |  DORn |  UPEn |  U2Xn | MPCMn |
    345.     // -----------------------------------------------------------------
    346.     // RXCn:USART接收结束标志
    347.     // TXCn:USART发送结束标志,写1可清除
    348.     // UDREn:USART数据寄存器为空标志,只有该标志为1才数据才可写入UDR0
    349.     // FEn:帧错误,未正确收到停止位
    350.     // DORn:数据过速
    351.     // UPEn:奇偶效验错误
    352.     // U2Xn:倍速发送,仅对异步操作有影响
    353.     // MPCMn:多处理器通讯模式
    354.     //UCSRnB USART控制和状态寄存器B
    355.     // -----------------------------------------------------------------
    356.     // | RXCIEn| TXCIEn| UDRIEn| RXENn | TXENn | UCSZn2| RXB8n | TXB8n |
    357.     // -----------------------------------------------------------------
    358.     // RXCIEn:接收结束中断使能
    359.     // TXCIEn:发送结束中断使能
    360.     // UDRIEn:USART数据寄存器空中使能
    361.     // RXENn:接收使能
    362.     // TXENn:发送使能
    363.     // UCSZn2:字符长度,具体见下面
    364.     // RXB8n:接收数据位8
    365.     // TXB8n:发送数据位8
    366.     //UCSRxC USART控制和状态寄存器C
    367.     // -----------------------------------------------------------------
    368.     // |   -   | UMSELn| UPMn1 | UPMn0 | USBSn | UCSZn1| UCXZn0| UCPOLn|
    369.     // -----------------------------------------------------------------
    370.     // UMSELn:模式选择,0为异步操作,1为同步操作
    371.     // UPMn1,UPMn0:奇偶效验模式,00禁止,01保留,10偶效验,11奇校验
    372.     // USBSn:停止位选择,0为1位停止位,1为2位停止位
    373.     // UCSZn2,UCSZn0:字符长度,000为5位, 001为 6位,010为7位, 011为8位
    374.     //                         100为保留,101为保留,110为保留,111为9位
    375.     // UCPOLn:时钟极性,(异步模式应清零)
    376.     //                              UCPOL0   发送数据位置   接收数据位置
    377.     //                                0        XCK0上升沿    XCK0下降沿
    378.     //                                1        XCK0下降沿    XCK0上升沿
    379.     //UBRRnL和UBRRnH USART波特率寄存器, UBRRnH15:12为保留位:
    380.     // -----------------------------------------------------------------
    381.     // |   -   |   -   |   -   |   -   | BIT11 | BIT10 | BIT09 | BIT08 |
    382.     // -----------------------------------------------------------------
    383.     // -----------------------------------------------------------------
    384.     // | BIT07 | BIT06 | BIT05 | BIT04 | BIT03 | BIT02 | BIT01 | BIT00 |
    385.     // -----------------------------------------------------------------
    386. }   
    387. void init_spi(void)
    388. {
    389.     //SPCR SPI控制寄存器
    390.     // -----------------------------------------------------------------
    391.     // |  SPIE |  SPE  |  DORD |  MSTR |  CPOL |  CPHA |  SPR1 | SPR0  |
    392.     // -----------------------------------------------------------------
    393.     // SPIE:SPI中断使能
    394.     // SPE:SPI使能
    395.     // DORD:数据次序,为1时LSB先发送
    396.     // MSTR:是否主机模式,若为主机模式,SS引脚配置为输入,但被拉低则MSTR被清零
    397.     // SPSR的SPIF位置位。用户必须重新设置MSTR位进入主机模式。
    398.     // CPOL:时钟极性,为1时表示空闲时SCK为高电平,否则为低电平。
    399.     // CPHA:时钟相位,为0时为时钟的起始沿采样数据,否则为终止沿采样数据
    400.     // SPR1,SPR0:SPI时钟速率选择:00  1/4, 01  1/16, 10  1/64, 11  1/128
    401.     //SPSR SPI状态寄存器
    402.     // -----------------------------------------------------------------
    403.     // |  SPIF |  WCOL |   -   |   -   |   -   |   -   |   -   | SPI2X |
    404.     // -----------------------------------------------------------------
    405.     // SPIF:SPI中断标志,串行发送结束后此位置位,对于查询方式,可先读SPSR,紧着
    406.     //       访问SPDR来对SPIF位清零。
    407.     // WCOL:写冲突标志,可通过先读SPSR,紧接着访问SPDR来清零。
    408.     // SPI2X:SPI倍速,若为主机,SCK最高频率可达CPU频率一半,从机则只能保证为1/4
    409.    
    410.     //SPDR SPI数据寄存器
    411.     // -----------------------------------------------------------------
    412.     // |  MSB  |       |       |       |       |       |       |  LSB  |
    413.     // -----------------------------------------------------------------
    414.     // SPDR为可读写寄存器,写则将启动数据传输,读则读取接收缓冲器
    415. }   
    416. void init_twi(void)
    417. {
    418.     //TWBR TWI比特率寄存器
    419.     // -----------------------------------------------------------------
    420.     // |  BIT7 |  BIT6 |  BIT5 |  BIT4 |  BIT3 |  BIT2 |  BIT1 |  BIT0 |
    421.     // -----------------------------------------------------------------
    422.     // SCL频率 = CUP时钟频率/(16 + 2 * TWBR * 4 ^ TWPS)
    423.     // TWBR值应该不小于10, TWPS为预分频值
    424.     //TWCR TWI控制寄存器
    425.     // -----------------------------------------------------------------
    426.     // | TWINT |  TWEA | TWSTA | TWSTO |  TWWC |  TWEN |   -   |  TWIE |
    427.     // -----------------------------------------------------------------
    428.     // TWINT:TWI中断标志,TWINT标志必须由软件写1清除, 即使在中断服务程序中硬件也不会自动清除
    429.     //        在清除TWI标志前一定要首先完成对TWAR TWSR TWDR的访问, 此位清零后TWI立即开始工作。
    430.     // TWEA:使能TWI应答,此位控制应答脉冲的产生。
    431.     // TWSTA:START状态位,自己想成为主机时置此位,发送START后软件必须清零TWSTA。
    432.     // TWSTO:STOP状态位。主模式下,置此位将在总线上产生STOP状态,后TWSTO自动清零;从机模式下
    433.     //        置此位可使接口从错误状态恢复到未被寻址的状态,此时总线上不会产生STOP状态。
    434.     // TWWC:TWI写冲突标志。每次写TWDR时都将更新此标志。
    435.     // TWEN:TWI使能位。置1时TWI引脚将从IO引脚切换到SCL和SDA引脚。
    436.     // TWIE:TWI中断使能。
    437.    
    438.     //TWSR TWI状态寄存器
    439.     // -----------------------------------------------------------------
    440.     // |  TWS7 |  TWS6 |  TWS5 |  TWS4 |  TWS3 |   -   | TWPS1 | TWPS0 |
    441.     // -----------------------------------------------------------------
    442.     // TWS7~TWS3:TWI状态
    443.     // TWPS1~TWPS0:TWI预分频值。00:1; 01:1/4; 10:1/16; 11:1/64。
    444.    
    445.     //TWDR TWI数据寄存器
    446.     // -----------------------------------------------------------------
    447.     // |  BIT7 |  BIT6 |  BIT5 |  BIT4 |  BIT3 |  BIT2 |  BIT1 |  BIT0 |
    448.     // -----------------------------------------------------------------
    449.     // 发送模式,TWDR中包含了要发送的字节,接收模式TWDR包含了接收到的数据。
    450.     // 只要TWINT置位,TWDR的数据就是稳定的。
    451.     //TWAR TWI从机地址寄存器
    452.     // -----------------------------------------------------------------
    453.     // |  TWA6 |  TWA5 |  TWA4 |  TWA3 |  TWA2 |  TWA1 |  TWA0 | TWGCE |
    454.     // -----------------------------------------------------------------
    455.     // TWA6~TWA0:TWI从机地址寄存器
    456.     // TWGCE:使能TWI广播识别
    457. }
    458.     //GICR 通用中断控制寄存器
    459.     // -----------------------------------------------------------------
    460.     // |  INT1 |  INT0 |  INT2 |   -   |   -   |   -   | IVSEL |  IVCE |
    461.     // -----------------------------------------------------------------
    462.     // INT1:使能外部中断1请求
    463.     // INT0:使能外部中断0请求
    464.     // INT2:使能外部中断2请求
    465.     // IVSEL:中断向量选择,为0时中断向量位于FLASH起始地址,为1时位于BOOT区起始地址
    466.     // IVCE:中断向量修改使能。改变IVSEL时IVCE必须置位。
    467.     //MCUCR MCU控制寄存器
    468.     // -----------------------------------------------------------------
    469.     // |  SM2  |   SE  |  SM1  |  SM0  | ISC11 | ISC10 | ISC01 | ISC00 |
    470.     // -----------------------------------------------------------------
    471.     // SM2, SM1, SM0:000:空闲模式  
    472.     //                001:ADC噪声抑制模式
    473.     //                010:掉电模式
    474.     //                011:省电模式
    475.     //                100:保留
    476.     //                101:保留
    477.     //                110:Standby模式
    478.     //                111:扩展Standby模式
    479.     //SE:休眠使能
    480.     //ISC11, ISC10: 00:INT1为低电平时产生中断请求
    481.     //               01:INT1引脚上任意的逻辑电平变化都将引发中断
    482.     //               10:INT1的下降沿产生异步中断请求
    483.     //               11:INT1的上升沿产生异步中断请求
    484.     //ISC01, ISC00:  00:INT0为低电平时产生中断请求
    485.     //               01:INT0引脚上任意的逻辑电平变化都将引发中断
    486.     //               10:INT0的下降沿产生异步中断请求
    487.     //               11:INT0的上升沿产生异步中断请求
    488.     //MCUCSR MCU控制和状态寄存器
    489.     // -----------------------------------------------------------------
    490.     // |  JTD  |   -   |   -   |  JTRF |  WDRF |  BORF | FXTRF |  PORF |
    491.     // -----------------------------------------------------------------
    492.     // JTD:
    493.     // JTRF:JTAG复位标志
    494.     // WDRF:看门狗复位标志
    495.     // BORF:掉电检测复位标志
    496.     // EXTRF:外部复位标志
    497.     // PORF:上电复位标志
    498.     //WDTCR 看门狗定时器控制寄存器
    499.     // -----------------------------------------------------------------
    500.     // |   -   |   -   |   -   |  WDCE |  WDE  |  WDP2 |  WDP1 |  WDP0 |
    501.     // -----------------------------------------------------------------
    502.     // WDCE:看门狗修改使能,清零WDE位时必须先置位WDCE位,否则不能禁止看门狗
    503.     // WDE:看门狗使能,只有WDCE为1时WDE才能清零
    504.     // WDP2~WDP0:看门狗定时器预分频值   WDT振荡周期  VCC=3V时溢出时间  VCC=5V时溢出时间
    505.     //                            000:     16K            14.8ms            14.0ms
    506.     //                            001:     32K            29.6ms            28.1ms
    507.     //                            010:     64K            59.1ms            56.2ms
    508.     //                            011:    128K             0.12s             0.11s
    509.     //                            100:    256K             0.24s             0.22s
    510.     //                            101:    512K             0.47s             0.45s
    511.     //                            110:   1024K             0.95s             0.9s
    512.     //                            111:   2048K             1.9s              1.8s
    513.     //EEARH/EEARL EEPROM地址寄存器
    514.     //EEARH
    515.     // -----------------------------------------------------------------
    516.     // |   -   |   -   |   -   |   -   | EEAR11| EEAR10| EEAR9 | EEAR8 |
    517.     // -----------------------------------------------------------------
    518.     //EEARL
    519.     // -----------------------------------------------------------------
    520.     // | EEAR7 | EEAR6 | EEAR5 | EEAR4 | EEAR3 | EEAR2 | EEAR1 | EEAR0 |
    521.     // -----------------------------------------------------------------
    522.     //EEPROM地址,在访问EEPROM前必须为其赋予正确的数据
    523.     //EEDR EEPROM数据寄存器   
    524.     // -----------------------------------------------------------------
    525.     // |  MSB  |  ...  |  ...  |  ...  |  ...  |  ...  |  ...  |  LSB  |
    526.     // -----------------------------------------------------------------
    527.    
    528.     //EECR EEPROM控制寄存器
    529.     // -----------------------------------------------------------------
    530.     // |   -   |   -   |   -   |   -   | EERIE | EEMWE |  EEWE |  EERE |
    531.     // -----------------------------------------------------------------
    532.     //EERIE:EEPROM就绪中断使能
    533.     //EEMWE:EEPROM主机写使能,当此位为1时,在4个时钟内EEWE置位,数据将写入EEPROM
    534.     //          EEMWE置位4个时钟后硬件将其清零
    535.     //EEWE:EEPROM写使能
    536.     //EERE:EEPROM读使能。当EEPROM地址设置好后,需置位EERE以便将数据读入EEAR
    537.     //EEPROM写时序:
    538.     //a等待EEWE位为0
    539.     //b等待SPMCSR的SPMEN位为0,此步只在软件包含引导程序,且允许CPU对Flash编程时才有用
    540.     //c将新的EEPROM地址写入EEAR
    541.     //d将新的EEPROM数据写入EEDR
    542.     //e对EECR的EEMWE位写1,同时清零EEWE位
    543.     //f在置位EEMWE位的4个周期内置位EEWE位

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

    很多初学者都会被移位算法迷惑,移位算法形如(1<

    1. UCSRC = (1<1<1<
    2. UCSR0B = (1<1<1<1<// 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<

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

    我们在程序中包含的头文件iom16v.h类似的文件会有#define URSEL 7 这样的定义,1<


    无人扶我青云志,我自踏雪至山巅。觉得不错,动动发财的小手点个赞哦!

  • 相关阅读:
    21.Redis系列之缓存穿透、击穿、雪崩
    Node.js的基本使用(四)项目实战——项目初始化及用户注册登录接口的实现
    PostgreSQL 查询修改max_connections(最大连接数)及其它配置
    (免费领源码)JAVA#springboot#MYSQL 社区医院病历管理平台11271-计算机毕业设计项目选题推荐
    使用html+css实现一个静态页面(厦门旅游网站制作6个页面) 旅游网页设计制作 HTML5期末考核大作业,网站——美丽家乡。 学生旅行 游玩 主题住宿网页
    抖音 滑块验证方案 s_v_web_id 参数分析
    Windows Server 2016安装SQLServer2008R2
    Glide源码解析二---into方法
    Java实现将JSON文件导出到Excel
    【Go语言】Go项目工程管理
  • 原文地址:https://blog.csdn.net/liht_1634/article/details/127910338