单片机片上开发方法(ATmega16为例).ppt
2023/9/24,1,单片机片上开发方法(ATmega16为例),王 浩98ID:woot,SOC,2023/9/24,2,2023/9/24,3,你现在有这些麻烦吗?,我根本不知道怎么把单片机用在机器人上我在自学,而且找了书在看,但越看越乱我看了一些方案的实例,对机械部分和电路部分有感觉了,但就是不知道他们是怎样工作的我只会用仿真器,到现在还不知道如何把写好的程序“烧”进一片真实的单片机中只要和单片机有一点关系的电路我们就不敢设计,这让我们在写方案的过程中阻力很大。我学过C,但是不会用它写单片机的程序我到底是用汇编还是用C,2023/9/24,4,要解决麻烦,首先假设你,会使用电脑(比如安装WindowsXP的PC)已经学过或对C语言有一定的了解能看得懂一些简单的电路和元器件符号充满激情和渴望,而且有毅力和敢于动手,2023/9/24,5,我去电子市场买来一片单片机!,我能且只能这样看着它 数数它的腿,瞅瞅它上面的印字!,40引脚DIP封装,ATmega16L-8,ATmega16-16,或,2023/9/24,6,从DATASHEET中了解更多,ATMEL公司为他的所有单片机产品都提供了一份超级详细的datasheet说明书,而且对常用的系列进行了中文翻译,这将是我们接下来进行各种实验环节的第一手资料!,2023/9/24,7,从DATASHEET中了解更多,现在很多单片机内部有三种存储器:FlashEEPROMSRAM/RAM,存放程序和静态数据,单片机在工作过程中一般不能修改,一般不会使用,使用时通过特殊的命令读写,其特点是掉电不丢失,存放变量,特点是掉电丢失,2023/9/24,8,其实你还需要很多,最起码(如果想完成这里的最少一个实验的话),你还需要准备:一支电烙铁、电烙铁架子、一小卷含铅的0.8mm焊锡和一块足够大的万用焊接电路板一些单芯带绝缘皮的镀锡铜导线一个40DIP插座和几根杜邦排针8只1K的电阻和8只LED灯一根AVR的下载线(比如USBASP线)最好还有一个万用表,2023/9/24,9,USBASP下载线,CC98上有人在做:,2023/9/24,10,下载一个开发资料包(woot整理),AVR_DEV.rar解压后,请关注论坛,即时会挂在临时ftp上并给出连接,2023/9/24,11,做好心理准备,接下来我们将为mega16单片机搭建一个最基本的电路,可以称它为一个“最小系统”,这个系统只能向单片机中下载程序并让其开始工作,然后我们会按照实验的顺序逐渐增加并完善这个系统,并让它最终成为SLOWLY机器人的一个标准系统。在这个过程中,我们会边讲、边试,不知不觉中学会使用datasheet,学会在Windows上开发平台的搭建、单片机C语言编程基础、程序的下载、延时程序、LED点灯程序、I/O操作、PWM功能、定时器功能、A/D功能等片上功能的使用,2023/9/24,12,ATmega16单片机的管脚排列,PB0PB1PB2PB3PB4PB5PB6PB7RESETVCCGNDXTAL2XTAL1PD0PD1PD2PD3PD4PD5PD6,PA0PA1PA2PA3PA4PA5PA6PA7AREFGNDAVCCPC7PC6PC5PC4PC3PC2PC1PC0PD7,2023/9/24,13,从datasheet上快速知道管脚定义,AVR_DEVdatasheetcn_mega16-16L.pdf的第2页(P2),2023/9/24,14,搭建ATmega16的“最小系统”,(MOSI)PB5(MISO)PB6(SCK)PB7RESETVCCGND,GNDAVCC,2023/9/24,15,建议的“最小系统”,(MOSI)PB5(MISO)PB6(SCK)PB7RESETVCCGNDXTAL2XTAL1,AREFGNDAVCC,USBASP下载头,插座(板子正面),VCC,GND,MOSI,MISO,SCK,RESET,+5V,+5V,104,22pF,22pF,8MHz,4K7,+10uF,+5V,RESET,XTAL2,XTAL1,100,2023/9/24,16,增加8个LED灯用来指示,(MOSI)PB5(MISO)PB6(SCK)PB7RESETVCCGNDXTAL2XTAL1,AREFGNDAVCCPC7PC6PC5PC4PC3PC2PC1PC0,USBASP下载头,插座(板子正面),VCC,GND,MOSI,MISO,SCK,RESET,+5V,+5V,104,22pF,22pF,8MHz,4K7,+10uF,+5V,RESET,XTAL2,XTAL1,LED,1K,100,2023/9/24,17,实验1:让8个LED灯闪烁,安装ICC编译器编写让8个LED灯闪烁的程序安装USBASP下载线驱动使用USBASP给mega16下载写好的程序更改mega16的熔丝位,2023/9/24,18,安装ICC编译器,双击AVR_DEVICCAVR7.13CSetup.exe,之后的图片使用ICC6.31A安装时的界面,ICC7.13的界面与其相似,2023/9/24,19,2023/9/24,20,2023/9/24,21,2023/9/24,22,C:iccv7avr,2023/9/24,23,2023/9/24,24,2023/9/24,25,2023/9/24,26,2023/9/24,27,2023/9/24,28,安装ICC编译器,将AVR_DEVICCAVR7.13CICC.exe文件复制到C:iccv7avrbin目录下面。,这里是默认的目录,根据你的安装情况使用安装时设置的目录。,以后,我们可以通过双击这个文件运行ICC,可不受其30天试用期限制,但仅限于自己学习,不能用于其它用途!,2023/9/24,29,运行ICC,使用刚才的ICC.exe运行ICC7.13,2023/9/24,30,ICC的界面,2023/9/24,31,新建一个工程,Project New,2023/9/24,32,新建一个工程,建议先建立一个文件夹,如LED_test,2023/9/24,33,新建一个工程,在建立的LED_test文件夹内建立LED_project.pro文件,如图点击“保存(S)”,2023/9/24,34,2023/9/24,35,在工程中建立一个LED.c文件,File New,2023/9/24,36,2023/9/24,37,在工程中建立一个LED.c文件,File Save As,2023/9/24,38,在工程中建立一个LED.c文件,在刚建立的LED_test文件夹内保存成LED.c,2023/9/24,39,将LED.c添加到工程中,File(右击)Add File(s),2023/9/24,40,将LED.c添加到工程中,选中刚才建立的LED.c文件,打开(O),2023/9/24,41,将LED.c添加到工程中,LED.c就成功添加到LED_project中了,2023/9/24,42,我们将会在这个区域里用C语言写一个LED闪烁的程序,2023/9/24,43,在开始之前,设置ICC,使其配置成为可以开发ATmega16的编译器环境,2023/9/24,44,设置你的ICC,Project Options,2023/9/24,45,设置你的ICC,如图在Target标签中的Device Configuration里选择ATmega16单片机,点击OK即可,2023/9/24,46,书写程序,程序将会被写到这里,如果你是第一次使用,不妨先把下一页PPT提供的写好的程序复制到这里,熟悉一下流程先,2023/9/24,47,写好的程序,#include#include#include void InitPorts(void)DDRC=0 xFF;PORTC=0 xFF;void delay_us(unsigned int time)do time-;while(time1);void delay_ms(unsigned int time)while(time!=0)delay_us(1000);time-;void main(void)InitPorts();delay_ms(50);while(1)PORTC=0 x00;delay_ms(500);PORTC=0 xFF;delay_ms(500);,2023/9/24,48,LED灯闪烁程序解释,#include/此头文件包含了ATmega16的口位定义等#include/此头文件包含了AVR系列通用口位定义等#include/*此头文件是C语言的标准头文件,在这里不写是没关系的*/,2023/9/24,49,LED灯闪烁程序解释,/端口初始化函数void InitPorts()/*7654 3210*/DDRC=0 xFF;/PC口定义为输出 PORTC=0 xFF;/PC口置1(也叫“拉高”)/1111 1111,2023/9/24,50,LED灯闪烁程序解释,/*8MHz晶振下*/微秒级延时函数void delay_us(unsigned int time)do time-;while(time1);/毫秒级延时函数void delay_ms(unsigned int time)while(time!=0)delay_us(1000);time-;,2023/9/24,51,LED灯闪烁程序解释,void main(void)/主程序 InitPorts();/端口初始化 delay_ms(50);/延时一下,保证外部电路稳定 while(1)/进入一个死循环 PORTC=0 x00;/C口的LED灯点亮 delay_ms(500);/延时500ms PORTC=0 xFF;/C口的LED灯熄灭 delay_ms(500);/延时100ms,2023/9/24,52,编译,Build Project,2023/9/24,53,编译,成功,2023/9/24,54,编译后的文件,2023/9/24,55,把程序写入mega16单片机,安装USBASP下载线驱动使用USBASP给mega16下载写好的程序,2023/9/24,56,安装USBASP下载线驱动,设置USBASP下载线的跳线跳线说明:+5V:连接时将通过USB接口为目标板供电。updata:连接时可以给USBasp进行固件升级(一般不使用)。这里我们连接+5,断开updata,+5V,updata,2023/9/24,57,安装USBASP下载线驱动,给USBASP插上下载排线黑色插头有突起的一侧对着板子上有白色方框的这一侧插入,2023/9/24,58,安装USBASP下载线驱动,先下载USBasp驱动:可以在CC98代理处下载也可以在AVR_DEVprogisp167USB-Drive下找到驱动不能直接双击安装,先把USBASP下载线插入电脑的USB口,2023/9/24,59,安装USBASP下载线驱动,电脑显示屏自动弹出下列提示框,用鼠标点击选择“是,仅这一次(Y)”,然后点击“下一步(N)”,2023/9/24,60,安装USBASP下载线驱动,当计算机屏幕显示下列提示框后,点击选择“从列表或指定位置安装(高级)(S)”,再点击“下一步(N)”,2023/9/24,61,安装USBASP下载线驱动,屏幕出现下列提示框,点击“浏览(R)”选择USBASP驱动文件所在的文件夹(USBasp-Drive),然后点击“下一步(N)”,2023/9/24,62,安装USBASP下载线驱动,2023/9/24,63,安装USBASP下载线驱动,2023/9/24,64,安装USBASP下载线驱动,2023/9/24,65,使用progisp167下载软件,progisp167 是一个免费绿色软件,就在AVR_DEVprogisp167目录下,双击progisp.exe就能运行软件,2023/9/24,66,使用progisp167下载软件,(1),(2),(3),依次选择好如图设置,ATmega16,USBASP,usb,2023/9/24,67,注意下载线另一头与单片机的连接,(MOSI)PB5(MISO)PB6(SCK)PB7RESETVCCGNDXTAL2XTAL1,AREFGNDAVCCPC7PC6PC5PC4PC3PC2PC1PC0,USBASP下载头,插座(板子正面),GND,VCC,MOSI,MISO,SCK,RESET,+5V,+5V,104,22pF,22pF,8MHz,4K7,+10uF,+5V,RESET,XTAL2,XTAL1,LED,1K,100,2023/9/24,68,使用progisp167下载软件,点击“调入Flash”,(4),点击“打开”,2023/9/24,69,使用progisp167下载软件,设置好编程方式,然后点击“自动”,(5),2023/9/24,70,使用progisp167下载软件,说明程序已经下载成功了!,2023/9/24,71,为什么会这样?,LED灯闪烁得很慢,好像根本不是1秒一次!中间的4个LED灯根本就没有被点亮过!,2023/9/24,72,设置ATmega16的熔丝位,原因很有可能出在“熔丝位”上!,2023/9/24,73,设置ATmega16的熔丝位,新手可能根本就看不懂,下面点“向导方式”,2023/9/24,74,设置ATmega16的熔丝位,钩选,不选,不选,2023/9/24,75,设置ATmega16的熔丝位,设置好熔丝位,然后点击“写入”,如果成功,这里会提示,2023/9/24,76,所有的LED灯都按照1s的节拍闪烁起来!,2023/9/24,77,端口初始化命令,DDRA=0 xF0;对端口A初始化,高4位作为输出(1),低4位作为输入(0),注:金黄色字体部分表示可以根据情况更改,2023/9/24,78,写端口命令,PORTA=0 x0F;将端口A的8个I/O口写为0000 1111,0表示I/O口拉低,1表示I/O口拉高。,注:只有在A口相应的I/O口位被定义为输出时才有实际作用,2023/9/24,79,写端口命令,P=PINA;读出端口A的8个I/O口上的高低电平状态,1表示高电平,0表示低电平,将其赋给P,P是无符号字节型变量(unsigned char P;),注:只有在A口相应的I/O口位被定义为输入时才有实际作用,2023/9/24,80,I/O操作应用举例,LED指示灯,unsigned char P;P=PINB;/B口值给PPORTC=P;/*C口按照P的值输出。*/,DDRB=0 x00;/B口输入DDRC=0 xFF;/C口输出,AVR ICC程序,2023/9/24,81,I/O口的一种位操作实现方法,/输出端口位操作(1为拉高,0为拉低)#define set_bit(x,y)(x|=(1y)/将x端口的第y位设置成1/*例:*/set_bit(PORTB,0)#define clr_bit(x,y)(x&=(1y)/将x端口的第y位设置成0/*例:*/clr_bit(PORTB,0),2023/9/24,82,I/O口的一种位操作实现方法,/输入端口位操作(1为高电平,0为低电平)#define get_bit(x,y)(x,2023/9/24,83,实验2:使用ATmega16的ADC,将ATmega16的PA7(ADC7)口与一个光电开关连接,打开A/D转换,并用LED指示灯指示转换的高八位结果。,2023/9/24,84,实验2:使用ATmega16的ADC,电路连接(在第16张“最小系统”基础上),+5V,ADC7,100,500,56K,2023/9/24,85,与ADC相关的寄存器,Datasheet P7,Datasheet P203,Datasheet P205,2023/9/24,86,与ADC相关的寄存器,Datasheet P206,2023/9/24,87,ICC程序(ADC),完整程序见备注,void ADC_init(void)/ADC初始化 ADMUX|=(1ADLAR);/ADC结果左对齐 ADCSRA|=(1ADPS2)|(0ADPS1)|(1ADPS0);/ADC时钟=clk/32 ADCSRA|=(1ADEN);/ADC使能void ADC_work(void)/8路共需要0.8ms左右 unsigned char i=0;for(i=0;i8;i+)ADMUX/读取本路转换结果,只读高8位,2023/9/24,88,实验3:使用ATmega16的PWM(上),使用ATmega16的PWM对电机进行调速,2023/9/24,89,L298N电机控制电路,PB4PB5PB6PB7,OC0OC2,2023/9/24,90,L298N真值表(以一个H桥为例),2023/9/24,91,ATmega16与PWM相关的寄存器,Datasheet P7,TCCR0OCR0TCCR2OCR2,Datasheet P78,Datasheet P80,Datasheet P119,Datasheet P121,TCCR1ATCCR1BOCR1AOCR1B,Datasheet P102,Datasheet P105,Datasheet P106,Datasheet P106,2023/9/24,92,ICC程序(PWM上),void pwm02_init(void)/PWM初始化/*OC0的PWM初始化*/TCCR0=0 x00;TCCR0|=(1WGM01)|(1WGM00);/选择快速PWM方式 TCCR0|=(1COM01)|(0COM00);/PWM左对齐 TCCR0|=(0CS02)|(1CS01)|(1CS00);/clk/64分频 OCR0=0;/OCR0的值:0255用来控制占空比,初值为0/*OC2的PWM初始化*/TCCR2=0 x00;TCCR2|=(1WGM21)|(1WGM20);/选择快速PWM方式 TCCR2|=(1COM21)|(0COM20);/PWM左对齐 TCCR2|=(0CS22)|(1CS21)|(1CS20);/clk/64分频 OCR2=0;/OCR2的值:0255用来控制占空比,初值为0,完整程序见备注,2023/9/24,93,实验4:使用ATmega16的PWM(下),使用ATmega16的PWM控制舵机,|黄|红|黑|PWMVccGND,OC1A,2023/9/24,94,舵机控制原理,2023/9/24,95,ICC程序(PWM下),void pwm1_init(void)/PWM初始化/控制寄存器设置 TCCR1A=0 x00;TCCR1B=0 x00;TCCR1B|=(0WGM13)|(1WGM12);TCCR1A|=(1WGM11)|(1WGM10);/选择成10位快速PWM模式 TCCR1A|=(1COM1A1)|(0COM1A0);/PWM1A左对齐 TCCR1A|=(1COM1B1)|(0COM1B0);/PWM1B左对齐 TCCR1B|=(0CS12)|(1CS11)|(1CS10);/clk/64分频,Fpwm=0 x7A OCR1A=197;/比较匹配1A赋初值,让右舵机回到初始状态 OCR1B=175;/比较匹配1B赋初值,让左舵机回到初始状态/0.5ms-6.1%-62/1.5ms-18.3%-187/2.5ms-30.5%-312,完整程序见备注,2023/9/24,96,Flash常量与SRAM变量,使用#pragma data:code 可以将以后的常量申请到Flash存储器中。使用#pragma data:data 可以将以后的变量申请到SRAM存储器中。,#pragma data:code const unsigned char numC=0 xF1,0 xB2,0 xA1,0 x27;#pragma data:dataunsigned char hs=0,m=0,h=0;,