AVR学习笔记
- 格式:doc
- 大小:105.00 KB
- 文档页数:27
学习笔记-avr单片机C编程1这几天在看AVR 单片机的书。
ASURO 的项目的编程是建立在已有的成熟函数上,所以导致我对AVR 单片机的运行机理(中断、定时器的使用)不甚了解。
突然一个个超声波模块的程序放在眼前,才发现我连AVR 单片机的了解基本上等于零。
另外一个项目需要用mega128 控制直流电机,还有和无线、有线遥控器的通信,电路(模块)需要自己搭起来,那么就必须知道AVR 单片机的原理和编程。
和已经学过的51 单片机相比,MEGA 系列单片机是十分高级的单片机,功能强大,因而在构造和使用上也复杂了一些。
存储器区别,AVR 分为5 个部分,访问指令上有区别。
输入输出,51 是准双向口,每个端口只有一个寄存器。
而AVR 的I/O 口是标准双向口,每个端口有三个寄存器,DDRX(输出使能),PORTX(输出数据,上拉使能?),PINX(输入管脚)。
定时器,51 的定时器两种用法,即以晶振频率的十二分频信号作为输入的定时器工作方式,或以外部引脚INT0,INT1 上输入信号的计数器工作方式。
而AVR 的定时器除了普通的定时/计数功能外,还有一些增强的功能,如:比较匹配(?),PWM 调制器,由ICP 引脚或模拟比较器触发的捕捉功能(?)。
在选择输入信号上,分频比有1、8、64、256、1024 几种,作为计数器使用,既可上升沿触发,也可以下降沿触发。
如下,一部分和定时器相关的寄存器T0: TCCR0: CS02 CS01 CS00 分频比T1: TCCR1A: COM1X1/0 PWM11/0 TCCR1B: ICNC1,CTC1,ICES1 TCNT1 OCIX 等等 C 中的一些位操作已经模块化了,如PORTB|=(1PWM 脉宽调制波PWM 是脉冲宽度调制的简称。
实际上,PWM 波也是一个连续的方波,但在一个周期中,其高电平和低电平的占空比是不同的。
一个典型PWM 的波形如图8-15 所示。
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寄存器掌控。
ATmega16中断表第一节课Avr单片机的每个引脚有三个寄存器来控制:DDRnx(输入输出控制寄存器1输出,0输入)PORTnx(引脚输出电平控制)PINnx(输入寄存器)第二节课AVR单片机的AD转换涉及寄存器:ADMUX sbit[7;6]参考电压选择,sbit[5] AD转换数据对齐方式选择,sbit[4:0]通道与增益选择;ADCSRA sbit[7]AD使能,sbit[6]AD开始转换,sbit[5]自动触发使能,sbit[4]AD 中断使能,sbit[3:0]分频设置;SFIOR(触发源的选择)sbit[7:5] (ADTS)选择触发源,ADCL,ADCH数据寄存器;初始化步骤:1:设置通道的IO口为输入(高阻);2:设置与AD有关的寄存器;3:开总中断,SREG=BIT(7);4:写中断函数(中断标号是15)第三节课AVR有三个定时计数器,T/C0,T/C1,T/C2;T/C0,T/C2是两个8BIT的计数器;T/C1定时计数器,普通模式时机寄存器:TCCR1B:2:0时钟选择TCNT1L,TCNTH:定时数据TIMSK :TOIE 中断使能位 使用方法1, 选择时钟源,TCCR1B ;2, 设计初值,TCNT1L ,TCNT1H ;3, 设置中断使能位;TIMSK{2},SREG{7} 4, 选中断号,写中断函数 5, (中断号9)CTC 模式如果输出波形,则设IO 位输出 设置波形模式和时钟源TCCR1B 设置输出模式TCCR1A根据需要设置上限OCR1ATCCR1A 设置输出口频率计算:()A OCR N ffclko112+∙∙=控制寄存器A TCCR1ACOM1A1:0: 通道A 的比较输出模式 COM1B1:0: 通道B 的比较输出模式COM1A1:0与COM1B1:0分别控制OC1A 与OC1B 状态。
如果COM1A1:0(COM1B1:0)的一位或两位 被写入"1”,OC1A(OC1B) 输出功能将取代I/O 端口功能。
原创--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:后面的一串字符,注意只复制#之前的那一部分,包括#也要复制。
AVR 单片机一些学习笔记
下面是自己在学习AVR 单片机时的学习经验,分享出来给大家,一起
学习。
1、AVR 单片机采用RISC 架构,8051 单片机采用CISC 架构。
前者速度为后者的2~4 倍,为流水线操作指令。
2、AVR 单片机有32 个通用寄存器(地址在RAM 区从$0000 开始到$001F),其中有6 个(最后6 个)合并为3 个16 位的X,Y,Z 寄存器,用来存放地址指针,Z 寄存器还可以寻址程序存储器。
3、哈佛结构,131 条机器指令。
4、延迟开机功能。
5、内部自带RC 振荡器,可提供1/2/4/8MHZ 的工作时钟。
6、FLASH+EEPROM+SRAM+SPI+USART+TWI+PWM+RTC+10 位ADC+模拟比较器+JTAG。
7、堆栈指针向下增长,51 单片机向上增长。
8、程序存储器按字来访问,擦除和写入以页为单位。
A VR学习笔记三、定时/记数器0实验-------基于LT_Mini_M163.1 定时/计数器0的计数实验3.1.1、实例功能定时/计数器(Timer/Counter)是单片机中最基本的接口之一,它的用途非常广泛,常用于计数、延时、测量周期、频率、脉宽、提供定时脉冲信号等。
在实际应用中,对于转速,位移、速度、流量等物理量的测量,通常也是由传感器转换成脉冲电信号,通过使用定时/计数器来测量其周期或频率,再经过计算处理获得。
相对于一般8位单片机而言,AVR不仅配备了更多的定时/计数器接口,而且还是增强型的,如通过定时计数器与比较匹配寄存器相互配合,生成占空比可变的方波信号,即脉冲宽度调制输出PWM信号,用于D/A、马达无级调速控制、变频控制等,功能非常强大。
ATmega16一共配置了2个8位和1个16位,共3个定时/计数器,它们是8位的定时计数器T/C0、T/C2和16位的定时/计数器T/C1。
在接下来的几个实例中,我们将逐一学习这些定时/计数器的各种功能和使用方法。
在前面的实例中,我们已经学习了利用单片机的I/O口进行按键的输入检测,并实现了将按键按下次数在数码管上进行显示。
使用的方法是不停的检测端口状态,每检测到一次电平变化记录一次,这样实现起来未免有些重复劳动的嫌疑,那么有没有一种方法可以不用每次都这么辛苦呢?答案是肯定的!我们可以使用定时/计数器的计数功能实现对外部事件(电平变化次数、脉冲个数等)进行计数。
在本实例中,我们利用ATmega16单片机的定时/计数器0的计数功能实现对按键次数的检测,并通过LED的亮灭来指示程序的运行状态。
本实例共有3个功能模块,分别描述如下:●单片机系统:检测按键的按下,通过LED灯的亮灭指示按键按下次数。
●外围电路:按键检测电路以及显示按键状态的LED显示电路。
●软件程序:熟悉掌握ATmega16单片机的定时/计数器0的计数程序的编写。
3.1.2、器件和原理本实例首先介绍ATmega16单片机的定时/计数器0的功能,然后详细介绍如何利用定时/计数器0实现对外部事件进行计数的功能。
一、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单片机引脚图。
1.输入状态IO寄存器设置DDRx某一位置0,相应位的IO口被设置为输入输出|=(置1),输入&=~(置0)PORTx某一位置1,使能对应IO口相应位的上拉电阻PINx的对应位是输入的数据,0或1头文件是includ <avr/io.h>2.ISC2为0时,外部中断2是下降沿触发,为1时,是上升沿触发。
3. 4.1.2.T/C寄存器在全局变量前加volatile,这个变量才能应用在中断程序中USART 1.2.GCC编程1)另外,宏_BV(bit) 是我们操作I/O 寄存器时频繁用到的,avr-libc 建议使用这一宏进行寄存器的位操作,它在文件sfr_defs.h 中定义如下:#define _BV(bit) (1 << (bit))2)avr-libc 建议使用一组数据类型符号,这些数据类型的定义在头文件inttype.h 中,头文件的包含形式如下:#include <inttype.h>其中定义了常用的整数类型如下表所示3)const int n = 5;4)int a[n];注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量!= 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是ANSI C对数组的规定限制了它。
5)那么,在ANSI C 语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。
6)在程序中访问 FLASH 程序存储器avr-libc 对FLASH 存储器的读写支持API 和宏在头文件pgmspace.h中定义,在源文件中的包含形式如下:#include < avr/pgmspace.h >在程序存储器内的数据定义使用关键字__attribute__((__progmem__))。
A VR学习笔记四、定时/记数器1实验-------基于LT_Mini_M164.1 定时/计数器1的计数实验4.1.1 实例功能ATmega16的T/C1是一个16位的多功能定时计数器,其主要特点有:●真正的16位设计,允许16位的PWM。
● 2个独立的输出比较匹配单元。
●双缓冲输出比较寄存器。
●一个输入捕捉单元。
●输入捕捉躁声抑制。
●比较匹配时清零计数器(自动重装特性,Auto Reload)。
●可产生无输出抖动(glitch-free)的,相位可调的脉宽调制(PWM)信号输出。
●周期可调的PWM波形输出。
●频率发生器。
●外部事件计数器。
●带10位的时钟预分频器。
● 4个独立的中断源(TOV1、OCF1A、OCF1B、ICF1)。
在前面的实例中,我们已经学习了AVR单片机的定时/计数器0,本实例和下一个我们学习定时/计数器1,从上面的介绍我们可以看出,ATmega16单片机的定时/计数器1功能更为强大,值得我们深入学习。
定时/计数器的基本功能都是定时、计数等,掌握了一个定时/计数器的用法就能很容易的掌握其他定时/计数器的用法,所以我们不在学习定时/计数器1的定时、计数等基本功能。
在接下来的两个实例中,我们将学习定时/计数器1的增强功能。
在本实例中,我们利用ATmega16单片机的定时/计数器1的输入捕捉功能实现对按键时间的捕捉,并检测两次按键之间的时间间隔,然后通过LED指示实例运行效果。
本实例共有3个功能模块,分别描述如下:●单片机系统:使用定时/计数器1的输入捕捉功能检测按键的按下,并判断两次按键按下的时间间隔,然后通过LED灯的亮灭指示按键按下次数。
●外围电路:按键检测电路以及显示运行结果的LED显示电路。
●软件程序:熟悉掌握ATmega16单片机的定时/计数器1的输入捕捉中断程序的编写。
3.1.2、器件和原理本实例首先介绍ATmega16单片机的定时/计数器1的输入捕捉功能,然后详细介绍如何利用定时/计数器1实现对外部事件进行输入捕捉。
A VR学习笔记之【外部中断】【一】Mega16共有三个外部中断,外部中断相比定时器而言它的寄存器比较少,因此相对比较简单。
我们现在只关心需要用的部分,其他的暂且放弃不管。
和外部中断相关的特殊功能寄存器有:①MCU控制寄存器(MCUCR)在上面八位的寄存器中,白色的部分使我们要关心的,灰色部分就不用管了。
资料上对后面四位(第四位)的作用有介绍。
ISC11与ISC10控制中断1的触发方式。
下表为ISC10/11的值对应触发方式:SC11与ISC10控制中断0的触发方式。
下表为ISC00/01的值对应触发方式:我们在使用外部中断0和1的时候,其触发方式的设置便是通过以上ISC的不同值实现的。
至于INT2下面有介绍。
②MCU控制与状态寄存器(MCUCSR)这个寄存器只有一个BIT与外部中断相关。
ISC2,我们通过和INT0/1的对比可以发现ISC的后缀数字命名只有规律的,这会方便我们记忆。
同时在说明文档上说了很长一段关于ISC2的说明:他的意思说早了,他也就是想说:ISC=0的话INT2是下降沿出发中断,ISC=1是上升沿出发。
这才是应该说明的最重要的点。
他后面还说了:(1)如果你让ISC=0那么外部的低电平必须保持到当前正在运行的指令运行结束才会出发,换一句意思就是,如果外部时间过短,有可能导致INT2不被触发。
(2)他又说明,如果改变ISC2的值的话有可能触发中断,导致误判,因此如果你想改变其中断触发方式的话,首先把通用中断控制寄存器(GICR)里面控制INT2的中断开关关了,这样便不会触发中断了。
③通用中断控制寄存器(GICR)他就是个中断开关。
前面三位依次赋值便会打开响应中断。
当然总中断开关也要打开才行(SREG|=BIT(7))。
④通用中断标志寄存器(GIFR)他就是一个中断标志,我们也就是说在中断发生的时候中断对用的标志会变为1,此时程序会自动转到中断程序子函数。
然后有硬件自动清零,以等待下一次的中断发生。
AVR TWIATMEL公司的AVR芯片上的TWI总线兼容I2C总线。
如何利用该硬件功能读写I2C设备网上的资料不多,而且很多很难得懂。
因此我查阅了ATMEL公司的技术文档,在学习的过程中,写下这篇笔记。
TWI接口是两线制的串口,与I2C接口一样,2线的名称都是SDA(串行数据地址线)和SCL(串行时钟线)。
在与设备相连时,2线都需要有上拉电阻相连。
如果设备输出为高阻时,上拉电阻10K将电平拉高。
一、地址包格式所有在TWI总线上传送的地址包均为9位,包括7位地址位,1个R/W控制位和1个应答位,如果R/W为1,则执行读操作。
如果R/W为0,则执行写操作。
从机被寻址后,必须在第9个SCL(ACK)周期通过拉低SDA做出应答,若从机忙或者无法响应主机,则应该在ACK周期保持SDA为高。
然后主机可以发出STOP状态或者REP START状态重新开始发送。
地址包包括从机地址和称为SLA+R或者SLA+W的READ或者WRITE位。
地址字节的MSB首先被发送。
所有1111xxxx的地址均保留,以便将来使用。
二、数据包格式所有在TWI总线上传送的数据包均为9位,包括8个数据位和一个应答位。
在数据传送中,主机产生时钟及START与STOP状态,而接收器响应接收。
应答是ACK在第9个SCL周期拉低SDA实现的。
如果接收器使SDA为高,则发送NACK信号。
如果接收器由于某种原因不能接受更多数据,应在最后一个数据字节后发出NACK信号告诉发送器停止发送。
数据的MSB首先发送。
三、地址包和数据包组合成一个完整的传输过程发送主要由START状态,SLA+R/W,至少一个数据包和STOP状态组成。
只有START与STOP状态的空信息是非法的。
四、比特率发生单元TWI工作于主机模式时,比特率发生器控制时钟信号SCL的周期。
具体数值由TWI状态寄存器TWSR的预分频系数以及比特率寄存器TWBR设定。
当TWI工作在从机模式时,不需要对比特率或者预分频系数进行设定,但从机CPU时钟频率必须大于TWI时钟线SCL频率的16倍。
大家好,写这个文档是想教你们如何写出单片机的第一个程序,同时对比一下单片机的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单片机学习笔记
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个数码管的发光位置,使其显示特定的数字。
林夕依然ATmega16学习笔记例程移植到Atmel Studio 6.2笔记相信你已经有了一定的C语言及数字电路基础,以及能定下心来,决心学点东西。
如果做不到的话,麻烦您把我轻轻的放开,该干啥干啥去。
前言最近学习A VR,网上找了N多资料后,发现就算林夕依然ATmega16学习笔记最合俺的心意。
优点如下:1、不讲原理,直接操作,适合俺这种不愿背书的差生。
2、每个例程都附有源程序及PROTEUS仿真文件,省了买零件的金钱及焊板的时间。
缺点当然也有:1、太省事了,初学者容易只跑跑例程,不求甚解(这也是市售所有学习板的通病)。
2、基于ICCA VR,而不是最新的AtmelStudio。
3、理论知识太少(也算是优点)。
还有一条就是这玩意是用EXE文件打包的,初次下载时,我不敢打开,生怕会给我强装软件或者开个后门什么的。
后来在网上下载了一个开发板的附带光盘文件,发现里面也带着这玩意。
心想这里面不该会有问题呀,才不是太放心的打开,打开后发现相见恨晚呀!好吧,先把这些例程一个一个琢磨完吧。
不过看程序时发现想打瞌睡,也难怪,看这玩意也太没挑战性了。
既然我的电脑中装了AtmelStudio,即然ICCA VR迟早要过时,不如把这里面的例程移植到AtmelStudio中吧!顺便也可以学习一下编程。
笔记不妨公开,俺也好刷一点成在感。
本文中所有例程均在AtmelStudio6.2+Proteus7.8中调试通过。
本文是我个人学习时的笔记,希望后来者能少走一点弯路。
学习MCU的惟一捷径是多读例程,多写程序,别无他法。
林夕依然ATmega16学习笔记下载链结如下:链接:密码:mzah实验1:8种LED点亮模式1、移植到AtmelStudio中的步骤打开Atmel Studio 6.2,新建一个项目。
不知道啥意思,我选第二个后,在下面起好项目名称及选好项目目录后OK。
这个好办,按CPU型号选就好了。
终于进入编辑窗口了。
一言蔽之,提取包中所有.c(C源码)、.h(C头文件)、.dsn(PROTEUS仿真文件)文件。
AVR 单片机学习笔记–LCD1602模块学完51单片机再来学AVR,感觉很容易上手,LCD1602在学51的时候学过,所以可以直接修改相关的IO口操作即可。
现在顺便也复习一下。
1602可以显示两行字符,每行可以显示16个字符,可惜的是不能显示中文,在我调试的时候它帮我不少的忙。
一、主要技术参数:显示容量:16X2个字符(两行,每行16个字符)模块工作电源:4.5~5.5V模块工作电流:2.0mA (5.0V)模块最佳工作电源:5.0V字符尺寸:2.95X4.35(WXH)mm二、IO引脚功能LCD1602A模块引脚功能编号符号引脚说明编号符号引脚说明1VSS电源地(模块供电)9D2Data I/O2VDD电源正极(模块供电) 10D3Data I/OVL接在滑动电阻可以调节对比度 11D4Data I/O4RS数据/命令选择端 (H/L)12D5Data I/O5R/W读/写选择端 (H/L)13D6Data I/O6E使能信号(通知芯片读取数据) 14Data I/O7D0Data I/O15BLA模块背光灯正极8D1Data I/O16BLK模块背光灯负极三、基本操作时序:读状态:输入:RS=L、RW=H、E=H模块输出:状态字=D0~D7写指令:输入:RS=L、RW=L、D0~D7=指令码、E=H 模块输出:无读数据:输入:RS=H、RW=H、E=H模块输出:数据=D0~D7写数据:输入:RS=H、RW=L、D0~D7=数据、E=H 模块输出:无状态字说明(因为单片机的速度可能快过1602,所以需要判断当1602是否在忙,或者延时。
)STA7STA6STA5STA4STA3STA2STA1STA0D7D6D5D4D3D2D1D0STA0-6:当前数据地址指针的数值STA7主要用来检查1602模块的是否可以写入或读出操作 1:禁止 0:允许四、指令说明(这指令是用来设置1602显示的方式)显示模式设置指令码功能111设置16X2显示,5X7点阵,8位数据接口显示开/关及光标设置指令码功能1DCBD=1 开显示D=0 关显示C=1 显示光标C=0 不显示光标B=1 光标闪烁B=0 光标不闪烁1NSN=1 当读或写一个字符后地址指针加1,且光标加1(即从左往右显示)N=0 当读或写一个字符后地址指针减1,且光标减1(即从右往左显示)S=1 当写一个字符,中国男排显示左移(N=1)五、时序图写操作(写指令、写数据)时序图时序参数写指令时序,RS拉低表示写指令,R/W拉低表示写操作,给DB0-DB7赋值指令数据并保持>;40ns时间,将E 拉高表示数据已经准备好保持>;150ns让1602读取,将E 拉低,并延时>;10ns一次写操作完毕。
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单片机控制负极更好。
用单片机的IO口去控制二极管的负极从而控制二极管。
IO复位后全部为输入工作方式内部上拉电阻无效,IO是三态高阻的状态IO工作时读取外部引脚的电平一定要用PINXN这个才是反应真正的电平AVR工作电源是5V灯泡的DDRA=0XFF PORTA=0X00LED灯管的DDRB=0XFF PORTB=0X00的时候量的开关的时候是DDRB=0X00 PORTB=0XFF 打开不闭合不导通当PORTB=0的时候导通让LED亮#include <avr/io.h>int main (void){DDRA=0xFF;DDRB=0xFF;PORTA=0xC0;PORTB=0xf7;while (1){}}#include<avr/io.h>#include<avr/delay.h>unsigned char digit[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};按键开关int main(void){DDRA=0xff;PORTA=0x00;DDRB=0xff;DDRD=0x00;PORTD=0xff;while (1){if((PIND^0xff)==4) {PORTA=0xF9; _delay_ms(1000);}elseif ((PIND^0xff)==8){ PORTA=0xA4; _delay_ms(1000);}elseif((PIND^0xff)==0x10) { PORTA=0xb0; _delay_ms(1000);}elseif((PIND^0xff)==0x20) {PORTA=0x99; _delay_ms(1000);}}}按键按一下后弹起#include<avr/io.h>#include<avr/delay.h>#define F_CPU 800000ULunsigned char digit[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};int main(void){DDRA=0xff;PORTA=0x00;DDRB=0xf8;DDRD=0X00;PORTD=0XFF;int i;while(1){if(~PIND&0x04) //保证其位为0{PORTA=digit[1];_delay_ms(100);}else PORTA=digit[0];}}第二部分 SPI通信第三部分数码管数码管由8段组成A B C D E F G P . 8 个连接在一起的发光二极管。
两种:共阳形共阴行。
驱动方式:静态驱动,动态驱动.静态:一个IO 端口控制一个数码管。
方便,耗电量大,占用资源多。
动态:一位一位动态点亮各个数码管。
每隔一段时间点亮一次。
占用资源少,不易控制。
8个段码加上几个位选。
几个位选代表几个数码管。
数码管驱动芯片:CH451,CH451可以驱动8个数码管或者64个发光二极管。
串行数据的输入顺序是低位在前,高位在后。
CH451有4个串行接口;4个:DIN DCLK LOAD DOUT .DIN(输入线)DCLK(时钟线)LOAD(加载线)是带上拉的输入信号线,默认是高电平。
DOUT 串行数据输出线。
第四部分引脚电源:VCC (电源)A VCC(模拟电源)GNDRESTE 外部复位脚单片机一般是低电平复位。
在RESTE上给一个低电平使其复位。
XTAL1 XTAL2 时钟CH451的扫描顺序为DIG0-DIG7 一个引脚吸入电流时,其他引脚不吸入电流。
降低扫描极限可以提高数码管的亮度。
CH451有8个8位的数据寄存器。
第五部分键盘(PD的高四位作为输出口低四位作为输入口列线作为输入端行线作为输出端)独立键盘:根据电平的不同来判断是否按下。
机械弹性触电开关。
按键抖动键盘的消抖硬件消抖:加入消抖电路(难度大)软件消抖:软件设计(第一次确认后经过10MS再确认按键是否按下)上拉电阻使能?(PORTXN=1 PUD=1 DDRXN=0)三个条件都满足时表示上拉电阻有效。
当PORTXN=0表示其上拉电阻无效。
矩阵键盘:反转法和逐行扫描矩阵(由行线列线构成)按键未按下时是高电平,按下变成低电平电平与信号一个键盘对应一个IO口IO 口有三态?上拉电阻逐行扫描法:确定有键按下:4行全部是低电平4列全部是高电平确定后确定哪个键按下依次将行线设置为低电平列线全部为高电平PA0-PA3控制行PA4-PA7控制列输出端是不变的如果输入端是低电平输出端为高电平输如端变为高电平程序#include <avr/io.h>#include <utile/delay.h>unsigned char read_key(void)unsigned char i,j,key_value=0xff;DDRD=0xf0;PORTD=0x0f;if((PIND&0x0f) return Oxff;else {delay_ms(5);if((PIND&0x0f)==0x0f) return 0xff;else{for (i=4;i<8;i++){PORTD=~(1<<i)|0x0f;for(j=0;j<4;j++){if((PIND&(1<<j)==0)key_value=(i-4)*4+j;}}return key_value;}}int main (){//}第六部分:中断中断:自动响应请求执行中断请求服务再回来。
优点:实时处理实现分时操作进行故障处理待机状态的唤醒几个概念:主程序中断源:可以发出单片机的CPU中断请求的部件和设备(分类:非屏蔽中断可屏蔽中断软件中断)中断请求信号:发出的申请信号中断标志:对应的不同中断标志位有不同的变化中断响应:停止现行程序转向中断服务程序中断服务程序:中断要做到事情转向断点:被打断的地方中断现场保护中断返回中断向量中断优先级(由硬件决定)中断嵌套响应A中断=全局中断标志中断A允许标志中断A标志(三个条件) 针对可屏蔽中断ATMEGE16共21个中断源每个中断向量占2个字(4个字节)中断响应过程:第一:全局允许中断位清0 禁止响应其它中断被响应的中断标志位清0 将中断的断点的地址压入堆栈自动将响应中断向量地址压入程序计数器(中断服务程序的入口地址)至少4个时钟周期中断返回的过程程序:几个寄存器MCUCR(ISC11ISC10)控制INT1(ISC01ISC00)控制INT0GICR(当它是1时开启中断)(中断使能寄存器)GIFR(外部中断标志器)#define F_CPU 7372800UL //定义时钟频率,保证delay函数的准确键盘中断#include<avr/io.h>#include<util/delay.h>#include<avr/interrupt.h>int num_tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示数字时对应的PA口信号void led_num(unsigned int num) //数字输出函数{unsigned char temp,i;for(i=0;i<4;i++){PORTB=0XFF;temp=num%10;PORTA=num_tab[temp];PORTB=~(1<<(3-i));_delay_us(20);num/=10;}}//中断SIGNAL(SIG_INTERRUPT0) //外部中断0所执行程序的内容{sei(); //开总中断PORTB=0X00;PORTA=0xf0;while(1);}SIGNAL(SIG_INTERRUPT1) //外部中断1所执行程序的内容{sei(); //开总中断PORTB=0X00;PORTA=0x0f;while(1);}void IO_init(void) //端口初始化{PORTA=0XFF;DDRA=0XFF;PORTB=0XFF;DDRB=0XFF;PORTC=0xff;DDRC=0xff;PORTD=0xff;DDRD=0x00;}void interrupt_init(void) //中断初始化{MCUCR=0X03; //中断0、1为上升沿产生中断请求,GICR=0xc0; //开中断0、1}int main(void){IO_init(); //端口初始化interrupt_init(); //中断初始化sei(); //开总中断unsigned int a,b;while(1){for(a=0;a<9999;a++){for(b=0;b<5000;b++)led_num(a); //输出信号}}}按键中断的起始条件:DDRA=0XFF;DDRB=0XFF;DDRD=0X00;PORTD=0XFF;中断函数SIGNAL(SIG_INTERRUPT0)void interrupt_init(void) //中断初始化{MCUCR=0X03; //中断0、1为上升沿产生中断请求,GICR=0xc0; //开中断0、1}计时器计数器定时计数器的长度 8位16位脉冲信号源外部引脚和内部提供计数器的类型 +1 -1上下限最小值最大值计数器的事件比较匹配中断2个八位一个16位的计数器主要是8位T/C01单通道计数器2比较匹配清0计数器3允许使用外部引脚410位的时钟分频器和频率发生器5溢出和比较匹配中断源6输出PWM信号中断方式:溢出中断比较中断时钟源外部时钟源同步采样电路边缘检测电路外部频率至少不能大于系统的 2.5分之一宽度大于一个系统时钟周期定时器的计数单元 +1 或者-1 或者清0比较匹配中断输出比较寄存器 TCNT OCRN 两者相等时输出中断标志位置为1 为什么有些是到255?定时器的工作模式:普通模式比较模式PWM模式TCNTO 记录初值输出比较寄存器OCROTIMSKTIFRTCCRO 控制寄存器调节工作模式用的是 WGM00 WGM01CS02 CS01 CS02 0选择时钟源1 1 0 下降沿触发1 1 1 上升沿触发void timer0_init() //计时器T0初始化{TCNT0 = 0;TCCR0 |= (1<<CS00)|(1<<CS02);//1024分频TIMSK |=(1<<TOIE0); //TO中断溢出允许}//ISR(TIMER0_OVF_vect)SIGNAL(SIG_OVERFLOW0) //T0中断溢出函数{n+=1;}两个独立的中断源:溢出中断TOVO 输出比较中断0CF0总结TCCRO T/C控制寄存器是用来控制信息源的类别和模式的TCNTO T/C寄存器OCRO 输出比较寄存器TIMSK T/C中断屏蔽寄存器TIFR 中断标志寄存器当TIMSK=0X01时是溢出中断当TIMSK=0X02时是比较中断中断标志寄存器是不用我们定义的电脑运行的时候中断执行会把它变为1中断使能的意思是这个中断可以运行.问:0CR0=0XFF的时候CTC模式等于普通模式.CTC与快速PWM的区别是两着的TOP不同,快速PWM模式改变波形:改变有效值(有效电压)快速PWM模式在比较匹配的时候电平变为0 达到最大值的时候(0XFF)变为10C0是在PB3上的打开这个端口是DDRB=0X04当有输出的时候要打开0CO不是所有的比较输出都要打开0C0的主要看要不要输出0CR0是那个比较的数值.TCO 八位计时器TC1十六位计时器使用内部时钟源计时使用外部时钟源用来计数{TCNTO=0X00;TCCRO=0X07;TIMSK|=(1<<TOIEO);}要发生中断要按255次1号按键 T0对应PB0 按键可以吗? PB0好像没有按键.在普通模式中当他完成溢出中断的时候他是返回原值还是0X00?0X00在CTC模式的时候是返回原值的。