AVR单片机及其编译软件

news2024/11/25 7:07:37

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

---------------------------------------

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的周期延时。

然后就是下面的操作了:

#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 JTAG ICE MKII仿真器

注意:此处的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是一个和串口通讯有关的一个八位寄存器,他的每一位都有特殊的定义,我们通过查数据手册可以看到,如下的内容。

我们在程序中包含的头文件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。

------------------------------------------------------------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/13939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用Python脚本能获取Wifi密码么?能。

注意&#xff0c;本文不是破解 WIFI 密码&#xff0c;当然你把程序发给别人再获取对方密码&#xff0c;那是社会工程学。 文章目录⛳️ 实战场景与 subprocess 模块介绍⛳️ Python 获取本地 Wifi 密码⛳️ 实战场景与 subprocess 模块介绍 这篇博客给大家带来一个小小的案例&…

魏副业而战:做闲鱼比打工强

我是魏哥&#xff0c;与其在家躺平&#xff0c;不如魏副业而战&#xff01; 学员小D做闲鱼又赚了122元&#xff0c;并在社群中晒了收入截图&#xff0c;大家纷纷点赞。 小D说&#xff0c;做闲鱼比打工强&#xff0c;一边聊天&#xff0c;一边赚钱&#xff0c;很喜欢这种赚钱方…

多线程服务器端的实现

理解线程的概念 引入线程的背景 多进程模型的缺点 ①、创建进程的过程会给操作系统带来相当沉重的复旦 ②、为了完成进程间数据交换&#xff0c;需要特殊的IPC技术 ③、每秒少则数十次、多则数千次的“上下文切换”是创建进程时最大的开销&#xff08;主要&#xff09; 线…

2022实验室更新 DBCO-NH2,DBCO-Amine 叠氮化物功能化化合物

DBCO(二苯并环辛炔) 氨基衍生物&#xff0c;可与含有羧基的生化小分子形成稳定酰胺键连接。DBCO-NHS酯是一种与胺反应的化合物&#xff0c;可用于修饰含胺分子(在水性介质中的溶解度有限)。它与伯胺(例如赖氨酸的侧链氨基或多肽的N端氨基)在中性或弱碱性pH下反应形成共价键。这…

某政府门户网站维护项目运维方案

一.1 运维总体原则 一.1.1 整体性原则 我们将综合考虑XXX目前所有门户网站相关应用系统的现状&#xff0c;提出整体的运行维护策略&#xff0c;有效保障系统运行中各环节的不间断运行&#xff0c;并综合使用不同层次的技术手段&#xff0c;为应用系统和系统依托的基础环境提供全…

【AI理论学习】多模态介绍及当前研究方向

多模态介绍及当前研究方向什么是多模态&#xff1f;多模态的任务和数据集有哪些&#xff1f;多种模态融合的方式有哪些&#xff1f;多模态任务的研究方向有哪些&#xff1f;参考资料什么是多模态&#xff1f; 什么是多模态&#xff1f;多模态指的是多种模态的信息&#xff0c;…

Golang入门笔记(8)—— init 函数

init 函数 &#xff1a; 每一个源文件都可以包含一个init函数&#xff0c;该函数会在 程序入口main函数执行前 &#xff0c;被Go运行的框架进行调用。 测试代码&#xff1a; package mainimport ("fmt" )func init() {fmt.Println("init...") }func main(…

vue 项目源码映射失败问题解决

文章目录vue 项目源码映射失败问题解决前言解决方案效果参考vue 项目源码映射失败问题解决 前言 不知何时起&#xff0c;项目控制台调试进入源代码变成编译后的文件了&#xff0c;调试起来十分不便&#xff0c;强迫症十分难受&#xff08;像是自己英语水平一般&#xff0c;基…

人工智能:PyTorch深度学习框架介绍

目录 1、PyTorch 2、PyTorch常用的工具包 3、PyTorch特点 4、PyTorch不足之处 今天给大家讲解一下PyTorch深度学习框架的一些基础知识&#xff0c;希望对大家理解PyTorch有一定的帮助&#xff01; 1、PyTorch PyTorch是一个基于Torch的Python机器学习框架。它是由Facebook的人工…

Android Studio实现记单词App,背完四六级一次过~

项目目录一、项目概述二、主要技术三、开发环境四、详细设计1、数据库2、单词详情3、搜索单词五、运行演示一、项目概述 本系统包含高考、四级、六级、托福和雅思词汇五个章节。每个章节分为多个单元&#xff0c;每个单元又包含上百个词汇。可以在单元列表查询单词&#xff0c…

JavaScript基础(12)_构造函数、this

我们每次创建对象时&#xff0c;常常会遇到属性和方法大量相同的情况&#xff0c;如果每次都创建相似的对象&#xff0c;代码就显得冗长多余&#xff0c;所以为了优化&#xff0c;我们往往利用函数调用的形式来简化这些代码&#xff0c;因为普通函数建立的对象并不能区分不同的…

Spark 3.0 - 2.机器学习核心 DataFrame 应用 API 与操作详解

目录 一.引言 二.创建 DataFrame 1.CreateDataFrame 2.RDD toDF By Spark implicits 3.By Read Format File 三.常用处理 API 1.select 选择 2.selectExpr 表达式 3.collect / collectAsList 收集 4.count 统计 5.limit 限制 6.distinct 去重 7.filter 过滤 8.ma…

Matlab:创建分类数组

Matlab&#xff1a;创建分类数组基于字符串数组创建分类数组添加新元素和缺失的元素基于字符串数组创建有序分类数组基于分 bin 数值数据创建有序分类数组此示例说明如何创建分类数组。categorical 是一个数据类型&#xff0c;用来存储值来自一组有限离散类别的数据。这些分类可…

FTX 深度数据复盘

Nov 2022, Sabrina Data Source: Footprint Analytics Dashboards 11月2日&#xff0c;Coindesk 公布了 Alameda 的私人财务文件&#xff0c;这是一家由 FTX 创始人 Sam Bankman-Fried 拥有的风险投资和交易公司&#xff0c;与该交易所密切相关&#xff0c;从而引发了加密货币…

Spring Framework 6.0 框架

Spring Framework 6.0.0 现已正式发布。 “这是 2023 年及以后新一代框架的开始&#xff0c;拥抱了 OpenJDK 和 Java 生态系统中当前和即将到来的创新。同时&#xff0c;我们将其精心设计为针对现代运行时环境的 Spring Framework 5.3.x 的直接升级。” 作为核心框架的重大修订…

脑肽载体Angiopep-2、906480-05-5、TFFYGGSRGKRNNFKTEEY

Angiopep-2 hydrochloride 是脑肽载体。抗肿瘤药物与 Angiopep-2 肽载体的结合可提高其在脑癌中的活性. Angiopep-2 hydrochloride is a brain peptide vector. The conjugation of anticancer agents with the Angiopep-2 peptide vector could increase their efficacy in th…

【正点原子FPGA连载】 第三章 硬件资源详解 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第三章 硬件资源…

提升Mac运行速度的十大小技巧,你用过几个?

经常听到小伙伴在抱怨PC电脑很慢&#xff0c;但是其实Mac电脑随着用的时间增长&#xff0c;运行速度也会越来越慢&#xff0c;那么造成Mac运行慢的原因有很多&#xff0c;可能是操作系统过时未更新&#xff0c;也可能是内存&#xff08;RAM&#xff09;不足&#xff0c;以下小编…

终于把下载安装更新的功能整出来了,记录关键点

我的第一个安卓应用终于也有了APP内安装更新的功能&#xff08;赶上末班车了吗&#xff09;&#xff0c;记录一些关键点&#xff0c;方方面面的。 托管检测更新和下载服务 由于没有服务器&#xff0c;这两个核心功能可以托管到一些比较好的平台。检测我用的是蒲公英分发&…

MySQL8.0分析查询语句EXPLAIN

文章目录学习资料分析查询语句EXPLAINidselect_typepartitions&#xff08;可略&#xff09;type【重点】possible_keys和keykey_len【重点】refrows【重点】filteredExtra【重点】EXPLAIN四种输出格式传统格式JSON格式SHOW WARNINGS的使用学习资料 【MySQL数据库教程天花板&a…