原创--IAR for AVR入门学习笔记
AVR学习笔记
AVR学习笔记前言:学习一块单片机,我们要几项准备工作:1.开发软件(熟悉开发软件操作流程,基本上开发软件都差不多的,学会了一款,再学其它的就会很顺手了(新建工程、新建设计文件、把源文件加到工程里面、最后设置一些参数)2.编程语言(这个就不用说了,先学语法规则,能够熟练掌握到自己写的代码没有语法错误,然后再逐步把自己的想法驾驭到编程语言上)3.硬件(硬件包括的范围很广,不仅包括你所要学的单片机还有单片机的外围电路所用到的器件),最好要学一款仿真软件。
我们始终要记住学单片机绝对不可以纸上谈兵,一定要实践,就是把自己所写的代码下载到板上,看看实际效果。
开发板可以买,也可以自己做!我喜欢自己做。
实验一:点亮发光二极管1.avr单片机的i/o端口1)学习单片机的主要任务就是了解、掌握单片机i/o端口的功能,以及如何正确设计这些端口与外围电路的连接,从而能够组成一个嵌入式系统,并编程、管理和运用他们完成各种各样的任务。
2)atmega16有4个8位的双向i/o端口pa、pb、pc、pd,他们对外对应32个i/o引脚,每一位都可以独立地用于逻辑信号的输入和输出。
在5v工作电压下,输出高点平时,每个引脚可输出达20ma的驱动电流;而输出低电平时,每个引脚可吸收最大为40ma的电流,可以直接驱动发光二极管(一般的发光二极管的驱动电流为10ma)和小型继电器等小功率器件。
avr大部分的i/o端口都具备双重功能(有的还有第三功能)。
其中第一功能是作为数字通用i/o接口使用,而复用的功能可分别与片内的各种不同功能的外围接口电路组合成一些可以完成特殊功能的i/o口,如定时器、计数器、串行接口、模拟比较器、捕捉器、usart、spi等。
3)avr单片机的每组i/o口都搭载存有三个8为寄存器,分别就是:方向掌控寄存器ddrx、数据寄存器portx、输出插槽寄存器pinx(x=a/b/c/d).i/o口的工作方式和整体表现特征由这三个i/o寄存器掌控。
IAR for AVR 学习笔记
IAR for AVR 学习笔记IAR FOR AVR 学习笔记在AVR编程一直是C,从ICC->GCC->IAR IAR是一个唯一自己选择的.ICC由于入门容易所以选择了开始,GCC因为不要钱,所以后来就用了它.随着对GCC的不断认识,缺点不断显露,开始对IAR产生了兴趣.IAR在51,AVR,ARM的C上都是非常优秀的,它针对不同的单片机都有不同的C版本.唯一一点遗憾的是IAR的价格是个人和小公司难以承受的.当然网上有很多破解,现在的最新版4.20A也有了破解.IAR FOR AVR相关信息:破解方法:ID号注意一定要大写,不然注册将会失败 ,另外并不是每个号都是能用的了,要多试几次.如果注册成功后,编译就会通过.不然就报\没有可的证书\错误. 注意点:如何输出HEX文件?在配置文件后面加入以下代码,便可输出HEX文件,A90文件与HEX文件一样,SLISP都能识别.// Output File-Ointel-extended,(XDATA)=.eep //产生eeprom文件 -Ointel-extended,(CODE)=.A90 //产生烧写文件 -Ointel-extended,(CODE)=.hex //产生烧写文件中断向量的使用IAR中定义中断函数的格式是 ///////////////////////////////// #pragma vector=中断向量__interrupt void 中断服务程序(void) {//中断处理程序 }/////////////////////////////////////中断的初始化要另外加入代码,可在主程序内加入。
如下是各个中断函数的定义。
//中断定义#include#pragma vector=INT0_vect__interrupt void INT0_Server(void) { }#pragma vector=INT1_vect__interrupt void INT1_Server(void) { }#pragma vector=TIMER2_COMP_vect__interrupt void TIMER2_COMP_Server(void) { } #pragma vector=TIMER2_OVF_vect__interrupt void TIMER2_OVF_Server(void) { } #pragma vector=TIMER1_CAPT_vect__interrupt void TIMER1_CAPT_Server(void) { } #pragma vector=TIMER1_COMPA_vect__interrupt void TIMER1_COMPA_Server(void) { } #pragma vector=TIMER1_COMPB_vect__interrupt void TIMER1_COMPB_Server(void) { } #pragma vector=TIMER1_OVF_vect__interrupt void TIMER1_OVF_Server(void) { } #pragma vector=TIMER0_OVF_vect__interrupt void TIMER0_OVF_Server(void) { } #pragma vector=SPI_STC_vect__interrupt void SPI_STC_Server(void) { }#pragma vector=USART_RXC_vect__interrupt void USART_RXC_Server(void) { } #pragma vector=USART_UDRE_vect__interrupt void USART_UDRE_Server(void) { } #pragma vector=USART_TXC_vect__interrupt void USART_TXC_Server(void) { } #pragma vector=ADC_vect__interrupt void ADC_Server(void) { }#pragma vector=EE_RDY_vect__interrupt void EE_RDY_Server(void) { }#pragma vector=ANA_COMP_vect__interrupt void ANA_COMP_Server(void) { }#pragma vector=TWI_vect__interrupt void TWI_Server(void) { }#pragma vector=INT2_vect__interrupt void INT2_Server(void) { }#pragma vector=TIMER0_COMP_vect__interrupt void TIMER0_COMP_Server(void) { }#pragma vector=SPM_RDY_vect__interrupt void SPM_RDY_Server(void) { }如何把常数字符串定义在flash 空间?法一:unsigned char __flash temptab[] = {1,2,3,4,5}; 法二:__flashunsigned char temptab[] = {1,2,3,4,5}; 法三:#pragma type_attribute=__flash unsigned char temptab[]={1,2,3,4,5};法四:const unsigned char temptab[]={1,2,3,4,5};注:第三种方式用#pragma说明后,下面的定义的变量将都在FLASH空间了,用于定义一批FLASH变量,但实际上一般只能作为常量使用了.感谢您的阅读,祝您生活愉快。
AVR学习笔记
一、AVR单片机位操作
(1)置位。
要将R的第3位置1,其他位不变,可以这样做:R |= (1<<3),其中“1<<3”
的结果是“0b00001000”,R |= (1<<3)也就是R=R|0b00001000,任何数和0相或不变,任何数和1相或为1,这样达到对R的第3位置1,但不影响其他位的目的。
(2)清位。
要将R的第2位清0,其他位不变,可以这样做:R &= -(1<<2),其中“-(1<<2)”
的结果是“0b11111011”,R&=-(1<<2)也就是R=R&0b11111011,任何数和1相与不变,任何数和0相与为0,这样达到对R的第2位清0,但不影响其他位的目的。
(3)获得某一位的状态。
(R>>4) & 1,是获得R第4位的状态,“R>>4”是将R右移4位,将R的第4位移至第0位,即最后1位,再和1相与,也就是和0b00000001相与,保留R最后1位的值,以此得到第4位的状态值。
二、AVR单片机中断向量表
三、AVR单片机引脚图。
IAR EWARM学习笔记
IAR EWARM5.20学习笔记学习笔记((基于LPC2132)---LPC2132)---从零起步从零起步----在在proteus 中仿真运行(幻磁帝国原创幻磁帝国原创))一:创建一个最简洁的工程模板目的:IARM EWARM5.20编程入门,学会怎么用EWARM5.20版来创建自己的工程。
1.1新建一个空的工程文件夹,这里起名为MyEWARMstartup1.2新建EWARM 工程创建一个空的EWARM 工程:点击OK ,选择刚才新建的文件夹,工程取名为MyEWARMsartatup ,保存。
这样一个空的新的工程文件就建好了。
1.3拷贝IAR EWARM安装目录下例程中的启动文件本例用的是LPC2132,顾找到软件安装目录下的LPC213x的例程进去找到config文件夹,这个文件夹中装的就是LPC2132的启动文件可以看到这个文件加下面有四个文件Flash.icf Flash.mac RAM.icf和ram.mac。
暂且不用理会这几个文件的具体内容,只要知道它是启动文件就可以了。
拷贝config 文件夹,复制到先前建立的工程文件夹MyEWARMstartup 中。
到此,准备工作基本完成。
1.4工程设置右键点击workspace 中的工程名,选择Options ,对工程进行相关设置。
再Generral options 中选择具体的ARM 型号,这里选择LPC2132第二个要设置的选项是Output Converter ,即输出文件的设置,这里设置如下,生成hex 文件,文件的目录可以直接加到hex 文件名前面的。
如:D:\MyEWARMsartatup.hex接下来就是至关重要的启动代码的链接设置了,打开Linker选项如下,congfig选项卡中默认是没有勾选Override default的。
这时候就要用到先前我们拷贝的config文件夹中的东东了,也就是启动文件了。
勾选Override default,点击后面的选择链接,将路径选择到:C:\Documents and Settings\Administrator\桌面\MyEWARMstartup\config\RAM.icf如果想在Flash中运行就选择FLASH.icf 最后一个设置:本人是在proteus中仿真调试的,所以这里选择的是simulator方式,启动后运行到main函数。
AVR自学笔记
RXB8(bit1):接收数据位 8 TXB8(bit0):发送数据位 8 *UCSRC: URSEL(bit7):读 UCSRC 时为 1,写 UCSRC 时为 1(?)(编译器自动处理) UMSEL(bit6):0,异步。1,同步 UPM1~UPM0(bit5、4):奇偶校验模式
USBS(bit3):停止位数选择;0 时,1bit 停止位,1 时,2bit 停止位 UCSZ1~UCSZ0(bit2、1):字符长度设置
一、基础知识 1.开发工具: 编辑与编译软件:WinAVR 仿真软件:AVR Studio 下载软件:AVR_fighter、MuCodeISP 等 在需要在中断函数中被修改的全局变量需要用 volatile 关键字声明 2.第一个简单的 AVR 程序 AVR 引脚排列:
ATMega8 引脚排列
ATMega16 引脚排列
*PWM 输出频率计算公式(快速 PWM 模式)
*PWM 输出频率计算公式(相位修正 PWM 模式)
4. 异步串行口 USART(同步或异步): ①相关寄存器:UDR(数据寄存器)、UCSRA(控制与状态寄存器 A)、UCSRB(控制与状态寄存器 B)、UCSRC (控制与状态寄存器 C)、UBRRL(波特率寄存器 L)、UBRRH(波特率寄存器 H) ②三个中断源:发送结束中断、发送数据寄存器空中断、接收完成中断(常用) ③寄存器介绍 *UDR: 8 位数据寄存器,接收和发送为同一地址的不同寄存器 *UCSRA:
②注意 OCR0(输出比较寄存器)用于输出比较,产生事件匹配中断,这里没有列出 *TCCR0:
FOC0(bit7):强制输出比较,仅在 WGM00 指明非 PWM 模式时才有效 WGM00、WGM01(bit6、3):波形产生模式
AVR学习笔记
PC = progammer counter //程序计数器ACC = accumulate //累加器PSW = progammer status word //程序状态字SP = stack point //堆栈指针DPTR = data point register //数据指针寄存器IP = interrupt priority //中断优先级IE = interrupt enable // 中断使能TMOD = timer mode //定时器方式 (定时器/计数器控制寄存器)ALE = alter (变更,可能是)PSEN = progammer saving enable //程序存储器使能(选择外部程序存储器的意思) EA = enable all(允许所有中断)完整应该是 enable all interruptPROG = progamme (程序)SFR = special funtion register //特殊功能寄存器TCON = timer control //定时器控制PCON = power control //电源控制MSB = most significant bit//最高有效位LSB = last significant bit//最低有效位CY = carry //进位(标志)AC = assistant carry //辅助进位OV = overflow //溢出ORG = originally //起始来源DB = define byte //字节定义EQU = equal //等于DW = define word //字定义E = enable //使能OE = output enable //输出使能RD = read //读WR = write //写中断部分:INT0 = interrupt 0 //中断0INT1 = interrupt 1//中断1T0 = timer 0 //定时器0T1 = timer 1 //定时器1TF1 = timer1 flag //定时器1 标志 (其实是定时器1中断标志位)IE1 = interrupt exterior //(外部中断请求,可能是)IT1 = interrupt touch //(外部中断触发方式,可能是)ES = enable serial //串行使能ET = enable timer //定时器使能EX = enable exterior //外部使能(中断)PX = priority exterior //外部中断优先级PT = priority timer //定时器优先级PS = priority serial //串口优先级第一部分二极管发光的条件是正负极相差达1V以上。
AVR随堂笔记
因为51单片机的IO端口大部分都是准双向口在复位时全部输出高电平对端口的输入和输出操作也是直接通过IO端口的地址进行的AVR的IO端口是标准的双向口在复位时所有端口处于高阻态 AVR的每个端口对应三个寄存器即DDRx(方向寄存器) PORTx(数据寄存器) PINx(读入 / 输入寄存器)在使用AVR单片机之前一定要根据引脚功能对相应的端口初始化否则端口很可能不能正常工作*DDRx寄存器7 6 5 4 3 2 1 0DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0 DDRBR/W R/W R/W R/W R/W R/W R/W R/W*PORTx寄存器7 6 5 4 3 2 1 0PORTB7 PORTB6 PORTB5 PORTB4 PORTB3 PORTB2 PORTB1 PORTB0 PORTBR/W R/W R/W R/W R/W R/W R/W R/W*PINx寄存器7 6 5 4 3 2 1 0PINB7 PINB6 PINB5 PINB4 PINB3 PINB2 PINB1 PINB0 PINBR R R R R R R R作为通用数字IO口使用时每个引脚都具有三个寄存器位: DDRxn PORTxn PINxnDDRxn PORTxn PINxn IO 上拉电阻说明0 0 - 输入无高阻态0 1 - 输入有带上拉的输入1 0 - 输出无输出低电平1 1 - 输出无输出高电平AVR单片机中对IO进行操作之前需要进行相应的初始化设置其设置步骤如下:(1)通过方向寄存器DDRx设置相应的端口为输入或者输出(2)如果设置为输出的话把需要输出的数据送往数据寄存器PORTx(3)如果设置为输入的话从输入寄存器PINx中读取外部的输入值同时可以通过设置PORTx来设置相应的引脚是否需要上拉电阻ICCAVR头文件的形式为: #include<io*v.h> 或 #include<iom*v.h> 若芯片使用的不是mega类则使用#include<io*v.h> 若是mega类则为#include<iom*v.h>在AVR单片机的使用当中有一个重要的头文件 macros.h 该头文件定义了一些常用的宏如BIT(x) 以及看门狗复位开关全局中断等等使用方法:#include<macros.h>如果在程序中要使用BIT(x) 则必须包含该头文件AVR单片机中同样可以对单个IO口进行操作其具体方法如下:(1)PORTA |= (1<<3)(2) PORTA |= BIT(3)(3) PORTA |= BIT(PORTA3)以上三种方法都是让它们第四位置1[0 1 2 3]按位或用于打开某一位或某几位即置位例如: PORTA |= 0X80; // 将端口A的第七位置“ 1 ”不管该位之前是什么状态都会将其置 1按位取反用于关闭某一位或某几位即清位例如: PORTA &= ~0X80; // 将端口A的第七位清零0X80(10000000)按位取反后是0x7f(01111111)不管该位之前是什么状态都会将其清零按位异或用于翻转某一位或某几位例如: PORTA ^= 0X80; // 将端口A的第七位翻转如果原来是“ 1 ”翻转之后是“ 0 ”如果原来是“ 0 ”翻转之后是“ 1 ”按位与用于检查某一位或某几位是否为 1例如: if(PINA & 0X80); // 检查PA.7是否为 1一般用于条件或判断语句中用于检查某一位是否为 1AVR单片机熔丝位简介熔丝位状态为 1 表示未编程熔丝位状态为 0 表示编程因为在AVR的器件手册中是使用已编程(Programmed)和未编程(Unprogrammed)定义熔丝位的AVR单片机的熔丝位是可以多次编程的AVR单片机芯片加密锁定之后(LB2 / LB1 = 1 / 0 0 / 0)不能通过任何方式读取芯片内部的Flash 和EEPROM的数据的下载编程的正确操作步骤是:下载运行代码和数据配置相关的熔丝位最后配置芯片的加密位芯片加密熔丝位简介加密锁定位保护类型(芯片加密)加密锁定方式 LB2 LB11(出厂设置) 1 1 无任何编程加密锁定保护2 1 0 禁止串 / 并行方式的再编程3 0 0 禁止串 / 并行方式的再编程和校验功能熔丝位简介熔丝位名称 1 0 出厂设置WDTON 看门狗由程序控制看门狗始终工作 1程序只能调节溢出时间SPIEN 禁止ISP串行编程允许ISP串行编程 0JTAGEN 禁止JTAG 允许JTAG 0EESAVE 芯片擦除时同时擦除芯片擦除时时不擦除 1EEPROM数据 EEPROM数据BODLEVEL 低电压检测门限电平低电压检测门限电平 1为2.7v 为4.0vOCDEN 禁止JTAG口的在线调允许JTAG口的在线调 1试功能试功能Bootloader熔丝位简介熔丝位名称 1 0 出厂设置 BootRst 芯片上电后从地址芯片上电后从地址 10x0000开始执行 Boot开始执行Bootloader区域大小设置BooTSZ1 BooTSZ1 BooT区大小起始地址出厂设置0 0 1024 0x1C000 1 512 0x1E001 0 256 0x1F00 四种都是 001 1 128 0x1F80系统时钟源选择熔丝位系统时钟源 CKSEL[3:0]外接石英 / 陶瓷晶体 1111 ~ 1010外接低频晶体 1001(32.768 KHz)外接RC振荡器 1000 - 0101使用可校准的内部RC振荡器 0100 - 0001 (出厂设置0001 1MHz)外部时钟 0使用外部晶体时的工作模式配置熔丝位工作频率范围MHz 适用晶体C1 C2容量 / pFCKPOT CKSEL[3:1]1 101 0.4-0.9(MHz) 注释(pF) 陶瓷晶体1 110 0.9-3.0 12-221 111 3.0-8.0 12-220 101-111 >=1.0 12-22 都是石英晶体当CKPOT = 0时振荡器的输出振幅较大适用于干扰大的场合反之振荡器的输出较小可以降低功耗对外电磁辐射也较小使用外部晶振时唤醒脉冲和延时时间的选择熔丝位掉电和省电复位延时启动时间适合应用条件CKSEL0 SUT[1:0] 模式唤醒 (Vcc=5v)0 00 258CK 4.1ms 陶瓷振荡器快速上升电源0 01 258CK 65ms 陶瓷振荡器慢速上升电源0 10 1K CK ---- 陶瓷振荡器BOD方式0 11 1K CK 4.1ms 陶瓷振荡器快速上升电源1 00 1K CK 65ms 陶瓷振荡器慢速上升电源1 01 16K CK ---- 陶瓷振荡器BOD方式1 10 16K CK 4.1ms 陶瓷振荡器快速上升电源1 11 16K CK 65ms 陶瓷振荡器慢速上升电源C51向ICCAVR快速过度头文件把REG52.H替换成相应的AVR头文件如iom16v.h对C52中的bit sbit的数据类型进行处理因为ICCAVR不支持bit和sbit数据类型可以用位运算和BIT来处理中断系统定时器与单片机结构密切相关的代码需要重新修改和延时定时相关的函数需要进行一些修改因为AVR的运算速度比51单片机要快的很多其余与CPU体系结构无关的代码可以直接使用AVR单片机中断的原理ATmega16单片机具有21个中断源每个中断源都有一个独立的中断向量作为中断服务程序的入口地址而且所有的中断源都有自己独立的使能位如果全局中断和相应的中断使能位都置位则在中断标志位时执行中断服务程序一个中断产生后全局中断使能位将被清零后续的中断被屏蔽用户可以在中断服务程序里面对置位从而开发中断在中断返回后全局中断位将重新位置ATmega16单片机中断向量表介绍向量号程序地址中断源中断定义1 S000 RESET 外部引脚电平引发的复位上电复位掉电检测复位看门狗复位以及JTAG AVR复位2 S002 INT0 外部中断请求03 S004 INT1 外部中断请求14 S006 TIMER2 COMP 定时器 / 计数器2比较匹配5 S008 TIMER2 OVF 定时器 / 计数器2溢出6 S00A TIMER1 CAPY 定时器 / 计数器1事件捕捉7 S00C TIMER1 COMPA 定时器 / 计数器1比较匹配A8 S00E TIMER1 COMPB 定时器 / 计数器1比较匹配B9 S010 TIMER1 OVF 定时器 / 计数器1溢出10 S012 TIMER0 OVF 定时器 / 计数器0溢出11 S014 SPI STC SPI串行传输结束12 S016 USART RXC USART Rx结束13 S018 USART UDRE USART数据寄存器空14 S01A UART TXC USART Tx结束15 S01C ADC ADC转换结束16 S01E EE_RDY EEPROM就绪17 S020 ANA_COMP 模拟比较器18 S022 TWI 两线串行接口 ( IIC )19 S024 INT2 外部中断请求220 S026 TIMER0 COMP 定时器 / 计时器比较匹配21 S028 SPM_RDY 保存程序存储器内容就绪AVR单片机外部中断ATmega16单片机具有3个外部中断分别是INT0 INT1 INT2这三个外部中断都是由单片机的引脚触发的需注意的是如果允许外部中断的话即使是INT0 INT1 INT2这3个引脚都设置为输出方式外部中断也会触发INT0 INT1外部中断可以选择的触发方式有上升沿触发下降沿触发以及低电平触发INT2只有跳变沿触发没有电平触发使用外部中断涉及到的寄存器有 MCU控制寄存器MCUCR MCU控制欲状态寄存器MCUCSR 通用中断控制寄存器CICR 通用中断状态寄存器GIFRMCU控制寄存器MCUCRBit 7 6 5 4 3 2 1 0SM2 SE SM1 SM0 ISC11 ISC10 ISC01 ISC00Read/Write R/W R/W R/W R/W R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 0为[3:2] - ISC1[1:0]外部中断1触发方式选择ISC11 ISC10 说明0 0 INT1引脚为低电平时产生中断请求0 1 INT1引脚上的任意逻辑电平变化都会产生中断请求1 0 INT1引脚的下降沿产生中断请求1 1 INT1引脚的上升沿产生中断请求MCU控制与状态寄存器MCUCSRBit 7 6 5 4 3 2 1 0JTD ISC2 - JTRF WDRF BORF ECTRF PORFRead/Write R/W R/W R R/W R/W R/W R/W R/Wlnitial Vaiue 0 0 0 see Bit Descriotion位6 -- ISC2 外部中断2触发方式外部中断2由外部引脚INT2激发若ISC2清零则INT2的下降沿激活中断若ISC2置1 则INT2的上升沿激活中断通用中断控制寄存器GICRBit 7 6 5 4 3 2 1 0INT1 INT0 INT2 - - - IVSEL IVCERead/Write R/W R/W R/W R R R R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 0位7 -- INT1 时能外部中断1请求当INT1为1且状态寄存器SREG的标志置位时相应的外部引脚中断使能只要使能即使INT1引脚被配置为输出一旦引脚电平发生了相应的变化中断就将产生位6 -- INT0 时能外部中断0请求当INT0为1且状态寄存器SREG的标志置位时相应的外部引脚中断使能只要使能即使INT1引脚被配置为输出一旦引脚电平发生了相应的变化中断就将产生位5 -- INT2 时能外部中断2请求当INT2为1且状态寄存器SREG的标志置位时相应的外部引脚中断使能只要使能即使INT1引脚被配置为输出一旦引脚电平发生了相应的变化中断就将产生通用中断状态寄存器GIFRBit 7 6 5 4 3 2 1 0INTF1 INTF0 INTF2 - - - - -Read/Write R/W R/W R/W R R R R Rlnitial Vaiue 0 0 0 0 0 0 0 0位7 -- INTF1 外部中断1标志位 INT1引脚电平发生跳变时触发中断请求并置位相应的中断标志INTF1 如果SREG的位I以及相应的中断使能位INT1为1 MCU立即跳转到相应的中断向量位6 -- INTF0 外部中断0标志位 INT0引脚电平发生跳变时触发中断请求并置位相应的中断标志INTF0 如果SREG的位I以及相应的中断使能位INT0为1 MCU立即跳转到相应的中断向量位5 -- INTF2 外部中断2标志位 INT2引脚电平发生跳变时触发中断请求并置位相应的中断标志INTF2 如果SREG的位I以及相应的中断使能位INT2为1 MCU立即跳转到相应的中断向量状态寄存器SREGBit 7 6 5 4 3 2 1 0I T H S V N Z CRead/Write R/W R/W R/W R/W R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 0位7 -- I 全局中断使能位置位时使能全局中断单独的中断使能由其他独立的寄存器控制如果I被清零则不论单独中断标识位置位与否都不会产生中断任意一个中断产生之后 I都将被清零而执行RETI指令后I被置位以重新使能中断 I也可以通过SEI指令和CLI指令来置位和清零在使用任何中断之前都必须将全局中断使能位置位使能语句 SREG |= BIT(7);中断服务函数怎么写用ICCAVR编程在C中只要用 #pragma伪指令和中断向量说明中断服务程序入口地址即可语法格式#pragma interrupt_handle < 函数名 >: < 中断向量 >例如定义INT0中断服务程序#pragma interrupt_handle int0_isr: 2void int0_isr(void){// INT0中断服务函数}外部中断使用的步骤设置外部中断的触发模式 ( 寄存器MCUCR )使能外部中断(寄存器GICR )设置中断管脚(是否需要上拉电阻)打开全局中断(寄存器SREG )选择中断号写中断服务程序AVR单片机片内EEPROMAtmega16单片机内部具有512字节的EEPROM 它一个独立的数据空间拥有至少10万次写入 / 擦除寿命地址范围是0x0000 - 0x01ff数据读写一字节为单位通过专用的指令来实现对EEPROM的操作可也可以通过ISP JTAG 并行编程的方式实现EEPROM的写入和读出采用内部RC振荡器的1MHz作为访问的定时时钟其编程使用周期8448个周期时间大约8.5ms操作过程中尽量关闭中断保持时序不被打断EEPROM存储器相关的寄存器EEPROM地址寄存器EEARH EEARLBit 15 14 13 12 11 10 9 8- - - - - - - EEAR8 EEARHEEAR7 EEAR6 EEAR5 EEAR4 EEAR3 EEAR2 EEAR1 EEAR0 EEARL7 6 5 4 3 2 1 0Read/Write R R R R R R R R/WR/W R/W R/W R/W R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 xx x x x x x x xEEPROM地址寄存器EEAR用于指定某个EEPROM单元的地址 512字节EEPROM线性编址为0x0000 - 0x01ff 地址寄存器EEAR可读可写 EEAR寄存器的初值没有意义在访问EEPROM 之前必须为其指定正确的地址EEPROM存储器相关的寄存器EEPROM数据寄存器EEDRBit 7 6 5 4 3 2 1 0MSB LSBRead/Write R/W R/W R/W R/W R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 0EEPROM数据寄存器EEDR存放即将写入EEPROM或者从EEPROM读出的某个单元的数据写入或者读出的地址由EEPROM的地址寄存器EEAR给出 EEPROM按字节进行读写 EEPROM数据寄存器EEDR可读可写初始值为0x00EEPROM控制寄存器EECRBit 7 6 5 4 3 2 1 0- - - - EERIE EEMWE EEWE EERERead/Write R R R R R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 x 0EEPROM控制寄存器EECR用于控制单片机对EEPROM的操作位3 - EERIE EEPROM中断准备好使能位当EERIE位置1而且全局中断置位时如果EEWE为0 则单片机产生一个中断表示写操作完成EEPROM存储器相关的寄存器位2 - EEMWE EEPROM主写使能位当EEMWE为1时设置EEWE为1将把EEDR中的数据写入EEAR所选择的地址空间中如果EEMWE为0 则EEWE无效 EEMWE在被用户置1后的4个时钟周期后被硬件清零EEPROM存储器相关的寄存器位1 - EEWE EEPROM写使能位当EEPROM的地址和数据准备好之后用户必须设置EEWE为1 才能将数据写入EEPROM中设置EEWE为1之前 EEMWE必须置1 否则写入操作无效EEPROM数据写入操作如下等待EEWE为0把EEPROM的地址写入EEAR把EEPROM的数据写入EEDR置EEMWE为1在置EEMWE为1的4个时钟周期内向EEWE中写入1位0 - EERE EEPROM读使能位 EERE用于对EEPROM的数据读取当EEAR中设置了EEPROM的读取地址后置位EERE将执行读操作当EEPROM中的数据被读取到数据寄存器EEDR中后EERE被硬件清零用户可以通过查询此位来判断读操作是否完成AVR单片机片内ADC简介ATmega16单片机集成了一个10位的逐次逼近型A/D装换器 A/D装换器与一个8位通道多路复用器连接能对来自端口A的8路单端输入电压进行采样8路可选的单端输入通道7路差分输入通道ADC转换结果的读取可设置为左端对齐在最高精度下可达到15KSPS/S的采样速率可选择的内部2.56V的ADC参考电压源自由连接转换模式和单次装换模式ADC自动转换触发模式选择ADC转换完成中断ADC的供电和参考电压ADC功能单元独立的专用模拟电源引脚AVCC供电 AVCC和VCC的电压差别不能大于+_0.3VADC装换的参考电源可采用芯片内部的2.56V参考电源或采用AVCC 也可采用外部参考电源使用外部参考电源时外部参考电源有引脚AREF接入使用内部电压参考源时可以通过在AREF引脚外部并接一个电容提高ADC的抗干扰性能与ADC有关的寄存器ADC多路复用器选择寄存器ADMUX7 6 5 4 3 2 1 0REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0R/W R/W R/W R/W R/W R/W R/W R/W0 0 0 0 0 0 0 0位[7:6] - REFS[1:0]:ADC参考电压选择这两位选择ADC的参考电压如果在装换过程中改变了设置则只有等到当前装换结束之后新的设置才会起作用如果在AREF脚上施加了外部参考电压则内部参考电压不能被选择与ADC有关的寄存器ADC参考电压选择位REFS1 REFS0 参考电压选择0 0 AREF 内部基准源关闭0 1 AVCC AREF外接滤波电容1 0 保留1 1 2.56V内部基准电压源 AVREF引脚外接滤波电容位5 - ADLAR: ADC转换结果对齐位 ADLAR位影响ADC转换结果在ADC数据寄存器中的存放形式 ADLAR置位时转换结果位左对齐否则位右对齐位[4:0] - MUX[4:0]:模拟通道与增益选择位这几位选择连接到ADC模拟输入通道也可以对差分通道增益进行设置如果在转换过程中改变了设置则只有等到当前装换结束之后新的设置才会起作用具体的设置表可以查看数据手册与ADC有关的寄存器ADC控制盒状态寄存器ADCSRA7 6 5 4 3 2 1 0ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0R/W R/W R/W R/W R/W R/W R/W R/W0 0 0 0 0 0 0 0位7 - ADEN: ADC使能位 ADCEN置位即启动ADC 否则ADC功能关闭位6 - ADSC: ADC开始转换在单次转换模式下 ADSC置位将启动一次ADC转换在连续转换模式下 ADSC置位将启动首次转换位5 - ADATE: ADC自动触发使能 ADATE置位将启动ADC自动触发功能触发信号的上升沿启动ADC转换位4 - ADIF: ADC中断标志位 ADC转换结束且数据寄存器被更新后 ADIF置位如果ADIE 及AREG寄存器中的全局使能位I被置位则ADC转换结束中断服务程序将被执行同时ADIF 硬件清零也可以通过软件写“1”清零位3 - ADIE: ADC中断使能位若ADIE及SREG中的I置位则ADC转换结束中断将被使能位2[2:0] - ADPA[2:0]: ADC预分频选择位这3位决定ADC输入时钟与CPU时钟之间的分频系数 ADC分频系数选择如下表:ADPS2 ADPS2 ADPS2 分频系数0 0 0 20 0 1 20 1 0 40 1 1 81 0 0 161 0 1 321 1 0 641 1 1 128ADC数据存储器ADCL及ADCHADC转换结束后转换结果将储存在这两个寄存器中在读取ADCL之后 ADC数据存储器需要等到ADCH也被读出之后才会更新数据寄存器因此如果转换结果为左对齐而只需要8位精度那么仅需要读取ADCH就足够了否则必须ADCH然后再读ADCLADMUX寄存器中的ADLAR及MUXn会影响转换结果在数据寄存器中的存放形式ADC数据存储器ADCL及ADCH当ADLAR = 0;Bit 15 14 13 12 11 10 9 8- - - - - - ADC9 ADC8 ADCHADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0 ADCL7 6 5 4 3 2 1 0Read/Write R R R R R R R RR R R R R R R R lnitial Vaiue 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0当ADLAR = 1;Bit 15 14 13 12 11 10 9 8 ADCHADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADCLADC1 ADC0 - - - - - -7 6 5 4 3 2 1 0Read/Write R R R R R R R RR R R R R R R R lnitial Vaiue 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0特殊功能IO寄存器SFIORBit 7 6 5 4 3 2 1 0ADTS2 ADTS1 ADTS0 - ACME PUD PSR2 PSR10 SFIOR Read/Write R/W R/W R/W R R/W R/W R/W R/Wlnitial Vaiue 0 0 0 0 0 0 0 0位[7:5] - ADTS[2:0]: ADC自动触发源选择ADTS2 ADTS1 ADTS0 触发源0 0 0 连续转换模式0 0 1 模拟比较器0 1 0 外部中断请求00 1 1 定时器/计数器0比较匹配1 0 0 定时器/计数器0溢出1 0 1 定时器/计数器比较匹配B1 1 0 定时器/计数器1溢出1 1 1 定时器/计数器1捕捉事件ADC的使用步骤1.ADC输入端口初始化2.基准电压设置数据对齐方式通道选择(寄存器ADMUX)3.AD使能启动转换及中断设置(寄存器ADCSRA)4.触发源选择(寄存器SFIOR)5.选择中断号编写中断服务函数读取ADC转换结果(ADCH ADCL)注意点:从ADCH和ADCL中读到的数据时BCD码格式的ATmega16定时器ATmega16单片机有3个定时/计数器: T/C0 T/C1和T/C2 其中T/C0和T/C2是两个8位的定时/计数器而T/C1是16位的定时/计数器这里以T/C1为例讲解普通模式CTC模式快速PWM模式相位修正PWM模式相位频率修正PWM模式输入捕捉模式普通模式普通模式是最简单的工作模式和51单片机的定时计数器类似根据设定的时钟频率每过一个时钟计数寄存器数值加116位计数器TCNT1一直累加1 当计数到0xFFFF之后由于计数值溢出 TCNT1简单的返回到最小值0x0000重新开始计数普通模式用到的寄存器1.T/C1控制寄存器TCCRIBBit 7 6 5 4 3 2 1 0ICNC1 ICES1 - WGM13 WGM12 GS12 CS11 CS10 TCCR1B读/写 R/W R/W R R/W R/W R/W R/W R/W初始值 0 0 0 0 0 0 0 0位2: 0 - CS1[2:0]: T/C1时钟选择CS12 CS11 CS10 说明0 0 0 无时钟源(T/C停止)0 0 1 CLK i/o /1(无预分频)0 1 0 CLK i/o /8(来自预分频器)0 1 1 CLK i/o /64(来自预分频器)1 0 0 CLK i/o /256(来自预分频器)1 0 1 CLK i/o /1024(来自预分频器)1 1 0 外部T1引脚下降沿驱动1 1 1 外部T1引脚上降沿驱动2.计数存储器TCNT1H和TCNT1LBit 7 6 5 4 3 2 1 0TCNT1[15:8] TCNT1HTCNT1[7:0] TCNT1L3.T/C1中断屏蔽寄存器TIMSKBit 7 6 5 4 3 2 1 0OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE1 TIMSK读/写 R/W R/W R/W R/W R/W R/W R/W R/W初始值 0 0 0 0 0 0 0 0位2 - TOIE1: T/C1溢出中断使能位当该位被置1且状态寄存器中的I位被置1时 T/C1的溢出中断使能一旦TIFR的TOV1置位 CPU即开始执行T/C1溢出中断服务程序普通模式的使用方法1.根据需要选择时钟源(寄存器TCCRIB)2.根据定时时间和时钟源确定定时器的初值(寄存器TCNT1H和TCNT1L)3.设置中断使能位4.选择中断号编写中断服务程序注意在中断服务函数里面需要重新设置定时器初值10-1AVR 8 - 2 程序未写AVR 9 - 2。
AVR学习笔记
一、AVR的PC口正常使用:1、在程序中连续写入两条语句:MCUCSR |= BIT(7);( 或者是MCUCSR =(1<<7); )。
2、将熔丝位OCDEN 和JTAGEN 设置为0,关闭仿真功能。
编译时出现错误警告:!E <library>(72): area 'data' not large enough解决方法:project----compiler----勾上Treat"const"as"_flash"解释:将定义的const较大数组装入flash.二、如何通过AVR_fighter对EEPROM编程:在运用ICCAVR编程时对需要写入EEPROM的数据作如下处理:///////////////////////////////////////////////////////#pragma data:eepromunsigned char table[]={0x01,0x02} //定义要写入EEROM的数据#pragma data:data并将#include <eeprom.h> 加入C代码中。
////////////////////////////////////////////////////////通过以上处理后的数据在编译时会被ICCAVR编译生成*.eep文件,将此文件加入AVR_fighter的装EEPROM ,AVR_fighter在编程flash时相应会编程EEPROM。
三、将SPI初始化为主机,进行简单的数据发送。
例子中SSR_SIP必须由实际的数据方向寄存器代替。
void spi_maxterinit (void){DDR_SPI = (I<<DD_MOSI)|(1<<DD_SCK); //设置MOSI和SCK为输出,其他为输入SPCR = (1<<SPE)|(1<<SPR0); //使能SPI主机模式,设置时钟速率为fck/16}void SPI_MasterTransimt(char cData){SPDR = cData; //启动数据传输while(!(SPRS & (1<<SPIF))); //等待传输结束}///////////////////////////////////////////////////////////////////////////////////////////////////////////例子假定已经饱含了正确的头文件:Void SIP_SlaveInit(void){DDR_SPI = (1<<DD_MISO); //设置MISO为输出,其他为输入SPCR = (1<<SPE); //使能SPI}Char SPI_SlaveReceive(void){While (!( SPSR & (1<<SPIF ))){};Return SPDR;}四、对一个十六进制数的某一位取反Num = num^( 1<< wei );五、STC自动下载:Include <reg52.h>Sfr ISP_CONTR =0XE7;sbit ISP=P3^0;void main(void){TMOD |= 0X01;TH0=0X00;TL0=0X00;EA=1;ET0=1;TR0 =1;}void Timer0_isr(void) interrupt 1 using 1{TH0=0x00; //重新赋值TL0=0x00;while(ISP==0){ISP_CONTR=0XE0;}}。
IAR for AVR 安装及入门使用手册
9、 在左边 Category 中选择 C/C++Compiler 项, 后在右边 Optimizations 中选择 None(Best debug suport) ,即选择不要代码压缩功能;
10、在左边 Category 中选择 Linker 项,后在右边 Output 中选择如下图的参数,该设置是生 成可以仿真用的文件;
IAR for AVR 安装及入门使用手册
一、安装 IAR for AVR 4.20A 版本
1、 点击
程序,开始安装程序;
2、 一路点击“next” ,直到出现下图(红笔处为说明,以下同):
3、 点击安装破解程序 4、 出现界面时选择参数如下图;
;
5、 把 上 图 的 license number 中 的 数 子 复 制 里 下 图 中 , 后 点 击 下 一 步 ;
11、在左边 Category 中选择 Linker 项,后在右边 Extra Output 中选择如下图的参数,该设置 是生成可以烧写用的文件;
12、在左边 C后在右边 Setup 中选择如下图的参数,该设置是 使用软件仿真 Simulator,当你只想用硬件调试时,可以选择 JTAGICE 等 JTAG 仿真器进行 与硬件连接调试用;
13 、可以编译了,按一下工具条的
图标,因为第一次编译,所以需要先保存一下 编译,在 Messages 中出现下图,表示成功编
Workspace,这里输入名 iardemo.再按一下 译了。
14、这时你打开 workspace 中的+号,会看到里面多了好多文件,这些都是编译时连接文件, 包括头文件,编译后的结果文件,其中 iardemo.a90 为烧写文件,iardemo.d90 不仿真文件;
AVR入门笔记1
大家好,写这个文档是想教你们如何写出单片机的第一个程序,同时对比一下单片机的C语言和你们在Visual Studio下编写的C语言的不同之处。
单片机编程也是用C语言,但是跟PC上编写风格还是有一些不同,大家要注意。
首先大家看一段十分简单的PC上的C语言程序。
#include <stdio.h>void main(void){int a = 1, b = 2, c = 3;int sum = 0;sum = a + b + c;printf("%d\n",sum);}大家再看一段十分简单的单片机C语言程序。
为了方便,我把PC上的C语言称为“C语言”,把单片机上的C语言称为“C51语言”。
/*****************************************************This program was produced by theCodeWizardAVR V1.25.9 ProfessionalAutomatic Program Generator?Copyright 1998-2008 PavelHaiduc, HP InfoTech s.r.l.Project :Version :Date : 2011/9/10Author : ZHOUQIANCompany : ZHOUQIANComments:Chip type : ATmega88P //AVR芯片型号Program type : ApplicationClock frequency : 7.372800 MHz //晶振频率Memory model : SmallExternal SRAM size : 0Data Stack size : 256*****************************************************/#include <mega88p.h> //该头文件定义了寄存器#include <delay.h> //该头文件引入延时函数void main(void){DDRD.6 = 1; //什么是DDRD?PORTD.6 = 0; //什么是PORTD?while (1) //while(1)是死循环,为什么会用它?{PORTD.6 = 1; //LED亮delay_ms(1000); //为什么要延时?PORTD.6 = 0; //LED灭delay_ms(1000);}}大家很容易观察发现,C语言习惯设一些变量,例如int a,b,c,然后对这些变量进行读写,而C51却对DDRD和PORTD进行读写,DDRD和PORTD是寄存器,AVR大概有60个寄存器,通过操作它们我们可以控制AVR芯片的某个引脚输出高电平或低电平,可以让某个引脚检测外部输入了什么电平或边沿,可以让单片机和别的设备互相收发信号,可以让单片机测出某个引脚上输入的电压值,可以让某个引脚发出特定频率和占空比的波形来控制电机,等等。
AVR单片机学习笔记
AVR单片机学习笔记
Atmega16A
一、寄存器
1.特殊功能寄存器SFIOR
位2-PUD为上拉电阻禁止位。
置位时即使DDRxn和PORTxn配置位使能上拉电阻,I/O 端口的上拉电阻也会被禁止。
PA端口:
2.端口A数据寄存器PORTA
确定PA口的工作状态;
PORTAn(n=0-7)初始值为0x00(十六进制)。
3.端口A方向寄存器DDRA
指定PA端口是作为输入还是输出口用;
DDRAn(n=0-7)初始值为0x00(十六进制)。
4.端口A输入引脚PINA
用来访问端口A的逻辑值且只允许进行读操作。
PB端口:
5.端口B数据寄存器PORTB
确定PB口的工作状态;
PORTBn(n=0-7)初始值为0x00(十六进制)。
6.端口B方向寄存器DDRB
指定PB端口是作为输入还是输出口用;
DDRBn(n=0-7)初始值为0x00(十六进制)。
7.端口B输入引脚PINB
用来访问端口B的逻辑值且只允许进行读操作。
PC端口、PD端口同上
二、数码管
1.段选数据输出-->>位选数据输出-->>数码管显示数字
2.段选
选择数码管的序号i,使第i个数码管发光(i为一整型数)。
3.位选
选择第i个数码管的发光位置,使其显示特定的数字。
IAR for AVR
t_bit1:1, t_bit2:1, t_bit3:1, t_bit4:1, t_bit5:1, t_bit6:1, t_bit7:1; }; }; void main(void) {
t_bit0=1;//访问变量 t 的位 t_bit0=~t_bit0; PORTB=t;//直接访问变量 t } 位变量也可以直接定义在工作寄存器里。
PORTB=a;//读取 flash 空间值 9 PORTC=p[0]; //读取 flash 空间值 }
4.1.2flash 空间绝对地址定位: __flash unsigned char a @ 0x8;//定义变量存放在 flash 空间 0X08 单元__fl ash unsigned char p[] @ 0x22//定义数组存放在 flash 空间,开始地址为 0X 22 单元 __flash unsigned char a @ 0x08=9;//定义常数存放在 flash 空间 0X08 单元 __flash unsigned char p[] @ 0x22={1,2,3,4,5,6,7,8};
3.4 bool 数据类型在 C++语言里是默认支持的。 如果你在 C 代码的头文件里包含 stdbool.h, bool 数据类型也可以使用在 C
语言里。也可以使用布尔值 false 和 true。不过是占用 8 位 1 个字节。 #include<iom8.h> #include<stdbool.h> bool y=0;//定义位变量 void main(void) {
4.4. __root 关键字保证没有使用的函数或者变量也能够包含在目标代码中. 定义存放在__flash 空间的数据在程序编译时会自动生成代码嵌入到 flash 代 码中,对于程序没有使用也要求编译的数据(比如可以在代码中嵌入你的版本号, 时间等)必须加关键字__root 限制。 例:
AVR单片机笔记
A VR单片机笔记说明:主要使用的编译环境为IAR,使用A VR的ATmega16 和128目录IO (2)时钟: (2)MCU控制寄存器-MCUCR (2)MCU控制和状态寄存器-MCUCSR (2)看门狗定时器控制寄存器-WDTCR (3)外部中断控制寄存器A -EICRA (4)外部中断控制寄存器B -EICRB (4)外部中断屏蔽寄存器-EIMSK (4)外部中断标志寄存器-EIFR (5)中断矢量表 (5)在IAR环境中AVR中断程序的格式 (6)定时器 (6)定时器/计数器0和2: (6)定时器/计数器1和3: (7)使用IAR调试注意事项 (7)IIC(TWI) (8)o8515.h头文件 (10)IOPort A-G:都含有内部上拉电阻数据:PORTA-G;方向DDRA-G;PINA-G 时钟:XTAL 分频控制寄存器-XDIVMCU控制寄存器-MCUCRMCU控制和状态寄存器-MCUCSR• Bit 4 – JTRF: JTAG 复位标志通过JTAG 指令A VR_RESET 可以使JTAG 复位寄存器置位,并引发MCU 复位,并使JTRF 置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 3 – WDRF: 看门狗复位标志看门狗复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 2 – BORF: 掉电检测复位标志掉电检测复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 1 – EXTRF: 外部复位标志外部复位发生时置位。
上电复位将使其清零,也可以通过写”0” 来清除。
• Bit 0 – PORF: 上电复位标志上电复位发生时置位。
只能通过写”0” 来清除。
看门狗定时器控制寄存器-WDTCR• Bits 7..5 – Res: 保留保留位,读操作返回值为零。
• Bit 4 – WDCE: 看门狗修改使能清零WDE 时必须先置位WDCE,否则不能禁止看门狗。
使用_IAR_FOR_AVR_时需要注意的几个地方
在AVR 所有的编译器中,IAR for AVR 是编译效率最高的编译器, 但是相对来说IAR for AVR 的设置项也非常多,如果使用不当反而会出现很多莫名其妙的问题.一. 关于堆栈的设置问题GCC 和IAR 分配堆栈的方式不同,IAR 先分配堆栈空间,相当于定义一个全局数组为堆栈空间,堆栈初始为堆栈空间最高地址;GCC 不用先分配堆栈,自动把RAM 剩余空间作为堆栈空间,堆栈初始为RAM 最高地址。
初学者很容易忽视这个问题,造成程序跑飞而找不到问题的症结,我在用IAR For MSP430 的时候没遇到过这个问题,因为MSP430 的RAM 比较大,IAR 默认是80 字节,足够一般程序使用。
但是使用IAR For SAM8 的时候,有一个比较耗费堆栈的程序运行一段时间后出问题,由于要记录一个24 小时的数组,而数组元素的值是在堆栈里改变的,所以,记录到一定时间以后,出现了堆栈不足的情况,初学者如果没有仿真器,是很难发现这个问题的,还好我用的OPENice i500 仿真器在Debug 的时候出现了堆栈不足的警告,我才意识到是这里问题。
IAR For SAM8 默认堆栈是32 字节,既然不够用,那么就要增大,但是设置到多少合适呢?首先编译你的程序,看程序用了多少自己的RAM,在看看芯片的Datasheet,看看芯片总共有多大的RAM,(原文件名:9428.JPG) 引用图片好了现在你就知道剩余多少RAM 了:208-142=66(Byte)前面说过IAR 的CSTACK,NEAR_HEAP 和RSTACK 是预先分配好的,占用存储空间是固定不变的,相当于定义了一个全局数组,GCC 堆栈策略与IAR 不同,堆栈大小不是预先分配好的,而是把SRAM 里面剩余空间作为堆栈空间。
如果是GCC,那么编译器就会自动设置剩余的RAM 为数据堆栈(和数据返回堆栈RSTACK,NEAR_HEAP 等)。
在IAR 里,STACK 应该设置到多少呢?在工程-》Options-》Linker-》List(不同的IAR 版本会稍有不同),选择生成LIST 文件,并包含stack 选项(原文件名:iar.JPG) 引用图片在./Debug/list 目录下,得到.map(可能是.lst 等其他格式)文件,用记事本打开,找到以下内容:******************************************* CALL GRAPH******************************************* ->Sub-tree of type: Interrupt function tree that does not make: indirect callsCSTACK01Stack used (prev) :int_T0_OV00000000| Stack used (prev) : 00000000 | + function block : 0000000C......(省略N 行)01 main| Stack used (prev) : 0000003A| + function block : 00000000<-Sub-tree of type: Function tree| Stack used : 0000003A找到最大的Stack used,我的就是0000003A,58 个字节,这就是用到的最大的堆栈空间,保守一点,我设置成64 字节,没有超过剩余RAM,再重新编译,运行,仿真器没有堆栈不足警告,程序也能正常运行了。
21IC-AVR学习笔记,AVR单片机教程
21IC-AVR 学习笔记,AVR 单片机教程AVR 学习笔记一、基本输出实验(电路原理图)
本实验包括七个例程:1、点亮LED 试验,2、流水灯试验,3、蜂鸣器试验,4、1 位数码管显示试验,5、四位数码管显示试验,6、1602 液晶显示试验,7、12864 液晶显示实验。
AVR 学习笔记二、基本输入和外部中断实验
本实验包括二个例程:1、检测按键,实现按键控制LED 的亮灭,2、外部中断实验,利用中断检测按键,并在数码管上显示。
AVR 学习笔记三、定时记数器0 实验
本实验包括五个例程:1、定时/计数器0 的计数实验,2、定时/计数器0 的定时实验,3、定时/计数器0 的比较匹配(CTC)实验,4、定时/计数器0 的快速PWM 实验,5、定时/计数器0 的相位修正PWM 实验。
AVR 学习笔记四、定时记数器1 实验
由于在定时/计数器0 的实验中我们已经学会了定时/计数器的定时、计数、PWM 等基本功能的使用方法。
而单片机中的定时/计数器的基本功能大致上是一样的。
主要区别只是在于对不同寄存器的设置。
所以在定时/计数器1 的。
IAR for AVR 安装及入门使用手册
一、安装 IAR for AVR 4.20A 版本
1、 点击
程序,开始安装程序;
2、 一路点击“next” ,直到出现下图(红笔处为说明,以下同):
3、 点击安装破解程序 4、 出现界面时选择参数如下图;
;
5、 把 上 图 的 license number 中 的 数 子 复 制 里 下 图 中 , 后 点 击 下 一 步 ;
面
。下一步将可以在 IAR 上编写程序了。
二、IAR for AVR 使用入门
1、 点击图标,打开软件源自面,将出现下图:2、 这里我们要新建一个工程, 点击 图:
图标, 出现下
3、 在 Tool chain 中选择 AVR,Project templates 中选 Empty project,创建一个空的工程;我 们命名为 iardemo,保存该工程;
9、 在左边 Category 中选择 C/C++Compiler 项, 后在右边 Optimizations 中选择 None(Best debug suport) ,即选择不要代码压缩功能;
10、在左边 Category 中选择 Linker 项,后在右边 Output 中选择如下图的参数,该设置是生 成可以仿真用的文件;
11、在左边 Category 中选择 Linker 项,后在右边 Extra Output 中选择如下图的参数,该设置 是生成可以烧写用的文件;
12、在左边 Category 中选择 Debugger 项,后在右边 Setup 中选择如下图的参数,该设置是 使用软件仿真 Simulator,当你只想用硬件调试时,可以选择 JTAGICE 等 JTAG 仿真器进行 与硬件连接调试用;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
原创--IAR for A VR入门学习笔记A VR单片机的编译软件五花八门,用宋丹丹的话就是:那是相当的多汇编语言的开发平台就不说了(俺不大会,呵呵,说不出什么道道来)。
简单列举几个高级语言的开发平台:WINA VR(GNU GCC A VR);ICC A VRCodeVison A VRIAR for A VRBASIC A VRFastA VRBASCOM其中用得最多的是完全免费的WINA VR。
我一直都是用的这个。
最专业,最好的,对AVR支持最全面的是IAR。
但同时IAR也是最贵的一款开发软件(听说升级也要收费,真黑啊)。
呵呵,不过不怕,我们可以破解之。
下面就详细介绍如何破解IAR。
这里安装破解的是5.11B版本的。
全名IAREmbeddedWorkbenchforAtmelAVR,v.5.11B1、先到网上下载5.11B文件,大概133M。
解压后,有如下文件:a1.jpg (29.87 KB)2009-12-20 00:282、到网上下载破解文件解压后生成文件Keygen包,将它复制到C盘根目录下,如下图a2.jpg (63.75 KB)2009-12-20 00:283、打开文件包keygen,双击文件IARID.exe,出现本电脑ID号,如图,记下来a3.jpg (42.68 KB)2009-12-20 00:284、从电脑的“程序---运行”输入“CMD”回车,按照下图操作,得到sn.txt文件;注意输入计算机ID号的时候,所有字符全部大写,包括"0X"中的"X"也要大写,a4.jpg (161.06 KB)2009-12-20 00:285、然后运行安装文件中的autorun.exe,开始安装IAR,当出现要求输入注册号的时候,请用记事本打开刚刚生成的sn.txt 文件,找到"EW A VR" version "2.25_WIN"对应的号码段,先输入序列号,NEXT后,再复制key:后面的一串字符,注意只复制#之前的那一部分,包括#也要复制。
再点击NEXT,如果出现提示错误,请重复步骤4,重新生成sn.txt文件,再用新号填入试试,直到成功。
很容易成功的!6、下面就跟常规软件的安装方法一样了,静静等待安装完成!要特别注意:1、获得的电脑ID号一定要大写!包括16进制符号:0X......;2、生成的sn.txt文件中,不是每个系列都能用,每次生的文件中,只有一个使能用于A VR的,就是那个"EW A VR" version "2.25_WIN"对应的号码段,其他就不要试了!今天就写这么多吧,明天写一下怎么写一个入门程序!IAR for A VR编程的第一个程序1、安装完成IAR for A VR5.11B后,就可以开始第一个入门程序的学习了。
IAR软件安装完成后,不会自动在桌面上建立一个快捷启动图标。
我们可以按照以下顺序打开改软件“开始-程序-IAR System-IAR Embedded Workbench for Atmel A VR V5-IAR Embedded Workbench”。
当然,在“IAR Embedded Workbench”图标上单击右键建立一个桌面快捷方式是很有必要的。
2、按照上述步骤,打开IAR for A VR的IDE开发环境,出现如下图的启动界面,在启动界面里,我们可以选择如下操作:在当前工作区新建一个工程项目;在当前工作区添加一个已经存在的工程项目;打开一个工作区;查看应用实例。
a5.jpg (119.84 KB)2009-12-20 22:423、,在当前工作区新建一个项目文件,点击如下图的图标,a6.jpg (18.13 KB)2009-12-20 22:424、出现如下对话框,在“tool chain”中选择单片机类型:A VR。
在“project templates”中选择空项目模板“empty project”。
然后点击“OK”按钮,进入下一步操作a7.jpg (48.25 KB)2009-12-20 22:425、出现如下对话框,提示我们将该项目另存到那个文件夹中,选择我们即将要保存的文件夹,然后输入项目名称(注意文件格式是.ewp格式),点击“保存”按钮,进入下一步操作a8.jpg (75.16 KB)2009-12-20 22:426、这时工程项目就出现在IAR IDE集成开发环境界面的左侧,如下图,一般在默认状态下,系统会生成两个项目文件版本:调试版本“debug”和发行版本“release”。
调试版本一般用以在项目文件开发阶段,进行程序的编译、仿真、调试等。
发行版本则是程序开发完成后,用于向外发布项目文件所用。
a9.jpg (33.54 KB)2009-12-20 22:427、关于调试版本“debug”和发行版本“release”的选择如下图所示。
在下拉箭头处进行两种版本的切换。
a10.jpg (4.92 KB)2009-12-20 22:428、接下来把刚才创建的项目保存到一个工作区中,依次点击file-save workspace后,出现如图所示的保存界面,输入工作区的名称(注意文件格式是.eww格式),选择存放路径,然后点击“保存”按钮进行保存。
a11.jpg (76.88 KB)2009-12-20 22:429、接下来可以编写源程序文件(也可直接添加程序文件到项目中),依次单击new-file,编辑区就出现了名为untitled1的文本文件编辑窗口,输入以下程序代码:如下图所示#includevoid main(void){DDRB = 0xFF;PORTB = 0xFF;while(1){PORTB = 0x00;PORTB = 0xff;}}a12.jpg (68.62 KB)2009-12-20 22:4210、程序代码输入完毕后,需要保存该代码文件,依次点击file-save,出现如下图所示的界面,然后输入要保存的文件名,保存在我们上面建立的文件夹中,这是可以看到,程序文件名称变为我们保存的文件名了。
a13.jpg (79.29 KB)2009-12-20 22:4211、接下来需要将这个程序文件添加到项目文件中,在workspace框中,选择项目文件名,然后点击鼠标右键,在出现的下拉菜单中依次选择add-add“xxx.c”(xxx.c代表我们刚才编写的程序文件),这样便将程序文件添加到项目中了,这时workspace框,出现了变化,如下图,多出了一个first.c文件和output文件夹。
first.c就是我们刚才编写的程序文件,而output文件夹则是用来防止编译后的结果文件的。
a14.jpg (54.94 KB)2009-12-20 22:4212、项目、工作区,程序文件都建好了,接下来该对项目文件进行编译、连接、调试方面的设置了。
在workspace框中选择项目名称,右键点击,在弹出的下拉菜单中选择”options“选项,如下图,首先在category选项框下面选择general options选项,a15.jpg (127.44 KB)2009-12-20 22:4213、按照下图选择CPU型号和存储器模式a16.jpg (91.5 KB)2009-12-20 22:4216、接着进行编译器的选择,如下图,优化选项设为none2009-12-20 22:4217、编译连接选项,如下图,编译的目的肯定是要输出可烧写的hex文件的,按照图中选项设置2009-12-20 22:4218、调试选项设置,可根据实际情况选择仿真类型:软件仿真或者硬件仿真器仿真a19.jpg (106 KB)2009-12-20 22:42项目文件的建立和配置就是这些了,今天到这里吧,明天我们再来了解一下模拟仿真的步骤和操作事项三、模拟仿真1、前面我们介绍了项目的创建和相关的配置,项目建立并配置后,就可以对该项目进行编译了,2、选中项目文件,右键点击,在弹出的下拉菜单中选择“rebuild all”,在编译器的下面会出现调试信息,如下图,编译成功后,会提示没有错误和警告,如果有错误的话,会提示错误类型和所在位置。
a1.jpg (25.4 KB)2009-12-21 23:142、开始模拟仿真,点击project菜单下的debug就可以进入软件模拟仿真环境,当然也可以单击快捷方式进入模拟仿真。
快捷方式如下图a2.jpg (2.23 KB)2009-12-21 23:143、进入模拟仿真环境后,如下图,选择view菜单下的register选项,即可看到各寄存器的情况。
a3.jpg (163.18 KB)2009-12-21 23:144、在弹出的register对话框中,可以通过下拉箭头来选择查看不同的寄存器,例如我们这个例子主要用到了端口B,我们就可以选择PORTB寄存器,如下图,可以通过点击“+”或者“-”符号来选择将该寄存器展开或者综合。
a4.jpg (68.28 KB)2009-12-21 23:145、我们可以通过如下图的快件方式来选择程序运行方式:单步、跳过、全速、复位,退出仿真等a5.jpg (23.6 KB)2009-12-21 23:146、通过单步运行方式可以看到PORTB端口寄存器的内容随着程序的执行发生变化,说明端口的输出值在变化,这与程序的功能是一致的,7、仿真调试结束后,可以选择debug菜单下的stop debug按钮退出仿真界面,当然也可以通过点击如下图所示的快捷按钮退出仿真环境。
a6.jpg (3.12 KB)2009-12-21 23:14今天就到这里,明天我们来学习一下中断程序的编写四、中断程序的编写1、在IAR中中断处理函数的形式为:#pragma vector = 中断向量_interrupt void 函数名(void){/******中断服务函数的程序代码********/}例如:定时器0的溢出中断#pragma vector = TIMER0_OVF_VECT_interrupt void timer0(void){/******中断服务函数的程序代码********/}2、不同型号的A VR芯片,其中断个数和中断向量各不相同。
以下是A Tmega16的中断向量表。
从下面的中断向量表可以看出,所谓的中断向量,其实只是一个符号,利用#define语句,将中断入口地址与中断向量符号联系了起来,这样用助记符来表示中断,便于记忆#define RESET_vect (0x00)#define INT0_vect (0x04)#define INT1_vect (0x08)#define TIMER2_COMP_vect (0x0C)#define TIMER2_OVF_vect (0x10)#define TIMER1_CAPT_vect (0x14)#define TIMER1_COMPA_vect (0x18)#define TIMER1_COMPB_vect (0x1C)#define TIMER1_OVF_vect (0x20)#define TIMER0_OVF_vect (0x24)#define SPI_STC_vect (0x28)#define USART_RXC_vect (0x2C)#define USART_UDRE_vect (0x30)#define USART_TXC_vect (0x34)#define ADC_vect (0x38)#define EE_RDY_vect (0x3C)#define ANA_COMP_vect (0x40)#define TWI_vect (0x44)#define INT2_vect (0x48)#define TIMER0_COMP_vect (0x4C)#define SPM_RDY_vect (0x50)3、中断函数不能进行参数传递,所以中断函数的输入和输出参数全部为void,即没有参数。