案例2单片机最小系统设计用户名:stu密码:stu2014.9.18单片机最小系统设计步骤•硬件设计–工具软件:AltiumDesigner、DXP•软件设计–工具软件:KeiluVision•调试–万用表–示波器最小系统-硬件单元电路•电源及其指示灯电路•晶振电路•复位电路•ROM启动选择电路•下载接口电路•独立按键电路•发光二极管电路等电源及其指示灯电路电源接插件XH2.54KF2510KF7.62HT5.08DC电源插座压线钳发光二极管5mm、3mm直径贴片发光管060308051206电阻1/4W立式电阻(碳膜、金属膜)贴片电阻热敏电阻压敏电阻晶振电路•时钟:定时与控制部件–晶振和电容组成的并联谐振回路。–晶振:1.2MHz~12MHz之间选择(典型:6M、12M、11.0592M)–电容:瓷片电容5~30PF•调试单片机最小系统时,可用示波器测晶振波形(正弦信号)来判断CPU是否已工作(正弦波)无源有源瓷片电容8051周期•振荡周期:指振荡源的周期(石英晶体的振荡周期)•时钟周期:(称S周期)为振荡周期的2倍•机器周期:一个机器周期含6个时钟周期,即12个振荡周期。•指令周期:完成一条指令占用的全部时间。805l的指令周期含1-4个机器周期•机器周期:T=12/fosc•若fosc=6MHz,则805l的:振荡周期=1/6us;时钟周期=1/3us;机器周期=2us;指令周期=2~8us。复位电路•为什么要复位?–单片机死机时,需要复位;–复位后CPU从地址0000H开始执行程序。•怎么复位?–在RST输入端出现高电平时实现复位和初始化。复位时RST引脚至少保持一定时间的高电平-高电平持续24个振荡周期以上(6MHz-4us)。–当RST引脚返回低电平以后,CPU从地址0000H开始执行程序,复位时晶振上无信号。6*6*5mm微动按钮12*12*7mm微动按钮复位电路•复位电路–上电复位(R=10k,C=10uFt=RC=100ms)–手动复位–看门狗自动复位看门狗监控复位电路•IMP705/706/813L为带看门狗μP监控电路。程序中要对813“喂狗”,若1.6秒内没有“喂狗”信号(P1.0),则813会自动产生信号对CPU复位。8051存储器系统•存储器分类–ROM:程序存储器,放代码•AT89S51片内(4K)•片外最大64K(0000H~FFFFH)–RAM:数据存储器,放数据•AT89S51片内(256字节)•片外最大64K(0000H~FFFFH)•8051的ROM与RAM采用独立编址(地址会出现重叠)•系统是通过控制信号–PSEN#(ROM编程选择使能)–RD#(RAM读控制)–WR#(RAM写控制)–来区分对ROM还是RAM的操作ROM启动选择电路•AT89S51单片机片内含4KFlashROM–地址范围:000H~3FFH•片外亦可扩展到最大64K的ROM–地址范围:0000H~FFFFH•8051单片机系统是从0H地址处开始运行的,因此8051单片机设置了EA#(ExternalAddress外部地址)选通控制位–EA#=0:用外部ROM启动–EA#=1:用内部ROM启动ROM(程序存储器)•ROM保留地址•其它ROM地址RAM(随机存储器)•低128字节(00H~7FH)–RAM区•高128字节(80H-FFH)–特殊功能寄存器(SFR)的区–8051有21个特殊功能寄存器,其它是预留,不能用于存储数据–具体见下页805121个特殊功能寄存器(SFR)符号地址注释符号地址注释*ACCE0H累加器*P3B0H通道3*BF0H乘法寄存器PCON87H电源控制及波特率选择*PSWD0H程序状态字*SCON98H串行口控制器SP81H堆栈指针SBUF99H串行数据缓冲器DPL82H数据存储器指针(低8位)*TCON88H定时器控制DPH83H数据存储器指针(高8位)TMOD89H定时器方式选择*IEA8H中断允许控制器TL08AH定时器0低8位*IPD8H中断优先控制器TL18BH定时器0高8位*P080H通道0TH08CH定时器1低8位*P190H通道1TH18DH定时器1高8位*P2A0H通道2*:表示该SFR可以位寻址8051单片机程序下载•编程器方式•ISP–InSystemProgram–在系统编程•IAP–InApplicationProgram–在应用编程:通过RS232、CAN、以太网等ISP下载接口电路ByteBlasterII并口下载实验室台式机参阅\Isplay1.3\ISPlay使用手册.pdfAVRISPUSB下载学生笔记本参阅\progisp168\USB-ASP使用说明.docFC10P压线头DC10P简易牛角座IDC压线钳输入检测电路1-独立按键电路高电平有效低电平有效输入检测电路2-大信号输入•工程应用中,很多开关量输入信号为12V或24V,要传入MCU,应将对应信号转换成MCU的匹配电平,可采用电阻分压或光耦方式实现,具体电路见下:电路1:电阻分压电路(74HC14:六施密特反相器)输入检测电路2-大信号输入•若输入信号为12V或24V的开关信号,要传入MCU,应将对应信号转换成MCU的匹配电平,可采用电阻分压或光耦方式实现,具体电路见下:电路2:光耦电路开关量输出控制电路1-发光二极管电路上拉接法(典型)低电平驱动下拉接法高电平驱动开关量输出控制电路2-大信号输出•工业现场的开关量通常是12V或24V,而MCU输出一般为5V或3.3V,因此需要加驱动电路。具体方法可采用三极管或集成达林顿管驱动。继电器驱动电路开关量输出控制电路2-大信号输出•工业现场的开关量通常是12V或24V,而MCU输出一般为5V或3.3V,因此需要加驱动电路。具体方法可采用三极管或集成达林顿管驱动。达林顿管驱动8051I/O口•8051单片机有4组8位–P0–P1–P2–P3•每个端口–可作为输入或输出–字节操作–位操作(位寻址)•部分端口除I/O功能外的第二功能–P0•AD7~AD0•低8位地址总线/8位数据总线分时复用–P2•A15~A8•高8位地址总线–P3•RXD、TXD、INT0#、INT1#•T0、T1、WR#、RD#8051I/O读写操作•字节操作–#include“reg51.h”//sfrP1=0x90;–读字节•unsignedchara;•a=P1;//读8位•a=P1&0x01;//读1位•a=P1&0x0f;//读4位–写字节•P2=0x01;//写8位常量•P2=a[i];//写8位数组元素•P2=P2|0x01;//对P2.0置1•P2=P2&0x0f;//对P2高4位清0,低4位保持不变•位操作–sbitP1_0=P1^0;//必须先定义位–读位•bdatamy_byte=0x20;•sbitmy_bit=my_byte^0;•或bitmy_bit=0x00;•my_bit=P1_0;•if(my_bit==1){;}•if(P1_0==1){;}–写位•P1_0=1;P1_0=0;P1_0=~P1_0;端口输出控制-字节操作方式•#includereg51.h•#defineDELAY1000•voiddelay(unsignedintn)•{•unsignedinti;•for(i=0;in;i++)•;•}•voidmain()•{•P2=0x7f;•delay(DELAY_1S);•P2=0xBf;•delay(DELAY_1S);•P2=0xDf;•delay(DELAY_1S);•P2=0xEf;•delay(DELAY_1S);•P2=0xF7;•delay(DELAY_1S);•P2=0xFB;•delay(DELAY_1S);•P2=0xFD;•delay(DELAY_1S);•P2=0xFE;•delay(DELAY_1S);•}问题:1、8状态完成后程序结束,应该加死循环while(1);2、低电平有效时,16进制数据书写较繁琐,可采用位取反“~”实现;3、8组语句可采用通过数组,用循环实现,以简化程序。具体方法见下页端口输出控制-字节操作方式•while内嵌for语句•voidmain()•{•unsignedchard[8]={0x80,0x40,0x20,0x10,•0x08,0x04,0x02,0x01};•unsignedchari;•while(1)•{•for(i=0;i8;i++)•{•P2=~d[i];•delay(DELAY_1S);•}•}•}•while内嵌if语句•voidmain()•{•unsignedchard[8]={0x80,0x40,0x20,0x10,•0x08,0x04,0x02,0x01};•unsignedchari;•i=0;•while(1)•{•P2=~d[i];•delay(DELAY_1S);•i++;•if(i==8)•i=0;•}•}问题:1、程序中数组d与变量i为什么要用unsignedchar类型定义?2、左右程序执行一次while循环各用多少时间?采用哪种方式更好?为什么?3、若要改变循环移动方向,程序应如何修改?端口输出控制-字节操作方式•循环左移改为循环右移•voidmain()•{•unsignedchard[8]={0x80,0x40,0x20,0x10,•0x08,0x04,0x02,0x01};•unsignedchari;•i=0;//i=7;•while(1)•{•P2=~d[i];•delay(DELAY_1S);•i++;//i--;•if(i==8)//if(i==-1)•i=0;//i=7•}•}•观察Proteus仿真效果•voidmain()•{•unsignedchard[8]={0x80,0x40,0x20,0x10,•0x08,0x04,0x02,0x01};•chari;•i=7;•while(1)•{•P2=~d[i];•delay(DELAY_1S);•i--;•if(i==-1)•i=7;•}•}问题原因:1、unsignedchari;i是不可能为负的,因此应修改为chari;端口输出控制-位操作方式•注意sbit定义位–必须在源程序的上方–必须在函数外•该程序的最终执行效果如何?•显然本例用字节方式输出更方便端口输入检测-字节操作方式•voidmain()•{•while(1)•{•if(P1&0x01==0)//S0按下•{•//循环左移•}•elseif(P1&0x02==0)//S1按下•{•//循环右移•}••}•}•8051输入–S0(P1.0)–S1(P1.1)–有效电平:低电平,即只要判断P1.0、P1.1是否为低电平即可•字节输入方式判断存在的问题:关系运算符(==)比位与运算符(&)的优先级高端口输入检测-位操作方式•voidmain()•{•while(1)•{•if(S0==0)//S0按下•{•//循环左移•}•elseif(S1==0)//S1按下•{•//循环右移•}••}•}•8051输入,首先定义–sbitS0=P1^0;//位定义–sbitS1=P1^1;//位定义–有效电平:低电平,即只要判断P1.0、P1.1是否为低电平即可•位输入方式判断对于按键判断,显然位方式输入更简单延时1秒实现•#defineDELAY_1S10000–采用宏定义设置1S延时常数,根据实际运行效果改变其值,达到粗略的运行效果。•延时函数定义voiddelay(unsignedintn){unsignedinti;for(i=0;in;i++);}–其形参数值范围为0~65535,采用循环空语句方式实现延时。•延时函数调用delay(DELAY_1S);//延时最小系统-软件设计•编辑、编译、连接–软件:KeiluVision–编辑:.c–编译:.obj–连接:.hex–详细步骤参阅《单片机技术实验指导书(基础部分-第5版_2015.3)》•运行:下载