nicksean 发表于 2009-6-23 23:58:16

AVR寄存器中的每一位都能记得住吗? 原创--AVR寄存器位功能注释

写程序时记不住寄存器里位的含义, 看代码时也不方便, 于是将寄存器位功能写成注释, 收集在一起, 写代码时把注释拷进去, 大大增强了代码可读性。 呵呵。 贡献给大家。 主要针对M16的, 有错误请指出来。

#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 ~ 00111ADC0~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未连接
    //                  01WGM13为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未连接
    //                  01WGM13为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位相位修正PWM0x00FF         TOP         BOTTOM
    //   2   0010   9位相位修正PWM0x01FF         TOP         BOTTOM
    //   3   001110位相位修正PWM0x03FF         TOP         BOTTOM
    //   4   0100            CTC   OCRnA      立即            MAX
    //   5   0101       8位快速PWM0x00FF         TOP            TOP
    //   6   0110       9位快速PWM0x01FF         TOP            TOP
    //   7   0111      10位快速PWM0x03FF         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/1024110:外部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未连接
    //                  01WGM13为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未连接
    //                  01WGM13为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位相位修正PWM0x00FF         TOP         BOTTOM
    //   2   0010   9位相位修正PWM0x01FF         TOP         BOTTOM
    //   3   001110位相位修正PWM0x03FF         TOP         BOTTOM
    //   4   0100            CTC   OCRnA      立即            MAX
    //   5   0101       8位快速PWM0x00FF         TOP            TOP
    //   6   0110       9位快速PWM0x01FF         TOP            TOP
    //   7   0111      10位快速PWM0x03FF         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/1024110:外部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时钟速率选择:001/4, 011/16, 101/64, 111/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位

cqfeiyu 发表于 2009-6-24 00:04:03

好贴

cock 发表于 2009-6-24 00:06:13

得,你的程序写完,整本AVR芯片的说明书也进去了.

puqingzj 发表于 2009-6-24 00:16:18

真是有心人,感谢

kanprin 发表于 2009-6-24 08:22:00

这样写,注释比程序还多,看着你说你是在写程序还是在写数据手册?

ThinkCell 发表于 2009-6-24 08:25:13

习惯比较好,时间越长,效率越高。

superzj 发表于 2009-6-24 08:29:56

谢谢,应该花了不少时间整理吧,收藏了

rei1984 发表于 2009-6-24 08:35:03

lz的辛苦,有目共睹。

但是项目开发的程序注释要做到窍倒好处。这样的注释看程序太累,不懂程序的人也看不懂。

还是那就话,注释只写重点部分

huwuzhao 发表于 2009-6-24 08:36:54

写这么详细,牛人!顶!

snail0204 发表于 2009-6-24 08:37:10

lz辛苦了,这样比翻手册好多了,就是开始麻烦点

deepin 发表于 2009-6-24 08:37:46

好模式!!!
标记

yangsen 发表于 2009-6-24 08:41:30

从没有这样写过注释,收藏

stdio 发表于 2009-6-24 08:42:24

写代码,读代码的时候,同时打开数据手册.pdf就可以了。

fsclub 发表于 2009-6-24 08:44:48

楼改行写DATASHEET算了。。。

hyz_avr 发表于 2009-6-24 08:49:01

程序要是写大点..手册内容就全进去了.

ilcvm 发表于 2009-6-24 08:59:45

注释跟执行语句长度差别太大了,找起具体执行语句会比较麻烦。如果用记事本来看程序就郁闷了。

ilcvm 发表于 2009-6-24 09:04:39

我开始的寄存器注释也有点类似楼主的,在定义语句上面写注释,后来发现看起来太麻烦了,就改成这种样子的

    /*Timer/Counter 0 Control Register A */
    TCCR0A = ( 0 << COM0A1 )    /* Compare Match Output A Mode */
            |( 0 << COM0A0 )    /* Compare Match Output B Mode */
            |( 0 << WGM01)    /* Waveform Generation Mode */
            |( 0 << WGM00)
            |( 0 << COM0B1 )
            |( 0 << COM0B0 );
   
    /*Timer/Counter 0 Control Register B */
    TCCR0B = ( 0 << FOC0A )   /* Compare Match Output A Mode */
            |( 0 << FOC0B )   /* Compare Match Output B Mode */
            |( 0 << WGM02 )
            |( 0 << CS02)   /* Clock Select */
            |( 0 << CS01)
            |( 0 << CS00);

    /*Timer/Counter 0 Interrupt Mask Register */
    TIMSK0 = ( 0 << TOIE0)    /* Timer/Counter 0 Overflow Interrupt Enable */
            |( 0 << OCIE0A )    /* Timer/Counter 0 Output Compare Match A Interrupt Enable */
            |( 0 << OCIE0B );   /* Timer/Counter 0 Output Compare Match B Interrupt Enable */

snoopyzz 发表于 2009-6-24 09:12:52

#include "ATmega16(L)中文手册.PDF"

holycat 发表于 2009-6-24 09:40:48

这个好,楼主帅呆了!!!

AWEN2000 发表于 2009-6-24 09:49:35

翻手册不就行了,还顺便看一下注释。

要是iar有 vb或vc那么智能就好了,自动提示关键字、函数变量

tclandmei 发表于 2009-6-24 09:54:40

【19楼】 AWEN2000

用SourceInsight作编辑软件就行(自动提示关键字、函数变量)!
很强大!

gmen_pliskin 发表于 2009-6-24 09:56:14

17楼牛

jchqxl 发表于 2009-6-24 10:06:29

注释这么详细啊~啧啧

snoopyzz 发表于 2009-6-24 10:14:36

下面是ATmega48的,我常用的定义方法,这样不写注释...

#define        BIT2(xx, b1,b0)         ( (b1<<xx##1)|(b0<<xx##0) )       
#define        BIT3(xx, b2,b1,b0)        ( (b2<<xx##2)|(b1<<xx##1)|(b0<<xx##0) )       
//
//        TCCR0A
#define        COM0A_OFF           BIT2(COM0A,0,0)
#define        COM0A_COM           BIT2(COM0A,0,1)
#define        COM0A_CLR           BIT2(COM0A,1,0)
#define        COM0A_SET           BIT2(COM0A,1,1)
//
#define        COM0B_OFF           BIT2(COM0B,0,0)
#define        COM0B_COM           BIT2(COM0B,0,1)
#define        COM0B_CLR           BIT2(COM0B,1,0)
#define        COM0B_SET           BIT2(COM0B,1,1)
//
#define        WGM0_OFF           BIT2(WGM0, 0,0)
#define        WGM0_SPWM           BIT2(WGM0, 0,1)
#define        WGM0_CTC           BIT2(WGM0, 1,0)
#define        WGM0_FPWM   BIT2(WGM0, 1,1)
//
//        TCCR0B
#define        FOC0A_CLR                (0<<FOC0A)
#define        FOC0B_CLR                (0<<FOC0B)
#define        FOC0A_SET                (1<<FOC0A)
#define        FOC0B_SET                (1<<FOC0B)
#define        CLK0_STOP                BIT3(CS0, 0,0,0)
#define        CLK0_PRE1                BIT3(CS0, 0,0,1)
#define        CLK0_PRE8                BIT3(CS0, 0,1,0)
#define        CLK0_PRE64                BIT3(CS0, 0,1,1)
#define        CLK0_PRE256        BIT3(CS0, 1,0,0)
#define        CLK0_PRE1024        BIT3(CS0, 1,0,1)
#define        CLK0_FALL                BIT3(CS0, 1,1,0)
#define        CLK0_RISE                BIT3(CS0, 1,1,1)

=========================================
TCCR0A = COM0A_OFF | COM0B_OFF | WGM0_FPWM;
TCCR0B = FOC0A_CLR | FOC0B_CLR | CLK0_PRE1;

mcu5i51 发表于 2009-6-24 10:17:44

很方便

cowboy 发表于 2009-6-24 10:21:29

楼主辛苦了!

liudeee 发表于 2009-6-24 10:46:32

楼主很幸苦。
但是我觉得我写程序的时候,那些不常用的寄存器我会直接查DATASHEET,最后几页似乎有全部的寄存器总结,还有页码注释,然后找到这页看看就行了。没有必要这么复杂吧?

yu_studio 发表于 2009-6-24 10:49:25

顶下

yaojinhao 发表于 2009-6-24 11:29:08

楼主厉害!~

ratrat 发表于 2009-6-24 11:32:04

楼主真是太厉害的,
不过,我个人觉得,没有这样的必要;
如果,话说过了,对不起

nicksean 发表于 2009-6-24 12:34:33

如果带程序到现场调试,还要带手册翻?反正我是记不住,为了方便改,直接加注释。 这是我学AVR看手册时顺便写的,边看边写,加深印象,以后还能用得着。忘记时直接把注释文件打开,查找一下,连手册都省了。一句话,送给有需要的人,呵呵

snoopyzz 发表于 2009-6-24 12:40:21

ATmega16不能代表全部avr芯片,建意LZ改下标题...
ATmega48就不尽相同...

另外,我还是觉得我在23L的方法修改起来方便...

lileistone 发表于 2009-6-24 12:47:22

其实可以写到头文件里
头文件一般是定义,写的全一点没问题,而且一般看代码很少看头文件,这样也减少过多注释对执行语句的干扰

bondxie3 发表于 2009-8-7 13:22:46

我要好好学楼主!

zhangxun0712 发表于 2009-8-7 13:29:26

谢谢楼主,收藏了

manhada 发表于 2009-11-27 11:00:32

楼主好强大!!   楼主要是再做avr另外一个系列:ATxmega寄存器位功能的注释出来就好了

huatong 发表于 2009-11-27 11:55:04

用 AVR Studio 编程的时候在右边就用寄存器的说明

king2009 发表于 2009-11-27 12:28:39

好贴

nicksean 发表于 2009-11-27 12:47:52

嗯,看来还是有喜欢的人,呵呵

avrwoo 发表于 2009-11-27 12:53:55

mark

foxsports 发表于 2009-11-27 13:02:09

#include "ATmega16(L)中文手册.PDF"
——————————————————————————————
还是17楼的狠啊!!

blueagle 发表于 2009-11-27 13:04:11

我也习惯这样将一些常用寄存器定义都放到.h文件里面,写好宏定义,以后直接看头文件都可以了,基本上以后都不用看datasheet

yu_studio 发表于 2009-11-27 14:11:15

好贴要收藏:)

jiangxingyuan 发表于 2009-11-27 16:34:56

看来还是有人和我一样,我也是和头文件里。直接 ctrl C, ctrl V 就可以了,不用看数据手删,基本上把一个芯片的头文件做完,这个芯片的基本功能大部分都了解了。
发个M8 T0的例子吧

/*-------------------------------------------------------------------------------------------------*/
//设置T0启动分频模式
#define T0TIMER0                TCCR0&=0xf8                         //T1无时钟源
#define T0TIMER1                TCCR0&=0xf8;TCCR0|=0x01                //T1以1分频启动
#define T0TIMER8                TCCR0&=0xf8;TCCR0|=0x02                //T1以8分频启动
#define T0TIMER64                TCCR0&=0xf8;TCCR0|=0x03                //T1以64分频启动
#define T0TIMER256                TCCR0&=0xf8;TCCR0|=0x04                //T1以256分频启动
#define T0TIMER1024        TCCR0&=0xf8;TCCR0|=0x05                //T1以1分频启动
#define T0TIMERDOWN        TCCR0&=0xf8;TCCR0|=0x06                //外部T0输入时钟,下降沿驱动
#define T0TIMERUP                TCCR0|=0x07                                //外部T0输入时钟,上升沿驱动
#define T0T1_RESET                SFIOR|=(1<<PSR10)                        //定时器0,1预分频器复位
                                                                        //(其作用用于同步进钟,犹其在分频因子比较大时,如分频因子为8,64,256,1024等时)
/*---------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------*/
//设置T0中断
#define T0OVER_INTERRUPT_EN                TIMSK|=(1<<TOIE0)                        //T0溢出中断使能
#define T0OVER_INTERRUPT_NOT        TIMSK|=~(1<<TOIE0)                        //T0溢出中断禁止
/*---------------------------------------------------------------------------------------------------*/


/*-------------------------------------------------------------------------------------------------*/
//清T0中断标志
#define T0OVER_INTERRUPT_CLR        TIFR|=(1<<TOV0)                                //清除T1溢出中断
/*---------------------------------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------------------------------
//需要设置的寄存器
TCNT0 8位寄存器器,用于T0,作计数器用
------------------------------------------------------------------------------------------------------*/

liubinkaixin 发表于 2010-1-23 15:36:26

楼主真是好人啊.........

lanbingmeng 发表于 2010-7-28 18:18:36

楼主这个方法我个人觉得有点多余,写程序时直接到PDF中找相关的寄存器就可以了吧,不过方法因人而已,也许对别人是个好方法吧 ··

jsjjccc 发表于 2010-7-28 18:44:33

如果能做成软件就更好了,比如说要找定时器有关,告诉软件我要知道定时器有关那就出来相应的寄存器和注解的话就非常方便了

qinhya 发表于 2010-7-28 19:13:29

楼主的这个方法不错呀!!

nicksean 发表于 2010-7-28 23:16:04

还以为我眼花了呢, 俺的贴子又冒出来啦, 呵呵. 这样写好处是增强代码可读性. 我最讨厌类似ADCSR = 0x41 这样的写法, 因为我记不住, 还得查手册.

fshunj 发表于 2010-7-29 00:29:01

顶一下

virtualbit 发表于 2010-7-29 06:05:44

我寫的軟件從前很少注釋, 現在注釋多了很多

tangwei039 发表于 2010-7-29 08:18:42

mark

beixue 发表于 2010-7-29 09:46:35

mark

wbanng 发表于 2010-7-29 10:04:24

mark

fjhcpu 发表于 2010-7-29 10:08:30

好东西,用的上

lv998127 发表于 2010-7-29 10:29:19

mark

llssr 发表于 2010-7-29 12:54:22

挺好的就是程序看着太长了

lucsunny 发表于 2010-7-29 14:21:44

是个好方法,之前老查手册,万一现场修改没手册可就麻烦了。还是楼主方法好。

kunpeng032 发表于 2010-7-29 19:38:55

lz的辛苦,有目共睹

esdart 发表于 2010-7-29 22:50:34

好东西,收藏。

wangle315065 发表于 2010-7-30 11:41:46

mark

plc_avr 发表于 2010-7-30 13:10:24

是个好方法,之前老查手册,万一现场修改没手册可就麻烦了?-------------要现场修改不用电脑?里面不能多放个datasheet?

liliuqun 发表于 2010-7-30 14:18:57

记号

altos 发表于 2010-8-3 09:27:11

mark

Gorgon_Meducer 发表于 2010-8-3 09:43:24

个人观点:不是一个值得推荐的方法——除非你是在写Reference Design或者Software Framework。
正常使用,推荐 【16楼】 ilcvm 的方法。这种方法叫做“基于语义的寄存器设置”。

dqlspzl 发表于 2010-9-19 09:15:13

对于我这个初学者来说,很好很强大哦,感谢

worldly_guest 发表于 2010-9-19 20:53:07

不错,我是初学,很好很强大,谢楼主!

tangwei039 发表于 2010-9-19 21:06:41

MRAK

rqiang 发表于 2010-9-19 21:15:54

LZ应该是个比较追求完美的人,搞一个大的项目,不知道要写多少行这样的代码和注释。。。

lihuyong 发表于 2010-9-19 22:27:10

过多的注释和零注释是一样的令人头痛的。

allenjwb 发表于 2010-9-20 12:34:16

lz费了不少时间啊

sangreal 发表于 2010-9-20 12:50:15

多谢楼主无私分享!

swustlx86 发表于 2010-9-20 13:38:45

mark

1181zjf 发表于 2010-9-20 13:55:07

mark

lisj2003 发表于 2010-10-19 11:07:48

谢谢楼主哦

xstt 发表于 2010-10-19 11:14:31

mark

slash1986 发表于 2010-10-19 12:20:02

mark

dgdjfw 发表于 2010-10-19 12:43:23

好贴

guxingganyue 发表于 2010-11-1 21:47:32

楼主辛苦了

eyeye 发表于 2010-11-1 21:57:14

还是手册 + 良好的数据结构    好一点!
要是遇到寄存器多的芯片你就疯狂了!

ldj7501 发表于 2011-4-13 16:04:42

mark

qikefeng1 发表于 2011-4-14 12:52:23

谢谢楼主的辛苦拿走了...

hao876474206 发表于 2011-4-14 16:24:06

楼主威武啊!对初学者很实用啊!谢谢楼主......

staroul 发表于 2011-4-16 10:57:34

-------

XIANSir 发表于 2011-4-16 11:19:31

http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_631330NEXHJU.jpg
(原文件名:1104100945994051e4abbce057.jpg)

这是我的方法——51的,我觉得我这种最好

cc6868 发表于 2011-4-16 11:20:13

真有心啊~~~

ubuntuman 发表于 2011-4-16 13:08:09

mark

huangdog 发表于 2011-4-16 14:53:05

jihao

XIANSir 发表于 2011-4-16 16:58:23

http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_631405MP7GZP.jpg
(原文件名:QQ截图未命名.jpg)

这样的编码虽然第一次比较麻烦,但是只要编写一次,终生受益!!

cuit4017 发表于 2011-4-16 22:00:33

mark 学习一下。

largeboss 发表于 2011-4-16 22:51:44

mark

kerrwang 发表于 2011-4-16 22:54:41

好东东

fefefe111 发表于 2011-4-16 23:00:05

mark

licongdwqx 发表于 2011-4-16 23:07:05

楼主强大,23楼也蛮好

lixupeng 发表于 2011-4-16 23:36:20

mark!!

zhouhaiyeild 发表于 2011-6-13 10:24:01

支持,MARK一下!

songtao0728 发表于 2011-6-13 13:04:18

MARK

jayzah 发表于 2011-6-17 17:00:40

楼主 真是有心啊~~~~~

lihp1603 发表于 2011-8-1 15:12:27

M16寄存器加注释

youmeng 发表于 2011-8-2 10:23:08

mark
页: [1] 2
查看完整版本: AVR寄存器中的每一位都能记得住吗? 原创--AVR寄存器位功能注释