上传带注释的iom32v.h和iom8v.h头文件,希望对大家有用,编程的时候不用查数据手册

ATMEGA(数码管加减显示) #include <iom8v.h> /******************************************************************** 数据类型定义 *********************************************************************/ #define uchar unsigned char #define uint unsigned int #define WEI. 阅读详情
点击此处下载 ourdev_283682.rar(文件大小:13K) (原文件名:avr头文件.rar) 
包括iom8v.h,iom32v.h
#ifndef __iom32v_h
#define __iom32v_h

/*typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;      // Unsigned  8 bit quantity
typedef signed   char  INT8S;      // Signed    8 bit quantity
typedef unsigned int   INT16U;     // Unsigned 16 bit quantity
typedef signed   int   INT16S;     // Signed   16 bit quantity
typedef unsigned long  INT32U;     // Unsigned 32 bit quantity
typedef signed   long  INT32S;     // Signed   32 bit quantity
typedef float          FP32;       // Single precision floating point

//位定义(m.b.b0=1;)整体定义m.a=0xff;同时使用联合和结构
union
{ struct
  { unsigned b0:1;
   unsigned b1:1;
   unsigned b2:1;
   unsigned b3:1;
   unsigned b4:1;
   unsigned b5:1;
   unsigned b6:1;
   unsigned b7:1;
  }b;
  INT8U a;
}m;

for(i=n;n!=0;n--);    //延时周期 4n   (i定义为unsigned char)
for(i=n;n!=0;n--);    //延时周期 6n+1 (i定义为unsigned int)

unsigned char  1 0~255
signed char    1 -128~127
char(*)        1 0~255
unsigned short 2 0~65535
signed short   2 -32768~32767
unsigned int   2 0~65535
signed int     2 -32768~32767
unsigned long  4 0~4294967295
signed long    4 -2147483648~2147483647
float      4
double     4
*/
/*ATmega32所有的I/O及外设都被放置于I/O空间。所有的I/O位置都可以通过IN 与OUT指令
来访问,在32个通用工作寄存器和I/O 之间传输数据。 地址为0x00 - 0x1F 的I/O 寄存器
还可用SBI 和CBI 指令直接进行位寻址,而SBIS 和SBIC 则用来检查某一位的值。更多
内容请参见指令集。使用IN 和OUT指令时地址必须在 0x00 - 0x3F之间。如果要象SRAM
一样通过LD 和ST 指令访问I/O 寄存器,相应的地址要加上0x20。*/

/* ATmega32 header file for
   ImageCraft ICCAVR compiler*/
/* not strictly sorted by address no more */
/* interrupt vector number definitions added */
/* last changed 2002/05/01 */

/* 2 wire serial interface 400kHz 两线串行接口TWI,总线电容要低于400pF*/
#define TWBR (*(volatile unsigned char *)0x20) //比特率寄存器
//TWI 工作在主机模式时,TWBR 值应该不小于10
#define TWSR (*(volatile unsigned char *)0x21) //状态寄存器
#define  TWPS1    1 //预分频位
#define  TWPS0    0
//SCL_Hz=CPU_Hz/(16+2(TWBR)*4^twps指)
//00->1 01->4 10->16 11->64 
#define TWCR (*(volatile unsigned char *)0x56) //控制寄存器
#define  TWINT    7 //中断标志,清零必须通过软件写"1”
#define  TWEA     6 //使能应答,TWEA 清零可以使器件暂时脱离总线。置位后器件重新恢复地址识别。
#define  TWSTA    5 //START 状态标志,发送START之后软件必须清零TWSTA
#define  TWSTO    4 //STOP 状态位,自动清零
#define  TWWC     3 //写冲突标志
#define  TWEN     2 //TWI使能
#define  TWIE     0 //中断使能
#define TWAR (*(volatile unsigned char *)0x22) //地址寄存器
#define  TWGCE    0 //1 读  0写
//高7位为从机地址,
#define TWDR (*(volatile unsigned char *)0x23) //数据寄存器
//只要TWINT 置位,TWDR 的数据就是稳定的,其内容为要发送的下一个字节,或是接收到的数据

/* ADC 50k-200kHz*/
#define ADC  (*(volatile unsigned int *)0x24)  //ADC结果寄存器
#define ADCL (*(volatile unsigned char *)0x24)
#define ADCH (*(volatile unsigned char *)0x25)
#define ADCSR (*(volatile unsigned char *)0x26)
#define ADCSRA (*(volatile unsigned char *)0x26) /*ADC 控制和状态寄存器*/
#define  ADEN     7 /*ADEN置位即启动ADC,否则ADC功能关闭。在转换过程中关闭ADC将立即终止转换。*/
#define  ADSC     6 /*ADC 开始转换*/
#define  ADFR     5 /*1 连续转换选择*/
#define  ADATE    5 /*ADC 自动触发使能*/
#define  ADIF     4 /*在ADC 转换结束,且数据寄存器被更新后, ADIF 置位*/
#define  ADIE     3 /*ADC 中断使能*/
#define  ADPS2    2
#define  ADPS1    1
#define  ADPS0    0
/*分频因子000 001 010 011 100 101 110 111
            2   2   4   8  16  32  64 128*/
#define ADMUX (*(volatile unsigned char *)0x27)/*ADC 多工选择寄存器*/
#define  REFS1    7
#define  REFS0    6
/*00 外部aref 内部VREF关闭 01 AVCC AREF外加滤波电容 10 保留 11 2.56V片内基准电源*/
#define  ADLAR    5  /*0 右对齐 ,1 左对齐*/
#define  MUX3     3
#define  MUX2     2
#define  MUX1     1
#define  MUX0     0
/*通道 0000 0001 0010 0011 0100 0101 0110 0111 1000-1101 1110 1111
          0    1    2    3    4    5    6    7    保留   1.23v 0v*/

/* Analog Comparator */
#define  ACSR (*(volatile unsigned char *)0x28) /*模拟比较器控制和状态寄存器*/
#define  ACD      7 /*ACD 置位时,模拟比较器的电源被切断*/
#define  ACBG     6 /*ACBG 置位后,模拟比较器的正极输入由能隙基准源所取代*/
#define  ACO      5 /*模拟比较器输出*/
#define  ACI      4 /*当比较器的输出事件触发了由ACIS1及ACIS0定义的中断模式时,ACI 置位*/
#define  ACIE     3 /*模拟比较器中断使能*/
#define  ACIC     2 /*ACIC置位后允许通过模拟比较器来触发T/C1 的输入捕捉功能*/
#define  ACIS1    1
#define  ACIS0    0
/*00 输出变化中断 01 保留 10 下降沿中断 11 上升沿中断*/

/* USART */
#define UBRRHI (*(volatile unsigned char *)0x40)
#define UBRRH (*(volatile unsigned char *)0x40) /*波特率寄存器 4位*/
#define  URSEL    7 /*UCSRC与UBRRH选择 0为UBRRH*/
#define UBRR (*(volatile unsigned char *)0x29)
#define UBRRL (*(volatile unsigned char *)0x29) /*波特率寄存器 8位*/
#define UCSRC (*(volatile unsigned char *)0x40) /*控制和状态寄存器C*/
#define  URSEL    7 /*UCSRC与UBRRH选择 1为UCSRC*/
#define  UMSEL    6 /*模式选择 0异步 1同步*/
#define  UPM1     5 /*奇偶校验模式*/
#define  UPM0     4
/*00 禁止 01 保留 10 偶检验 11 奇检验*/
#define  USBS     3 /*停止位选择 0 1位 1 2位*/
#define  UCSZ1    2 /*字符长度与UCSRB中的UCSZ2共用*/
#define  UCSZ0    1
/*000 5位 001 6位 010 7位 011 8位 100 101 110 保留 111 9位*/
#define  UCPOL    0 /*时钟极性 这一位仅用于同步工作模式*/

#define UCSRB (*(volatile unsigned char *)0x2A) /*控制和状态寄存器B*/
#define  RXCIE    7  /*接收结束中断使能*/
#define  TXCIE    6  /*发送结束中断使能*/
#define  UDRIE    5  /*数据寄存器空中断使能*/
#define  RXEN     4  /*置位后将启动USART 接收器*/
#define  TXEN     3  /*置位后将启动USART 发送器*/
#define  UCSZ2    2  /*字符长度*/
#define  RXB8     1  /*接收数据位8*/
#define  TXB8     0  /*发送数据位8*/
#define UCSRA (*(volatile unsigned char *)0x2B) /*控制和状态寄存器A*/
#define  RXC      7 /*接收缓冲器中有未读出的数据时RXC 置位,否则清零*/
#define  TXC      6 /*发送移位缓冲器中的数据被送出,且当发送缓冲器 (UDR) 为空时TXC 置位,自动清零和写1清零*/
#define  UDRE     5 /*UDRE为1说明发送缓冲器为空,已准备好进行数据接收。*/
#define  FE       4 /*帧错误*/
#define  DOR      3 /*数据溢出时DOR 置位*/
#define  OVR      3 /*This definition differs from the databook*/
#define  PE       2 /*奇偶校验错误*/
#define  U2X      1 /*倍速发送,异步有用*/
#define  MPCM     0 /*多处理器通信模式*/
#define UDR (*(volatile unsigned char *)0x2C)
/*发送和接收数据寄存器 相当于51的SBUF*/

/* SPI */
#define SPCR (*(volatile unsigned char *)0x2D)
#define  SPIE     7  //中断使能
#define  SPE      6  //使能SPI
#define  DORD     5  //数据次序,'1' 低位先发送
#define  MSTR     4  //主从机选择 '1'为主机
#define  CPOL     3  //CPOL置位表示空闲时SCK 为高电平
#define  CPHA     2  //时钟相位,'0'CPHA 决定数据是在SCK 的起始沿采样
#define  SPR1     1  //SPI 时钟速率选择1 与0
#define  SPR0     0
/*00 1/4    01 1/16   10 1/64   11 1/128*/
#define SPSR (*(volatile unsigned char *)0x2E)
#define  SPIF     7  //中断标志
#define  WCOL     6  //写冲突标志,在发送当中对SPI 数据寄存器SPDR写数据将置位WCOL。
//WCOL可以通过先读SPSR,紧接着访问SPDR 来清零。
#define  SPI2X    0  //置位后SPI 的速度加倍
#define SPDR (*(volatile unsigned char *)0x2F) //SPI 数据寄存器
/*CPOL 与CPHA 功能
                       起始沿          结束沿    SPI 模式
CPOL = 0, CPHA = 0 采样 ( 上升沿) 设置 ( 下降沿) 0
CPOL = 0, CPHA = 1 设置 ( 上升沿) 采样 ( 下降沿) 1
CPOL = 1, CPHA = 0 采样 ( 下降沿) 设置 ( 上升沿) 2
CPOL = 1, CPHA = 1 设置 ( 下降沿) 采样 ( 上升沿) 3
SPI 引脚重载(1)
引脚方向, SPI 主机方向, SPI 从机
MOSI     用户定义   输入
MISO     输入   用户定义
SCK     用户定义   输入
SS     用户定义   输入*/

/*void SPI_MasterInit(void)
{
    //设置MOSI,SCK,SS为输出,MISO为输入 
DDR_SPI |=(1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
// 使能SPI 主机模式,设置时钟速率为fck/16 
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0);
//使能SPI,主机模式,SCK空闲时为高,SCK结束沿采样,1/16
}
void SPI_SlaveInit(void)
{
    //设置MISO为输出,其他为输入
   DDR_SPI |= (1<<DD_MISO);
   // 使能 SPI
   SPCR = (1<<SPE)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0);
}
*/
/* Port D */
#define PIND (*(volatile unsigned char *)0x30)
#define DDRD (*(volatile unsigned char *)0x31)
#define PORTD (*(volatile unsigned char *)0x32)

/* Port C */
#define PINC (*(volatile unsigned char *)0x33)
#define DDRC (*(volatile unsigned char *)0x34)
#define PORTC (*(volatile unsigned char *)0x35)

/* Port B */
#define PINB (*(volatile unsigned char *)0x36)
/*端口B 输入引脚地址*/
#define DDRB (*(volatile unsigned char *)0x37)
/*端口B 数据方向寄存器 1 为输出 0 为输入*/
#define PORTB (*(volatile unsigned char *)0x38)
/*端口B 数据寄存器*/
 
/* Port A */
#define PINA (*(volatile unsigned char *)0x39)
#define DDRA (*(volatile unsigned char *)0x3A)
#define PORTA (*(volatile unsigned char *)0x3B)

/*未用脚,用内部上拉,或者外部上下拉
先PROTA=0xff;后DDRA=0x00;
引脚配置为输入时,若PORTxn 为"1“,上拉电阻将使能。
当引脚配置为输出时,若PORTxn 为"1“,引脚输出高电平("1“),
在上拉输入和输出低电平之间切换也有同样的问题。用户必须选择高阻态({DDxn,
PORTxn} = 0b00) 或输出高电平({DDxn, PORTxn} = 0b11) 作为中间步骤。
DDxn PORTxn PUD(SFIOR中) I/O  上拉电阻 说明
0   0  X   输入 No     高阻态 (Hi-Z)
0   1  0   输入 Yes     被外部电路拉低时将输出电流
0   1  1   输入 No     高阻态(Hi-Z)
1   0  X   输出 No     输出低电平 ( 漏电流)
1   1  X   输出 No     输出高电平 ( 源电流)*/

/* EEPROM */
#define EECR (*(volatile unsigned char *)0x3C) //控制寄存器
#define  EERIE    3  //就绪中断使能
#define  EEMWE    2  //主机写使能,EEWE置位是否可以启动EEPROM写操作
#define  EEWE     1  //写使能,置位EEWE以便将数据写入EEPROM
#define  EERE     0  //EEPROM 读使能
/* 写时序如下( 第3 步和第4 步的次序并不重要):
1. 等待EEWE 位变为零。
2. 等待SPMCSR 中的SPMEN 位变为零。
3. 将新的EEPROM 地址写入EEAR( 可选)。
4. 将新的EEPROM 数据写入EEDR( 可选)。
5. 对EECR 寄存器的EEMWE 写"1",同时清零EEWE。
6. 在置位EEMWE 的4 个周期内,置位EEWE*/
#define EEDR (*(volatile unsigned char *)0x3D) //数据寄存器
#define EEAR (*(volatile unsigned int *)0x3E)
#define EEARL (*(volatile unsigned char *)0x3E) //地址寄存器
#define EEARH (*(volatile unsigned char *)0x3F)

/* Watchdog Timer Control Register */
#define WDTCR (*(volatile unsigned char *)0x41) //看门狗定时器控制寄存器
#define  WDCE     4 //看门狗修改使能,清零WDE 时必须先置位WDCE,否则不能禁止看门狗。
#define  WDTOE    4    /*This definition differs from the databook*/
#define  WDE      3 //看门狗使能,只有在WDCE为"1“时WDE才能清零
/*以下为关闭看门狗的步骤:
1. 在同一个指令内对WDCE 和WDE 写"1“,即使WDE 已经为"1“。
2. 在紧接的4 个时钟周期之内对WDE 写"0”。
asm("cli");WDTCR|=(1<<WDCE)|(1<<WDTOE);WDTCR&=~(1<<WDCE);asm("sei");*/
#define  WDP2     2 //看门狗定时器预分频器2, 1, 和0
#define  WDP1     1
#define  WDP0     0
#define WDT()     (WDTCR = (1<<WDCE) | (1<<WDE)); //启动看门狗
/*清除asm("wdr")
          溢出周期         3V时间  5V时间
   000 16K (16,384)       17.1 ms 16.3 ms
   001 32K (32,768)       34.3 ms 32.5 ms
   010 64K (65,536)       68.5 ms 65 ms
   011 128K (131,072)     0.14 s 0.13 s
   100 256K (262,144)     0.27 s 0.26 s
   101 512K (524,288)     0.55 s 0.52 s
   110 1,024K (1,048,576) 1.1 s 1.0 s
   111 2,048K (2,097,152) 2.2 s 2.1 s*/
/* Timer/Counter 2 */
#define ASSR (*(volatile unsigned char *)0x42) //异步状态寄存器
#define  AS2      3 //异步 T/C2  0-内部 1-TOSC1 时钟
#define  TCN2UB   2 //T/C2 更新中
#define  OCR2UB   1 //输出比较寄存器2 更新中
#define  TCR2UB   0 //T/C2 控制寄存器更新中
#define OCR2 (*(volatile unsigned char *)0x43) //输出比较寄存器2
#define TCNT2 (*(volatile unsigned char *)0x44) //定时器/ 计数器2寄存器
#define TCCR2 (*(volatile unsigned char *)0x45) //T/C2控制寄存器
#define  FOC2     7 //强制输出比较
#define  WGM20    6 //波形产生模式
#define  COM21    5 //比较匹配输出模式
#define  COM20    4
/*com21 com20 
比较输出模式,非PWM 模式
00 正常的端口操作,OC2未连接   01 比较匹配发生时OC2 取反
10 比较匹配发生时OC2清零   11 比较匹配发生时OC2 置位

比较输出模式,快速PWM 模式
00 正常的端口操作,OC2 未连接   01 保留
10 比较匹配发生时OC2 清零 ,计数到TOP 时OC0 置位
11 比较匹配发生时OC2 置位 ,计数到TOP 时OC0 清零

比较输出模式,相位修正PWM 模式
00 正常的端口操作, OC2 未连接   01 保留
10 在升序计数时发生比较匹配将清零OC2 ;降序计数时发生比较匹配将置位OC2
11 在升序计数时发生比较匹配将置位OC2 ;降序计数时发生比较匹配将清零OC2
*/
#define  WGM21    3 //波形产生模式
/*WGM21 WGM20  T/C的工作模式  TOP  OCR2的更新时间 TOV2的置位时刻
  0     0      普通   oxff 立即更新   MAX
  0     1      相位修正PWM    0xFF TOP    BOTTOM
  1  0     CTC    OCR2 立即更新   MAX
  1  1     快速 PWM    0xFF TOP    MAX*/
#define  CS22     2 //时钟选择
#define  CS21     1
#define  CS20     0
/*000 无时钟,T/C 不工作 001 clk/T2S   010 1/8    011 1/32
  100 1/64         101 1/128   110 1/256   111 1/1024
*/
/*在某些操作模式下, TOP 值或T/C 的最大值可由OCR1A 寄存器、ICR1 寄存器,或一
些固定数据来定义。在PWM 模式下用OCR1A 作为TOP 值时, OCR1A 寄存器不能用
作PWM 输出。但此时OCR1A 是双向缓冲的, TOP 值可在运行过程中得到改变。当需
要一个固定的TOP 值时可以使用ICR1 寄存器,从而释放OCR1A 来用作PWM 的输出。*/
/* Timer/Counter 1 */
#define ICR1 (*(volatile unsigned int *)0x46)  //输入捕捉寄存器
#define ICR1L (*(volatile unsigned char *)0x46)
#define ICR1H (*(volatile unsigned char *)0x47)
#define OCR1B (*(volatile unsigned int *)0x48)  //输出比较寄存器1B
#define OCR1BL (*(volatile unsigned char *)0x48)
#define OCR1BH (*(volatile unsigned char *)0x49)
#define OCR1A (*(volatile unsigned int *)0x4A)  //输出比较寄存器1A
#define OCR1AL (*(volatile unsigned char *)0x4A)
#define OCR1AH (*(volatile unsigned char *)0x4B)
#define TCNT1 (*(volatile unsigned int *)0x4C)  //定时器/计数器TCNT1
#define TCNT1L (*(volatile unsigned char *)0x4C)
#define TCNT1H (*(volatile unsigned char *)0x4D)
#define TCCR1B (*(volatile unsigned char *)0x4E) //T/C控制寄存器B
#define  ICNC1    7 //输入捕捉噪声抑制器,4个相同才输入
#define  ICES1    6 //输入捕捉触发沿选择 0下降沿  1上升沿
#define  WGM13    4
#define  WGM12    3
#define  CS12     2 //分频
#define  CS11     1
#define  CS10     0
/*CS12:0 = 0 时,计数器停止计数。
  CS12:0 = 1 时,系统内部时钟直接作为T/C的时钟源,
  CS12:0 = 2 8分频 3 64分频 4 256分频 5 1024分频
  CSn2:0 = 6 外部T1 引脚,下降沿驱动
  CSn2:0 = 7 外部T1 引脚,上升沿驱动*/
#define TCCR1A (*(volatile unsigned char *)0x4F)//T/C控制寄存器A
#define  COM1A1   7 //通道A 的比较输出模式
#define  COM1A0   6
#define  COM1B1   5 //通道B 的比较输出模式
#define  COM1B0   4
/*比较输出模式,非PWM
  0 0 普通端口操作,OC1A/OC1B 未连接
  0 1 比较匹配时OC1A/OC1B 电平取反
  1 0 比较匹配时清零OC1A/OC1B( 输出低电平)
  1 1 比较匹配时置位 OC1A/OC1B ( 输出高电平)
  比较输出模式,快速PWM
  0 0 普通端口操作, OC1A/OC1B 未连接
  0 1 WGM13:0 = 15: 比较匹配时OC1A 取反 ,OC1B 未连接。WGM13:0 为其它值时为普通端口操作, OC1A/OC1B 未连接
  1 0 比较匹配时清零 OC1A/OC1B, OC1A/OC1B在TOP 时置位
  1 1 比较匹配时置位 OC1A/OC1B, OC1A/OC1B在TOP 时清零
  比较输出模式,相位修正及相频修正 PWM 模式
  0 0 普通端口操作, OC1A/OC1B 未连接
  0 1 WGM13:0 = 9 或14: 比较匹配时OC1A 取反,OC1B 未连接。 WGM13:0为其它值时为普通端口操作, OC1A/OC1B 未连接
  1 0 升序记数时比较匹配将清零OC1A/OC1B,降序记数时比较匹配将置位OC1A/OC1B
  1 1 升序记数时比较匹配将置位OC1A/OC1B,降序记数时比较匹配将清零OC1A/OC1B*/
#define  FOC1A    3 //通道A 强制输出比较
#define  FOC1B    2 //通道B 强制输出比较
//FOC1A/FOC1B只有当WGM13:0指定为非PWM模式时被激活
#define  WGM11    1
#define  WGM10    0
/* 模式 WGM13:0 定时器/计数器工作模式 TOP   OCR1x更新时刻 TOV1置位时刻
   0 0 0 0 0   普通模式  0xFFFF 立即更新  MAX
   1 0 0 0 1   8位相位修正PWM   0x00FF TOP   BOTTOM
   2 0 0 1 0   9位相位修正PWM   0x01FF TOP   BOTTOM
   3 0 0 1 1   10位相位修正PWM   0x03FF TOP   BOTTOM
   4 0 1 0 0   CTC   OCR1A  立即更新  MAX
   5 0 1 0 1   8位快速PWM   0x00FF TOP   TOP
   6 0 1 1 0   9位快速PWM   0x01FF TOP   TOP
   7 0 1 1 1   10位快速PWM   0x03FF TOP   TOP
   8 1 0 0 0   相位与频率修正PWM   ICR1  BOTTOM   BOTTOM
   9 1 0 0 1   相位与频率修正PWM   OCR1A  BOTTOM   BOTTOM
  10 1 0 1 0   相位修正PWM   ICR1  TOP   BOTTOM
  11 1 0 1 1   相位修正PWM   OCR1A  TOP   BOTTOM
  12 1 1 0 0   CTC   ICR1  立即更新  MAX
  13 1 1 0 1   保留  –  –   –
  14 1 1 1 0   快速PWM   ICR1   TOP   TOP
  15 1 1 1 1   快速PWM   OCR1A  TOP   TOP*/

/* Special Function I/O register */
#define SFIOR (*(volatile unsigned char *)0x50)/*特殊功能IO 寄存器*/
#define  ADTS2    7  //ADC 自动触发源
#define  ADTS1    6
#define  ADTS0    5
/*000 连续转换模式 001 模拟比较器 010 外部中断请求0 011 定时器/计数器0比较匹配
  100 定时器/计数器0溢出 101 定时器/计数器比较匹配B
  110 定时器/计数器1溢出 111 定时器/计数器1捕捉事件*/
#define  ADHSM    4 //保留
#define  ACME     3 //模拟比较器多路复用器使能,逻辑"1,ADC 处于关闭状态
#define  PUD      2 //禁用上拉电阻
#define  PSR2     1 //预分频复位T/C2 写'1'
#define  PSR10    0 //置位时T/C1与T/C0的预分频器复位。由硬件自动清零

/* Oscillator Calibration */
#define OSCCAL (*(volatile unsigned char *)0x51) //振荡器标定寄存器
/* On-Chip Debug register */
#define OCDR (*(volatile unsigned char *)0x51)

/* Timer/Counter 0 */
#define OCR0 (*(volatile unsigned char *)0x5C)
#define TCNT0 (*(volatile unsigned char *)0x52)
/*T/C 寄存器*/
#define TCCR0 (*(volatile unsigned char *)0x53)
/*T/C 控制寄存器*/
#define  FOC0     7  //强制输出比较
#define  WGM00    6  //WGM01:0: 波形产生模式
#define  COM01    5  //COM01:0: 比较匹配输出模式
#define  COM00    4
#define  WGM01    3
#define  CS02     2
#define  CS01     1
#define  CS00     0
/*模式 WGM01 WGM00 T/C 的工作模式  TOP  OCR0更新时间 TOV0置位时刻
  0    0   0     普通    0xFF 立即更新  MAX
  1    0   1     PWM,相位修正   0xFF TOP   BOTTOM
  2    1   0     CTC     OCR0 立即  更新MAX
  3    1   1     快速 PWM     0xFF TOP   MAX*/
  
/*000 无时钟 001 clk/1 ( 没有预分频) 010 clk/8 ( 来自预分频器) 011 clk/64
  100 clk/256 101 clk/1024 110 T0引脚输入,下降沿触发 111 T0引脚输入,上升沿触发*/

/* MCU general */
#define MCUCSR (*(volatile unsigned char *)0x54)
#define MCUSR (*(volatile unsigned char *)0x54) //控制和状态寄存器
#define  JTD      7 //禁止JTAG 接口,必须在四个时钟周期内将期望的数值两次写入JTD。
#define  ISC2     6 //中断2 触发方式控制 0-下降沿,1-上升沿
#define  JTRF     4 //JTAG 复位标志
#define  WDRF     3 //看门狗复位标志,上电复位和写0清零
#define  BORF     2 //掉电检测复位发生时置位,上电复位和写0清零
#define  EXTRF    1 //外部复位标志,上电复位和写0清零
#define  PORF     0 //上电复位标志,只能通过写"0"来清除
#define MCUCR (*(volatile unsigned char *)0x55) //MCU 控制寄存
#define  SE       7 //休眠使能
#define  SM2      6
#define  SM1      5
#define  SM0      4
/*000 空闲模式 001 ADC 噪声抑制模式 010 掉电模式 011 省电模式
  100 保留    101 保留 110 仅在使用外部晶体或谐振器时Standby 模式才可用 */
#define  ISC11    3 //中断1 触发方式控制
#define  ISC10    2
#define  ISC01    1 //中断0 触发方式控制
#define  ISC00    0
/*00 为低电平时产生中断请求 01 引脚上任意的逻辑电平变化都将引发中断
  10 下降沿产生中断请求 11 上升沿产生中断请求*/

/* SPM Conrol Register */
#define SPMCR (*(volatile unsigned char *)0x57) //保存程序存储器控制寄存器
#define  SPMIE    7 //中断使能
#define  RWWSB    6 //RWW 区忙标志
#define  RWWSRE   4 //RWW 区读使能
#define  BLBSET   3 //Boot 锁定位设置
#define  PGWRT    2 //页写入
#define  PGERS    1 //页擦除
#define  SPMEN    0 //存贮程序存储器使能

/* Timer/Counter Interrupts */
#define TIFR (*(volatile unsigned char *)0x58) //定时器/ 计数器 中断标志寄存器
#define  OCF2     7 //输出比较标志2
#define  TOV2     6 //T/C2 溢出标志
#define  ICF1     5 //T/C1 输入捕捉标志
#define  OCF1A    4 //T/C1 输出比较 A 匹配标志
#define  OCF1B    3 //T/C1 输出比较 B 匹配标志
#define  TOV1     2 //T/C1 溢出标志,写1 来清零
#define  OCF0 1 //T/C0 输出比较标志0,中断硬件清零,也可以对其写1 来清零。
#define  TOV0     0 //T/C0 溢出标志,写1 来清零
#define TIMSK (*(volatile unsigned char *)0x59) //定时器/ 计数器中断屏蔽寄存器
#define  OCIE2    7 //T/C2 输出比较匹配中断使能
#define  TOIE2    6 //T/C2 溢出中断使能
#define  TICIE1   5 //T/C1 输入捕捉中断使能
#define  OCIE1A   4 //T/C1 输出比较A匹配中断使能
#define  OCIE1B   3 //T/C1 输出比较B匹配中断使能
#define  TOIE1    2 //T/C1 溢出中断使能
#define  OCIE0 1 //T/C0 输出比较匹配中断使能
#define  TOIE0    0 //T/C0 溢出中断使能

/* General Interrupts */
#define GIFR (*(volatile unsigned char *)0x5A) //通用中断标志寄存器
#define  INTF1    7 //外部中断标志1 ,写入”1” 来清零
#define  INTF0    6 //外部中断标志0 ,写入”1” 来清零
#define  INTF2    5 //外部中断标志2 ,写入”1” 来清零

#define GICR (*(volatile unsigned char *)0x5B) //通用中断控制寄存器
#define  INT1     7 //外部中断请求1 使能
#define  INT0     6 //外部中断请求0 使能
#define  INT2     5 //外部中断请求2 使能
#define  IVSEL    1 //中断向量选择 1时,中断向量转移到Boot 区的起始地址
#define  IVCE     0 //中断向量修改使能,改变IVSEL 时IVCE 必须置位。
/*为了防止无意识地改变中断向量表,修改IVSEL 时需要遵照如下过程:
1. 置位中断向量修改使能位IVCE
2. 在紧接的4 个时钟周期里将需要的数据写入IVSEL,同时对IVCE 写”0”
asm("cli");GICR=1<<IVCE;GICR=1<<IVSEL;asm("sei");*/
/* Stack Pointer */
#define SP (*(volatile unsigned int *)0x5D)
#define SPL (*(volatile unsigned char *)0x5D)
#define SPH (*(volatile unsigned char *)0x5E)

/* Status REGister */
#define SREG (*(volatile unsigned char *)0x5F)
/*Bit 7 – I: 全局中断使能     Bit 6 – T: 位拷贝存储,BLD 和BST利用T作为目的或源地址
  Bit 5 – H: 半进位标志    Bit 4 – S: 符号位, S = N ⊕ V
  Bit 3 – V:2 的补码溢出标志  Bit 2 – N: 负数标志
  Bit 1 – Z: 零标志    Bit 0 – C: 进位标志
*/
/* Port A bits */
#define  PORTA7   7
#define  PORTA6   6
#define  PORTA5   5
#define  PORTA4   4
#define  PORTA3   3
#define  PORTA2   2
#define  PORTA1   1
#define  PORTA0   0
#define  PA7      7
#define  PA6      6
#define  PA5      5
#define  PA4      4
#define  PA3      3
#define  PA2      2
#define  PA1      1
#define  PA0      0

#define  DDA7     7
#define  DDA6     6
#define  DDA5     5
#define  DDA4     4
#define  DDA3     3
#define  DDA2     2
#define  DDA1     1
#define  DDA0     0

#define  PINA7    7
#define  PINA6    6
#define  PINA5    5
#define  PINA4    4
#define  PINA3    3
#define  PINA2    2
#define  PINA1    1
#define  PINA0    0

/* Port B bits */
#define  PORTB7   7
#define  PORTB6   6
#define  PORTB5   5
#define  PORTB4   4
#define  PORTB3   3
#define  PORTB2   2
#define  PORTB1   1
#define  PORTB0   0
#define  PB7      7
#define  PB6      6
#define  PB5      5
#define  PB4      4
#define  PB3      3
#define  PB2      2
#define  PB1      1
#define  PB0      0

#define  DDB7     7
#define  DDB6     6
#define  DDB5     5
#define  DDB4     4
#define  DDB3     3
#define  DDB2     2
#define  DDB1     1
#define  DDB0     0

#define  PINB7    7
#define  PINB6    6
#define  PINB5    5
#define  PINB4    4
#define  PINB3    3
#define  PINB2    2
#define  PINB1    1
#define  PINB0    0

/* Port C bits */
#define  PORTC7   7
#define  PORTC6   6
#define  PORTC5   5
#define  PORTC4   4
#define  PORTC3   3
#define  PORTC2   2
#define  PORTC1   1
#define  PORTC0   0
#define  PC7      7
#define  PC6      6
#define  PC5      5
#define  PC4      4
#define  PC3      3
#define  PC2      2
#define  PC1      1
#define  PC0      0

#define  DDC7     7
#define  DDC6     6
#define  DDC5     5
#define  DDC4     4
#define  DDC3     3
#define  DDC2     2
#define  DDC1     1
#define  DDC0     0

#define  PINC7    7
#define  PINC6    6
#define  PINC5    5
#define  PINC4    4
#define  PINC3    3
#define  PINC2    2
#define  PINC1    1
#define  PINC0    0

/* Port D bits */
#define  PORTD7   7
#define  PORTD6   6
#define  PORTD5   5
#define  PORTD4   4
#define  PORTD3   3
#define  PORTD2   2
#define  PORTD1   1
#define  PORTD0   0
#define  PD7      7
#define  PD6      6
#define  PD5      5
#define  PD4      4
#define  PD3      3
#define  PD2      2
#define  PD1      1
#define  PD0      0

#define  DDD7     7
#define  DDD6     6
#define  DDD5     5
#define  DDD4     4
#define  DDD3     3
#define  DDD2     2
#define  DDD1     1
#define  DDD0     0

#define  PIND7    7
#define  PIND6    6
#define  PIND5    5
#define  PIND4    4
#define  PIND3    3
#define  PIND2    2
#define  PIND1    1
#define  PIND0    0


/* Lock and Fuse Bits with LPM/SPM instructions */

/* lock bits */
#define  BLB12    5
#define  BLB11    4
#define  BLB02    3
#define  BLB01    2
#define  LB2      1
#define  LB1      0

/* fuses low bits */
#define  BODLEVEL 7
#define  BODEN    6
#define  SUT1     5
#define  SUT0     4
#define  CKSEL3   3
#define  CKSEL2   2
#define  CKSEL1   1
#define  CKSEL0   0

/* fuses high bits */
//#define  RSTDISBL 7 //ATmega8
//#define  WDTON    6 //ATmega8
#define  OCDEN    7
#define  JTAGEN   6
#define  SPIEN    5
#define  CKOPT    4
#define  EESAVE   3
#define  BOOTSZ1  2
#define  BOOTSZ0  1
#define  BOOTRST  0

/* Interrupt Vector Numbers */
#define iv_RESET        1  //外部引脚,上电复位,掉电检测复位,看门狗复位
#define iv_INT0         2  //外部中断请求0
#define iv_INT1         3  //外部中断请求1
#define iv_INT2         4  //外部中断请求2
#define iv_TIMER2_COMP  5  //定时器/ 计数器2 比较匹配
#define iv_TIMER2_OVF   6  //定时器/ 计数器2 溢出
#define iv_TIMER1_CAPT  7  //定时器/ 计数器1 捕捉事件
#define iv_TIMER1_COMPA 8  //定时器/ 计数器1 比较匹配 A
#define iv_TIMER1_COMPB 9  //定时器/ 计数器1 比较匹配 B
#define iv_TIMER1_OVF   10 //定时器/ 计数器1 溢出
#define iv_TIMER0_COMP  11 //定时器/ 计数器0 比较匹配
#define iv_TIMER0_OVF   12 //定时器/ 计数器0 溢出
#define iv_SPI_STC      13 //SPI 串行传输结束
#define iv_USART_RX     14 
#define iv_USART_RXC    14 //USART, Rx 结束
#define iv_USART_DRE    15
#define iv_USART_UDRE   15 //USART 数据寄存器空
#define iv_USART_TX     16
#define iv_USART_TXC    16 //USART, Tx 结束
#define iv_ADC          17 //ADC 转换结束
#define iv_EE_RDY       18 //EEPROM 就绪
#define iv_EE_READY     18
#define iv_ANA_COMP     19 //模拟比较器
#define iv_ANALOG_COMP  19
#define iv_TWI          20 //两线串行接口
#define iv_TWSI         20
#define iv_SPM_RDY      21 //保存程序存储器内容就绪
#define iv_SPM_READY    21

/*外部时钟
CKSEL3..0  频率范围(MHz)  SUT1..0
0000    00    6 CK – BOD 使能
   01    6 CK 4.1 ms 电源快速上升
   10    6 CK 65 ms 电源缓慢上升
   11   保留
片内标定的RC 振荡器工作模式
0001 1    00   6 CK – BOD 使能
0010 2    01   6 CK 4.1 ms 电源快速上升
0011 4    10   6 CK 65 ms 电源缓慢上升
0100 8    11   保留
外部RC 振荡器工作模式
0101 <=0.9      00    18 CK – BOD 使能
0110 0.9-3    01    18 CK 4.1 ms 电源快速上升
0111 3-8        10    18 CK 65 ms 电源缓慢上升
1000 8-12    11   6 CK(1) 4.1 ms 电源快速上升,或是BOD 使能
低频晶体振荡器
1001 32.768 kHz     00    1K CK(1) 4.1 ms 电源快速上升,或是BOD 使能
       01    1K CK(1) 65 ms 电源缓慢上升
   10    32K CK 65 ms 启动时频率已经稳定
   11   保留
晶体振荡器  CKOPT 未编程时的最大频率为8 MHz,输出信号幅度比较小
1010 1   0.4-0.9  00 258 CK(1) 4.1 ms 陶瓷谐振器,电源快速上升
1100 1   0.9-3    01 258 CK(1) 65 ms 陶瓷谐振器,电源缓慢上升
1110 1   3-8    10 1K CK(2) – 陶瓷谐振器, BOD 使能
101,110,111 0   1<     11 1K CK(2) 4.1 ms 陶瓷谐振器,电源快速上升
1011 1   0.4-0.9  00 1k  CK(1) 65 ms 陶瓷谐振器,电源缓慢上升
1101 1   0.9-3    01 16k CK(1) – 石英振荡器, BOD 使能
1111 1   3-8    10 16k CK(2) 4.1 ms 石英振荡器,电源快速上升
101,110,111 0   1<     11 16k CK(2) 65 ms 石英振荡器,电源慢速上升
*/
 
/*WINAVR
// Interrupt vectors 

// External Interrupt Request 0
#define INT0_vect _VECTOR(1)
#define SIG_INTERRUPT0 _VECTOR(1)

// External Interrupt Request 1
#define INT1_vect _VECTOR(2)
#define SIG_INTERRUPT1 _VECTOR(2)

// External Interrupt Request 2
#define INT2_vect _VECTOR(3)
#define SIG_INTERRUPT2 _VECTOR(3)

// Timer/Counter2 Compare Match
#define TIMER2_COMP_vect _VECTOR(4)
#define SIG_OUTPUT_COMPARE2 _VECTOR(4)

// Timer/Counter2 Overflow 
#define TIMER2_OVF_vect _VECTOR(5)
#define SIG_OVERFLOW2 _VECTOR(5)

// Timer/Counter1 Capture Event 
#define TIMER1_CAPT_vect _VECTOR(6)
#define SIG_INPUT_CAPTURE1 _VECTOR(6)

// Timer/Counter1 Compare Match A
#define TIMER1_COMPA_vect _VECTOR(7)
#define SIG_OUTPUT_COMPARE1A _VECTOR(7)

// Timer/Counter1 Compare Match B
#define TIMER1_COMPB_vect _VECTOR(8)
#define SIG_OUTPUT_COMPARE1B _VECTOR(8)

// Timer/Counter1 Overflow 
#define TIMER1_OVF_vect _VECTOR(9)
#define SIG_OVERFLOW1 _VECTOR(9)

// Timer/Counter0 Compare Match 
#define TIMER0_COMP_vect _VECTOR(10)
#define SIG_OUTPUT_COMPARE0 _VECTOR(10)

// Timer/Counter0 Overflow
#define TIMER0_OVF_vect _VECTOR(11)
#define SIG_OVERFLOW0 _VECTOR(11)

// Serial Transfer Complete
#define SPI_STC_vect _VECTOR(12)
#define SIG_SPI _VECTOR(12)

// USART, Rx Complete 
#define USART_RXC_vect _VECTOR(13)
#define SIG_USART_RECV _VECTOR(13)
#define SIG_UART_RECV _VECTOR(13)

// USART Data Register Empty
#define USART_UDRE_vect _VECTOR(14)
#define SIG_USART_DATA _VECTOR(14)
#define SIG_UART_DATA _VECTOR(14)

// USART, Tx Complete
#define USART_TXC_vect _VECTOR(15)
#define SIG_USART_TRANS _VECTOR(15)
#define SIG_UART_TRANS _VECTOR(15)

// ADC Conversion Complete
#define ADC_vect _VECTOR(16)
#define SIG_ADC _VECTOR(16)

// EEPROM Ready
#define EE_RDY_vect _VECTOR(17)
#define SIG_EEPROM_READY _VECTOR(17)

// Analog Comparator
#define ANA_COMP_vect _VECTOR(18)
#define SIG_COMPARATOR _VECTOR(18)

// 2-wire Serial Interface
#define TWI_vect _VECTOR(19)
#define SIG_2WIRE_SERIAL _VECTOR(19)

// Store Program Memory Ready
#define SPM_RDY_vect _VECTOR(20)
#define SIG_SPM_READY _VECTOR(20)
*/

/*WINAVR
在程序中访问FLASH 程序存储器
#include <avr/pgmspace.h>
数据类型 变量名 PROGMEM = 值 ;如:
char val8 PROGMEM = 1 ;

pgm_read_byte(prog_void * addr)
pgm_read-word(prg_void *addr)
pgm_read_dword(prg_void* addr)

pgmspace.h 中定义的8 位整数类型 prog_char prog_uchar 分别指定在FLASH
内的8 位有符号整数和8 位无符号整数

EEPROM 数据存储器操作
#include <avr/eeprom.h>
这些函数有:
eeprom_is_ready() //EEPROM 忙检测(返回EEWE 位)
eeprom_busy_wait() //查询等待EEPROM 准备就绪
uint8_t eeprom_read_byte (const uint8_t *addr) //从指定地址读一字节
uint16_t eeprom_read_word (const uint16_t *addr) //从指定地址一字
void eeprom_read_block (void *buf, const void *addr, size_t n) //读块
void eeprom_write_byte (uint8_t *addr, uint8_t val) //写一字节至指定地址
void eeprom_write_word (uint16_t *addr, uint16_t val) //写一字到指定地址
void eeprom_write_block (const void *buf, void *addr, size_t n) //写块

void my_init_portb (void) __attribute__ ((naked)) \
__attribute__ ((section (".init1")));
void my_init_portb (void)
{
PORTB= 0xff;
DDRB=0xff;
}
使用__arrribute__关键字为函数指定属性要在函数的原型声明上,而不是函数的实现例
程里。由于属性section(“.init1”)的指定,编译后函数my_init_portb 生成的代码自动插入
到.init1 段中,在main 函数前就得到执行。naked 属性确保编译后该函数不生成返回指令,
使下一个初始化段得以顺序的执行。

中断服务程序
SIGNAL(signame)和INTERRUPT(signame)。
宏INTERRUPT 的用法与SIGNAL 类似,区别在于SIGNAL 执行时全局中断触发位被
清除、其他中断被禁止,INTERRUPT 执行时全局中断触发位被置位、其他中断可嵌套执行。

signame 中 断 类 型
SIG_INTERRUPT0 外部中断INT0
SIG_INTERRUPT1 外部中断INT1
SIG_OUTPUT_COMPARE2 定时器/计数器比较匹配中断
SIG_OVERFLOW2 定时器/计数器2 溢出中断
SIG_INPUT_CAPTURE1 定时器/计数器2 输入捕获中断
SIG_OUTPUT_COMPARE1A 定时器/计数器1 比较匹配A
SIG_OUTPUT_COMPARE1B 定时器/计数器1 比较匹配B
SIG_OVERFLOW1 定时器/计数器1 溢出中断
SIG_OVERFLOW0 定时器/计数器0 溢出中断
SIG_SPI SPI 操作完成中断
SIG_UART_RECV USART 接收完成
SIG_UART_DATA USART 寄存器空
SIG_UART_TRANS USART 发送完成
SIG_ADC ADC转换完成
SIG_EEPROM_READY E2PROM 准备就绪
SIG_COMPARATOR 模拟比较器中断
SIG_2WIRE_SERIAL TWI 中断
SIG_SPM_READY 写程序存储器准备好

以下是个外部中断0 的重写示例:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
SIGNAL(SIG_INTERRUPT0)

看门狗应用
#include <avr/wdt.h>
wdt_reset() // Watchdog 复位
wdt_enable(timeout) // Watchdog 使能
wdt_disable() // Watchdog 禁止
符号常量 值含意
WDTO_15MS Watchdog 定时器15 毫秒超时
WDTO_30MS Watchdog 定时器30 毫秒超时
WDTO_60MS Watchdog 定时器60 毫秒超时
WDTO_120MS Watchdog 定时器120 毫秒超时
WDTO_250MS Watchdog 定时器250 毫秒超时
WDTO_500MS Watchdog 定时器500 毫秒超时
WDTO_1S Watchdog 定时器1 秒超时
WDTO_2S Watchdog 定时器2 秒超时

C 代码中内联汇编程序
asm("in %0,%1 " : "=r " (value) : "I" (_SFR_IO_ADDR(PORTD)));
asm(code:output operand list : input operand list [: clobber list])
如上声明格式,四部分之间用符号 “:”隔开,Clobber 寄存器指示部分空时可以忽略,
其它部分可空但不可忽略。例如:
asm volatile(“cli” : : );
专用寄存器定义
符 号 寄 存 器
__SREG__ 状态寄存器 SREG(0X3F)
__SP_H__ 堆栈指针高字节(0X3E)
__SP_L__ 堆栈指针低字节 (0X3E)
__tmp_reg__ R0
__zero_reg__ R1,对C 代码来说其值永远为0

操作作数约束符
约束符号 适用于 范围
a 后半部分寄存器 R16~R23
b 指针 Y,Z
d 后半部分寄存器 R16~R31
e 指针 X,Y,Z
G 浮点常数 0.0
I 6 位正常数 0~63
J 6 位正常数 -63~0
K 常整数 2
L 常整数 0
l 前半部分寄存器 R0~R15
M 8 位正常数 0~255
N 常整数 1
O 常整数 8,16,24
P 常整数 1
q 堆栈指针寄存器 SPH:SPL
r 全部寄存器 R0~R31
t 暂存寄存器 R0
w 寄存器对 R24,R26,R28,R30
x 指针X
y 指针Y
z 指针Z
修饰符 意义
= 只 写
+ 读 写(内联汇编不支持)
约束符前可加的
修饰符
& 寄存器只用做输出

嵌入语句  编译结果
asm volatile(“cli;
ld r24,%a0;
inc r24;
st %a0,r24;
sei”
:
: “z”(ptr)
: “r24”
);

CLI
LD R24,Z
INC R24
ST Z,R24

C 编译器使用寄存器约定
(1)r0 和r1 :在C 程序中这两个寄存器用于固定目的,从不分配局部变量。
r0 是暂存寄存器,在汇编程序中可以自由的使用,若在汇编程序中使用了r0 并且要调
用C 函数则必需在调用C 函数前要保存它。若在中断函数中使用此寄存器要在使用前保存,
和退出时恢复,C 中断函数会自动保存的恢复r0。
r1 是零寄存器,C 编译器总认为其内容为零。如果汇编程序要使用这个寄存器,则在汇
编代码返回之前要清零它。中断函数要使用r1 则必需在退出时将其清零,C 中断函数会自
动保存的恢复r1。
(2)r2-r17、r28-r29:
局部变量分配寄存器,汇编程序若改变了这些寄存器内容,则必需恢复其内容。
(3)r18-r27、r30-r31
局部变量分配寄存器,汇编程序可自由的使用这此寄存器,无需恢复,但若在汇编程序
中使用了这些寄存并要调用C 函数,则需在调用前保护所用的寄存器。
SEI

flash区常量的初始化:
prog_char c='A';
prog_int a=1234;
prog_char str[]="string";
PGM_P pstr;
pstr=PSTR("static strings");//字符串"static strings"在flash区,宏PSTR(获得静态字符串指针)只能在函数中使用。
flash区常量的读取:
读字符:pgm_read_byte(address_short)
读字:pgm_read_word(address_short)
读n个字符/字节:void *memcpy_P(void *, PGM_VOID_P, size_t) //void * 指目的指针(在SRAM)
读字符串:char *strcpy_P(char *, PGM_P)
其他内容参阅pgmspace.h和avr-libc用户手册
2.访问或定义flash区常量应注意的问题
flash区常量是不可见的,不能用常规 的方法来读取/定义,比如:
//拼音索引表结构定义
struct t9PY_index
{
    PGM_P    t9PY_T9;
    PGM_P    PY;
    PGM_P    PY_mb;
};
const prog_char PY_mb_space []PROGMEM={""};
const prog_char PY_mb_a     []PROGMEM={"@啊阿"};
...
}
//"拼音输入法查询码表,T9数字字母索引表(index)"
const struct t9PY_index  t9PY_index2[]PROGMEM =
{
  {"","",PY_mb_space},
  {"2","a",PY_mb_a},
  ..
}
结构定义中的所有域都定义成PGM_P,按理拼音输入法查询码表t9PY_index2所有数据都应放在flash区,但事实并不这样,“”、“2”、“a"
却放在.data段(SRAM),不管在字符串常量前加强制类型转换,这是因为GCC把全局或静态常量强制放在.data段(SRAM),解决的方法是
字符串常量换成常量标识符:
const prog_char digits_2[]="2";
..
const prog_char alpha_a[]="a";
..
const struct t9PY_index  t9PY_index2[]PROGMEM =
{
{PY_mb_space,PY_mb_space,PY_mb_space},
{digits_2,alpha_a,PY_mb_a},
..
}
PGM_VOID_P p_PY_CurrenIndex;//指向拼音输入法查询码表的指针
指向flash 结构指针或结构类型不能用指向符或域引用符获取结构的域成员,如(struct t9PY_index) p_PY_CurrenIndex->t9PY_T9。
正确方法:
  struct t9PY_index PY_TempIndex;
  char  temp_t9PY_T9[8],*str;
  memcpy_P(&PY_TempIndex,p_PY_CurrenIndex,sizeof(struct t9PY_index));
  strcpy_P(temp_t9PY_T9,PY_TempIndex.t9PY_T9);
  str=strstr(temp_t9PY_T9,p_PadInput); 
*/
/*IAR中生成HEX
LINK/Extro Option加上: 

-Ointel-standard,(CODE)=.hex  
-Oraw-binary,(CODE)=.bin 
-Ointel-standard,(XDATA)=.eep.hex  
-Oraw-binary,(XDATA)=.eep.bin
*/
#endif
AVR所有头文件 包含所有的AVR头文件,如: #include #include #include #include 立即下载

相关推荐

AVR-atmega32的头文件

AVR-atmega32的头文件

AVR 看门狗

/* * ATmega16_wdto.c * * Created: 2022/4/29 16:27:00 * Author : admin */ #ifndef F_CPU #define F_CPU 8000000UL #endif #include <avr/io.h> #include <avr/wdt.h> #include <GPIO_IO.h> #include <util/delay.h> int main(void)//GCC.

qq_24426625的博客 536

AVR-C库文件

AVR-C库文件

AVR无功能秒表

 #include iom8v.h>#include macros.h>/**//*********************** PC0~3 -------   G1~4 ** PB0~7 -------    h~a ***********************/#define LED_BITE_SELECT PORTC    //当前选择的显示的7位数码管#define LED_BI

loongee的专栏 1188

arduino轻量级且高效的AVR固件库

Arduino-Lite是由RoboPeak开发并使用的轻量级且高效率的AVR固件库,他基于Arduino项目的固件库改良而来,我们保留了Arduino固件库的简单易用的风格,同时有效的缩小了固件的代码尺寸,相比Arduino,Arduino-Lite拥有诸多优点。并且,他是相当易于使用的。使用Arduino-Lite的固件往往比使用Arduino固件库小了50%以上.

AVR开发库代码

AVR开发库,开发AVR单片机的利器,内容包括各种外设的代码操作,轻松搞定硬件驱动,快速提高开发效率,AVR软件工程师的良品。

AVR8位定义闪烁灯设计

原理图 程序 #include <iom8v.h> /********************************************************************** 函数数据类型说明 / #define uchar unsigned char #define uint unsigned int ​ //定义BIT 0-7 置1 #define BIT0_POS (1<<0) #define BIT1_POS (1<<1) #define B

m0_46202433的博客 222

love109.github.io:个人爱情记录网站,未经允许禁止直接搬运整站!

love109.github.io 个人爱情记录网站: 个人学习记录网站: 优快云: 博客园: 知乎: 网站使用 和 搭建而成 搭建教程: Hexo 博客搭建专栏(从搭建到美化一条龙): Hexo 博客交流群(924812033): 期待认识更多的爱情博主,欢迎前来留言交换友链! 愿天下有情人终成眷属!:red_heart::red_heart::red_heart: @@@@ @@@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@

avr单片机c语言程序设计,avr单片机c语言编程风格介绍

描述摘要:作为一个初学者如何具有良好的程序设计风格呢?下面小编将以avr单片机介绍它的c语言编程风格。C语言编程风格介绍1.变量定义在定义变量时,前缀使用变量的类型,之后使用表现变量用途的英文单词或单词缩写,且每个单词或缩写的首字母大写,各种前缀缩写如下:无符号变量使用 u8,u16,u32;例:unsigned char u8Temp;有符号变量使用 s8,s16,s32;例:char s8Te...

weixin_35900054的博客 771

绝对旋转编码器学习笔记(基本原理,与PC通信等,不定期更新中)

前言 最近开始学习编码器相关内容,目的在于搞清楚编码器的原理,与上位机的联系等问题。笔记资料来源为网络,整理的同时也会有一些总结和感悟。由于研究方向需求,主要研究数字旋转编码器。 1.编码器的定义 编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。——摘自《百度百科》 通常来说,编码器可以将角度位移、直线位移、转速等物理量转换为电信号。这里的电信号根据不同原理的编码器输出脉冲、二进制数码等不同的类型,下面会提到。 2.编码器的分类 编.

黑化咸鱼的博客 1万+

PSOC Creator 入门教程超详细

最近工作原因需要使用到赛普拉斯的一款芯片,奈何以前没有用过,所以趁这次也学习了一些简单的用法,总结一下,希望能帮到有需要朋友,因为网上关于这方面的文章少的可怜,详细点的更是少之又少!废话少说,正文开始.

qm_mq的博客 5747

AVR单片机的端口位操作方法解析:位域bit field(和STM32位带bit-band不同,位带是利用位域的功能做成的)方式和移位宏方式,文中有位域和移位宏定义的例程反汇编,便于理解他们的实现机制

AVR单片机的端口位操作方法解析 来源:未知•作者:工程师周亮•2018年11月22日 16:07•3708次阅读 正在上传…重新上传取消​0 一、常规方法 AVR单片机的各类教材或编程应用参考资料,对介绍的端口位操作方法不外乎宏定义及整体和某个常量相或、相与来实现某一单个位状态的改变。如: PORT&=-(1《1);等价于:PORTB&=oxfd;作用是PB1清零而其余位不变。与之类似的还有: PORTBl=(1《4);PB4置位,其余位不变。 PORTB=(k《4);PB4翻转...

二进制模----细微行动改变影响世界 2227

从零到一:Halcon手眼标定的实战避坑指南

本文详细解析了Halcon手眼标定的完整流程,重点介绍了Eye-in-Hand和Eye-to-Hand两种模式的实操技巧与常见陷阱。通过九点法、N点法等实战案例,提供硬件配置检查、数据采集策略及误差修正方案,帮助开发者提升机械臂与视觉系统的协同精度,适用于工业自动化领域的精准定位与抓取任务。

neovim7hacker的博客 235

简单的avr c语言程序,avr单片机c语言编程风格介绍 - 全文

摘要:作为一个初学者如何具有良好的程序设计风格呢?下面小编将以avr单片机介绍它的c语言编程风格。C语言编程风格介绍1.变量定义在定义变量时,前缀使用变量的类型,之后使用表现变量用途的英文单词或单词缩写,且每个单词或缩写的首字母大写,各种前缀缩写如下:无符号变量使用 u8,u16,u32;例:unsigned char u8Temp;有符号变量使用 s8,s16,s32;例:char s8Temp...

weixin_36237278的博客 949

Apache Flink集成HDFS报错Failed to create checkpoint storage at checkpoint coordinator side.

在网上查询相关资料后,在flink的lib目录添加flink-shaded-hadoop-3-3.1.1.7.0.3.0-79-7.0.jar、commons-cli-1.5.0.jar两个包,但报错依旧存在,添加了export HADOOP_CLASSPATH=后面发现是hadoop与flink的兼容性问题,hadoop原先使用的是3.3.4,与多个版本的flink集成都会出现报错,最后将Hadoop的版本改成3.1.3,使用flink run运行jar包就没有这个错误了,在hdfs上成功保存了检查点。

zywenmag的博客 623

OpenWebUI外部模型配置异常排查与修复指南

本文详细解析了OpenWebUI外部模型配置异常的常见问题及解决方案,包括隐藏字符、数据库锁死等典型现象。通过错误日志分析和数据库修复实战指南,帮助开发者快速定位并解决配置问题,确保OpenWebUI与第三方大模型的稳定连接。

weixin_29205061的博客 314

linux驱动调试方法

驱动程序开发的一个重大难点就是不易调试。 本文目的就是介绍驱动开发中常用的几种直接和间接的调试手段: printk        查看OOP消息        strace        内核内置的hacking选项        ioctl方法        /proc 文件系统        kgdb 一、利用printk 这是驱动开发中最朴实无华,同时也是最常

wgembed的专栏 1924

SDMA 如何实现设备对主机内存的访问

摘要:SDMA(System Direct Memory Access)是PCIe设备直接访问主机内存的核心机制,使外设无需CPU干预即可高效读写系统RAM。其实现原理包括:设备作为主控发起DMA请求,通过PCIe Memory TLP访问主机物理地址;完整通路涉及驱动分配DMA安全内存、设备配置、地址转换(IOMMU)和中断通知等步骤;关键技术涵盖地址类型(HPA/IOVA)、TLP格式、缓存一致性和安全防护机制。SDMA广泛应用于GPU、网卡、NVMe等高性能场景,是现代异构计算的基础技术,需软硬件协同

MHD0815的博客 240

嵌入式学习笔记(17)——AVR单片机之头文件简介和使用

1.  ICCAVR的头文件形式为:     #include  ——芯片使用的不是mega类;或#include  ——使用的芯片为mega类。其中“*”用相应的芯片型号代替,如芯片ATmega8,则头文件为#include 2.  在AVR单片机的使用中有一个重要的头文件,macros.h,该头文件定义了一些常用的宏,如BIT(X),以及看门狗复位,开/关全局中断等等。 3.  AVR单

3670

14 ABSOLUTE评估肿瘤纯度

14 ABSOLUTE评估肿瘤纯度 Absolute介绍 ABSOLUTE可以直接从体细胞突变和拷贝数变异的结果中推断肿瘤纯度和倍性的计算方法。 通常来说,我们取肿瘤组织进行测序,往往是一个混合样品,既包括肿瘤细胞也包括正常细胞,因此需要进行肿瘤纯度 purity 的评估。当从混合样品中提取 DNA 进行测序后,得到的也是一个混合样品的结果。肿瘤不一定是单纯的二倍体了,其本身异质性高,存在部分突变部分不突变的情况,直接分析拷贝数变异,得到的结果并不准确,评估肿瘤倍性 ploidy 也更加必要。而 ABSO

qq_23435961的博客 4215

C++ Qt6 QtQuick/QML入门进阶与项目实战视频教程

C++ Qt这些年在PC客户端、嵌入式、汽车座舱仪表等领域应用很广泛,例如剪映专业版、微信4.0、亿图脑图、Steam、美图秀秀、腾讯会议、钉钉(部分模块)等都是使用C++ QWidget/QML开发。特别是QML这种声明式UI开发更加快捷,QML的界面开发效率相对于QWidget更快速,界面效果更好,QtQuick/QML在Qt6版本也逐渐完善了,使用QML进行客户端开发是个不错的选择。

琅嬛福地 4490

Arduino - 看门狗定时器(WDT:Watch Dog Timer)

dog

u014421313的博客 2803

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java的IO_18打印流(了解)

PrintStream 打印给控制台 打印到文件 输出到文件——重定向输出端 重定向回控制台 package com.io.cx3; import java.io.BufferedOutputStream; import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.FileOutpu...

Re_view的博客 587

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Arduino 使用看门狗

简介 本人使用的Arduino uno r3,avr单片机自带看门狗电路 下文引自单片机文档 ATmega48/88/168/328 has an Enhanced Watchdog Timer (WDT). The WDT is a timer counting cycles of a separate on-chip 128 kHz oscillator. The WDT gives

chn89的专栏 8121

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Arduino代码机制-avr/pgmspace.h

与GNU-GCC不同的是,AVR-GCC含有pgmspace.h这个文件。单片机采用哈弗结构,将程序存储器和数据存储器分开,而数据存储器RAM通常比较小,而程序存储器Flash空间比较大,因此就需要将占用空间较大的不需要改变的数据放在Flash中。比如需要单片机支持LCD显示文字,就需要一个庞大的字体库,可达到几kb,这样打的数据量放在RAM中是不合适的,只能放在Flash中。pgmspace.h就

qq_24027059的博客 8827
上一篇: 编程 程序读取数据与SQL编写手记
下一篇: C#时间/日期格式大全
ty_soft
博客等级 码龄15年 31粉丝 60原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值