Proteus仿真单片机实例
基于Proteus的单片机设计仿真

第三, 实例的难度要由浅入深、 循序渐进, 并呈
础。 教学实践证明, VB 是一 门 集 知 识 和 技 能 于 一 体 、 现出一定的梯度。
逻辑分析和实践操作都很强的课程, 且由于教学内容
总之, 实例要以教学的内容为依据, 以现实的对
枯燥、 难懂, 学生学起来非常困难, 甚至会产生放弃 象为材料, 既要包含基本的教学知识点, 又要调动学
·职 业 教 育
2009年1月 总第138期
149
览对象方位控制按钮、 仿真进程控制按钮、 预览窗口、 对象选择器窗口、 图形编辑窗口等。
标 (不用拖动), 将鼠标的指针靠近另一个元件的连接 点时, 接着鼠标的指针就会又出现一个 “×” 号, 表明 找到了该元件的连接点, 同时屏幕上出现了粉红色的 连接, 单击鼠标左键, 粉红色的连接线就变成了深绿 色, 该条连线绘制完成。 再用同样的方法绘制其他连 接线, 电路原理图的编辑就完成了。 如图 4 所示。
图 3 元件选择窗口 在 “Results” 的列表项中 , 双击 “AT89C51”, 则 可 将 “AT89C51” 添 加 至 对 象 选 择 器 的 窗 口 中 。 用 同 样的方法将 “CD4094” 和 “led-bargraph-red” 添加至 对象选择器窗口, 单击 “OK” 按钮, 结束对象选择。 经过以上操作, 在对象选择器窗口中, 已有了 CD4094、 AT89C51、 led-bargraph-red 这三个元器件对 象。 在对象选择器的窗口中, 选中 CD4094, 将鼠标置 于图形编辑窗口该对象的欲放位置、 单击鼠标左键, 从而完成放置。 同理, 将 AT89C51 和 led-bargraph-red 放置到图形编辑窗口中。 接下来, 用导线连接各接点: Proteus 的 智 能 化 可 以在你想要画线的时候进行自动检测。 当鼠标的指针 靠近元件的连接点时, 跟着鼠标的指针就会出现一个 “×” 号, 表明找到了连接点; 单击鼠标左键, 移动鼠
基于Proteus的单片机系统的仿真设计

如 模 拟 分 析 、 字 分析 、 合 信 号 分 析 、 率 分 析 等 有 各种 虚 拟 数 混 频
仪器 , 如示 波 器 、 辑 分 析 仪 、 号 发 生 器 、 数 器 、 表 等 。 和 可 简 化单 片机 程序 在 目标 硬 件 上 的调 试 工 作 .加 快 工 程 项 目的 逻 信 计 电 能 K i Ma a e , f b等 编 译 软 件 整 合 使 用 。 到 更 好 的 仿 真效 果 。 仿 真 开 发 过 程 , 低 开 发 成 本 。 需 要 注 意 的 是 , 真 不 能 完 全 代 替 实 l l 达 该 降 仿
空航 天 大 学 出版社 . 0 . 2 6 0 3 王锋 . 于 P oe s 数 字 时 钟 设 计 与 仿 真 卟 福 建 电 脑 ,0 91 : 5 . 基 rtu 的 2 0 ,01 - 3
1 6 3 .
4王 瑞 萍 . 于 Poe s 单 片 机 虚 拟 开 发 环 境 o. 代 电 子 技 术 , 0 ,: . 基 rtu 的 】现 2 98 0
16 4
福
建 电
脑
21 0 0年 第 6期
基 于 Po u 的 单 片 机 系统 的仿真 设计 rt s e
刘 艳 ,张 文 超 ,秦 鑫
(新 乡 医 学 院生 命 科 学技 术_ 河 南 新 乡 4 3 0 系 5 0 31 【 摘 要 】 介 绍 了利 用 P o u 开 发 单 片机 系 统 的 仿 真 设 计 方 法 。基 于 Po u 的 单 片 机 虚 拟 开 发 环 境 可 以 完 成 单 片 : rt s e rt s e
l i是 德 国 K i公 司 开发 的单 片机 编译 器 .是 一 种 集 成 化 (l e e l 参考文献: . 沈 郭 8 1单 片机 实 践 与 应 用 [ . 京 : 华 大学 0 M】北 清 的 文 件 管 理 编 译 环 境 , 编 辑 、 译 和 程 序 仿 真 等 于 一 体 。 用 1昊 金 戌 , 庆 阳春 , 庭 吉 . 5 集 编 可
仿真单片机c语言程序设计实训100例 基于pic proteus仿真

仿真单片机c语言程序设计实训100例基于pic proteus
仿真
单片机上使用C语言进行程序设计的基本步骤和要点:
1. **理解硬件**:在开始编程之前,你需要对单片机的硬件有深入的理解。
这包括它的内存结构,输入/输出端口,以及任何特定的硬件特性。
2. **选择开发环境**:有很多可用的单片机开发环境,如Keil、IAR Embedded Workbench等。
这些环境都支持C语言编程,并且提供了编译、调试等功能。
3. **编写代码**:在理解了硬件和开发环境之后,就可以开始编写代码了。
这可能包括配置IO端口,读写内存,以及控制单片机的各种功能。
4. **编译代码**:在大多数开发环境中,你都可以直接编写和编译代码。
编译过程会将你的C代码转换成单片机可以执行的机器码。
5. **调试代码**:这是整个开发过程中最重要的一步。
你可以使用开发环境提供的调试工具来检查你的代码是否按照预期工作。
这可能包括查看变量的值,单步执行代码,以及使用断点等。
6. **仿真和测试**:在真实硬件上测试代码之前,你可以使用仿真软件(如Proteus)来模拟你的代码的行为。
这可以帮助你发现和修复一些在真实硬件上可能无法发现的错误。
7. **在真实硬件上测试**:最后,当你的代码在仿真环境中运行正常后,你就可以将其烧录到真实硬件上进行了。
以上就是在单片机上使用C语言进行程序设计的基本步骤和要点。
不过请注意,由于具体的硬件和开发环境可能会有所不同,因此具体的步骤可能会有所不同。
《单片机C语言程序设计实训100例—基于8051+Proteus仿真

《单片机C语言程序设计实训100例—基于8051+Proteus仿真》案例第01 篇基础程序设计01 闪烁的LED/* 名称:闪烁的LED说明:LED按设定的时间间隔闪烁*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P1^0;//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){while(1){LED=~LED;DelayMS(150);}}02 从左到右的流水灯/* 名称:从左到右的流水灯说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){P0=0xfe;while(1){P0=_crol_(P0,1); //P0的值向左循环移动DelayMS(150);}}03 8只LED左右来回点亮/* 名称:8只LED左右来回点亮说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;P2=0x01;while(1){for(i=0;i<7;i++){P2=_crol_(P2,1); //P2的值向左循环移动DelayMS(150);}for(i=0;i<7;i++){P2=_cror_(P2,1); //P2的值向右循环移动DelayMS(150);}}}04 花样流水灯/* 名称:花样流水灯说明:16只LED分两组按预设的多种花样变换显示*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code Pattern_P0[]={0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe, 0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};uchar code Pattern_P2[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;while(1){ //从数组中读取数据送至P0和P2口显示for(i=0;i<136;i++){P0=Pattern_P0[i];P2=Pattern_P2[i];DelayMS(100);}}}05 LED模拟交通灯/* 名称:LED模拟交通灯说明:东西向绿灯亮若干秒,黄灯闪烁5次后红灯亮,红灯亮后,南北向由红灯变为绿灯,若干秒后南北向黄灯闪烁5此后变红灯,东西向变绿灯,如此重复。
单片机C语言程序设计实训100例--基于8051+PROTEUS仿真1

《单片机C说话程序设计实训100例—基于8051+Proteus仿真》案例第 01 篇基本程序设计01 闪耀的LED/* 名称:闪耀的LED解释:LED按设定的时光距离闪耀*/#include<reg51.h>#define uchar unsignedchar#define uint unsigned intsbit LED=P1^0;//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}//主程序void main(){while(1){LED=~LED;DelayMS(150);}}02 从左到右的流水灯/* 名称:从左到右的流水灯解释:接在P0口的8个LED从左到右轮回依次点亮,产生走马灯后果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x)uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){P0=0xfe;while(1){P0=_crol_(P0,1); //P0的值向左轮回移动DelayMS(150);}}03 8只LED阁下往返点亮/* 名称:8只LED阁下往返点亮解释:程序运用轮回移位函数_crol_和_cror_形成往返滚动的后果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;P2=0x01;while(1){for(i=0;i<7;i++){P2=_crol_(P2,1); //P2的值向左轮回移动DelayMS(150);}for(i=0;i<7;i++){P2=_cror_(P2,1); //P2的值向右轮回移动DelayMS(150);}}}04 名堂流水灯/* 名称:名堂流水灯解释:16只LED分两组按预设的多种名堂变换显示*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code Pattern_P0[]={0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0 xff,0xff,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0 xc3,0xe7,0xff,0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0 x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0 x0f,0xf0,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff,0xff,0 xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef,0xf7,0 xfb,0xfd,0xfe,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xf0,0 xf8,0xfc,0xfe,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};uchar code Pattern_P2[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf9,0xf3,0xe7,0xcf,0 x9f,0x3f,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0 xc3,0xe7,0xff,0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0 x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0 x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0 xdf,0xbf,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0 xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0 xc0,0x80,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0 xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;while(1){ //从数组中读取数据送至P0和P2口显示for(i=0;i<136;i++){P0=Pattern_P0[i];P2=Pattern_P2[i];DelayMS(100);}}}05 LED模仿交通灯/* 名称:LED模仿交通灯解释:器械向绿灯亮若干秒,黄灯闪耀5次后红灯亮, 红灯亮后,南北向由红灯变成绿灯,若干秒后南北向黄灯闪耀5此后变红灯,器械向变绿灯,如斯反复.*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit RED_A=P0^0; //器械向灯sbit YELLOW_A=P0^1;sbit GREEN_A=P0^2;sbit RED_B=P0^3; //南北向灯sbit YELLOW_B=P0^4;sbit GREEN_B=P0^5;uchar Flash_Count=0,Operation_Type=1; //闪耀次数,操纵类型变量//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//交通灯切换void Traffic_Light(){switch(Operation_Type){case 1: //器械向绿灯与南北向红灯亮RED_A=1;YELLOW_A=1;GREEN_A=0;RED_B=0;YELLOW_B=1;GREEN_B=1;DelayMS(2000);Operation_Type=2;break;case 2: //器械向黄灯闪耀,绿灯封闭DelayMS(300);YELLOW_A=~YELLOW_A;GREEN_A=1;if(++Flash_Count!=10) return; //闪耀5次Flash_Count=0;Operation_Type=3;break;case 3: //器械向红灯,南北向绿灯亮RED_A=0;YELLOW_A=1;GREEN_A=1;RED_B=1;YELLOW_B=1;GREEN_B=0;DelayMS(2000);Operation_Type=4;break;case 4: //南北向黄灯闪耀5次DelayMS(300);YELLOW_B=~YELLOW_B;GREEN_B=1;if(++Flash_Count!=10) return;Flash_Count=0;Operation_Type=1;}}//主程序void main(){while(1) Traffic_Light();}06 单只数码管轮回显示0~9/* 名称:单只数码管轮回显示0~9解释:主程序中的轮回语句反复将0~9的段码送至P0口,使数字0~9轮回显示*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff };//延时void DelayMS(uint x){uchar t;while(x--)for(t=0;t<120;t++);}//主程序void main(){uchar i=0;P0=0x00;while(1){ /* for(;i<11;i++){ P0=~DSY_CODE[i]; DelayMS(300);} //注:另一计划 */P0=~DSY_CODE[i];i=(i+1)%10;DelayMS(300);}}07 8只数码管滚动显示单个数字/* 名称:8只数码管滚动显示单个数字解释:数码管从左到右依次滚动显示0~7,程序经由过程每次仅轮回选通一只数码管*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//主程序void main(){uchar i,wei=0x80;while(1){for(i=0;i<8;i++){P2=0xff; //封闭显示wei=_crol_(wei,1);P0=DSY_CODE[i]; //发送数字段码P2=wei; //发送位码DelayMS(300);}}}08 8只数码管动态显示多个不合字符电路如上图/* 名称:8只数码管动态显示多个不合字符解释:数码管动态扫描显示0~7.*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//主程序void main(){uchar i,wei=0x80;while(1){for(i=0;i<8;i++){P2=0xff;P0=DSY_CODE[i]; //发送段码wei=_crol_(wei,1);P2=wei; //发送位码DelayMS(2);}}}09 8只数码管闪耀显示数字串电路如上图/* 名称:8只数码管闪耀显示数字串解释:数码管闪耀显示由0~7组成的一串数字本例用动态刷新法显示一串数字,在停滞刷新时所稀有字显示消掉.*/#include<reg51.h>#define uchar unsigned char#define uint unsigned int//段码表uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//位码表uchar code DSY_IDX[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//主程序void main(){uchar i,j;while(1){for(i=0;i<30;i++){for(j=0;j<8;j++){P0=0xff;P0=DSY_CODE[j]; //发送段码P2=DSY_IDX[j]; //发送位码DelayMS(2);}}P2=0x00; //封闭所稀有码管并延时DelayMS(1000);}}10 8只数码管滚动显示数字串电路如上图/* 名称:8只数码管滚动显示数字串解释:数码管向左滚动显示3个字符组成的数字串*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//段码表uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff };//下面数组看作环形队列,显示从某个数开端的8个数(10暗示黑屏)uchar Num[]={10,10,10,10,10,10,10,10,2,9,8};//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//主程序void main(){uchar i,j,k=0,m=0x80;while(1){ //刷新若干次,保持一段时光的稳固显示for(i=0;i<15;i++){for(j=0;j<8;j++){ //发送段码,采取环形取法,从第k个开端取第j个P0=0xff;P0=DSY_CODE[Num[(k+j)%11]];m=_crol_(m,1);P2=m; //发送位码DelayMS(2);}}k=(k+1)%11; //环形队列首支针k递增,Num下标规模0~10,故对11取余}}11 K1-K4 掌握LED移位/* 名称:K1-K4 掌握LED移位解释:按下K1时,P0口LED上移一位;按下K2时,P0口LED下移一位;按下K3时,P2口LED上移一位;按下K4时,P2口LED下移一位; */#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//依据P1口的按键移动LEDvoid Move_LED(){if ((P1&0x10)==0) P0=_cror_(P0,1); //K1else if((P1&0x20)==0) P0=_crol_(P0,1); //K2else if((P1&0x40)==0) P2=_cror_(P2,1); //K3else if((P1&0x80)==0) P2=_crol_(P2,1); //K4 }//主程序void main(){uchar Recent_Key; //比来按键P0=0xfe;P2=0xfe;P1=0xff;Recent_Key=0xff;while(1){if(Recent_Key!=P1){Recent_Key=P1; //保管比来按键Move_LED();DelayMS(10);}}}12 K1-K4 按键状况显示/* 名称:K1-K4 按键状况显示解释:K1.K2按下时LED点亮,松开时熄灭,K3.K4按下并释放时LED点亮,再次按下并释放时熄灭; */#include<reg51.h>#define ucharunsigned char#define uintunsigned intsbit LED1=P0^0;sbit LED2=P0^1;sbit LED3=P0^2;sbit LED4=P0^3;sbit K1=P1^0;sbit K2=P1^1;sbit K3=P1^2;sbit K4=P1^3;//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//主程序void main(){P0=0xff;P1=0xff;while(1){LED1=K1;LED2=K2;if(K3==0){while(K3==0);LED3=~LED3;}if(K4==0){while(K4==0);LED4=~LED4;}DelayMS(10);}}13 K1-K4 分组掌握LED/* 名称:K1-K4 分组掌握LED解释:每次按下K1时递增点亮一只LED,全亮时再次按下则再次轮回开端,K2按下后点亮上面4只LED,K3按下后点亮下面4只LED,K4按下后封闭所有LED*/#include<reg51.h>#define ucharunsigned char#define uintunsigned int//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//主程序void main(){uchar k,t,Key_State;P0=0xff;P1=0xff;while(1){t=P1;if(t!=0xff){DelayMS(10);if(t!=P1) continue;//取得4位按键值,由模式XXXX1111(X中有一位为0,其他均为1)//变成模式0000XXXX(X中有一位为1,其他均为0)Key_State=~t>>4;k=0;//检讨1地点地位,累加获取按键号kwhile(Key_State!=0){k++;Key_State>>=1;}//依据按键号k进行4种处理switch(k){case 1: if(P0==0x00) P0=0xff;P0<<=1;DelayMS(200);break;case 2: P0=0xf0;break;case 3: P0=0x0f;break;case 4: P0=0xff;}}}}14 K1-K4 掌握数码管移位显示/* 名称:K1-K4 掌握数码管移位显示解释:按下K1时加1计数并增长显示位,按下K2时减1计数并削减显示位,按下K3时清零.*/#include<reg51.h>#define uchar unsigned char#define uint unsigned int//段码uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff };//位码uchar code DSY_Index[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //待显示到各数码管的数字缓冲(开端仅在0位显示0,其他黑屏)uchar Display_Buffer[]={0,10,10,10,10,10,10,10};//延时void DelayMS(uint x){uchar i;while(x--)for(i=0;i<120;i++);}void Show_Count_ON_DSY(){uchar i;for(i=0;i<8;i++){P0=0xff;P0=DSY_CODE[Display_Buffer[i]];P2=DSY_Index[i];DelayMS(2);}}//主程序void main(){uchar i,Key_NO,Key_Counts=0;P0=0xff;P1=0xff;P2=0x00;while(1){Show_Count_ON_DSY();P1=0xff;Key_NO=P1;//P1口按键状况分离为K1-0xfe,K2-0xfd,K3-0xfbswitch(Key_NO){case 0xfe: Key_Counts++;if(Key_Counts>8) Key_Counts=8;Display_Buffer[Key_Counts-1]=Key_Counts;break;case 0xfd: if(Key_Counts>0)Display_Buffer[--Key_Counts]=10;break;case 0xfb: Display_Buffer[0]=0;for(i=1;i<8;i++)Display_Buffer[i]=10;Key_Counts=0;}//若键未释放则仅刷新显示,不进行键扫描while(P1!=0xff) Show_Count_ON_DSY();}}15 K1-K4 掌握数码管加减演示/* 名称:K1-K4 掌握数码管加减演示解释:按下K1后加1计数,按下K2后减1计数,按下K3后清零.*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//段码uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff };//待显示的3位缓冲uchar Num_Buffer[]={0,0,0};//按键代码,按键计数uchar Key_Code,Key_Counts=0;//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++); }//显示函数void Show_Counts_ON_DSY(){uchar i,j=0x01;Num_Buffer[2]=Key_Counts/100;Num_Buffer[1]=Key_Counts/10%10;Num_Buffer[0]=Key_Counts%10;for(i=0;i<3;i++){j=_cror_(j,1);P0=0xff;P0=DSY_CODE[Num_Buffer[i]];P2=j;DelayMS(1);}}//主程序void main(){uchar i;P0=0xff;P1=0xff;P2=0x00;Key_Code=0xff;while(1){Show_Counts_ON_DSY();P1=0xff;Key_Code=P1;//有键按下时,数码管刷新显示30次,该行代码同时起到延时感化if(Key_Code!=0xff)for(i=0;i<30;i++) Show_Counts_ON_DSY();switch(Key_Code){case 0xfe: if(Key_Counts<255) Key_Counts++;break;case 0xfd: if(Key_Counts>0) Key_Counts--;break;case 0xfb: Key_Counts=0;}Key_Code=0xff;}}16 4X4矩阵键盘掌握条形LED显示/* 名称:4X4矩阵键盘掌握条形LED显示解释:运行本例时,按下的按键值越大点亮的LED越多.*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//矩阵键盘按键特点码表uchar code KeyCodeTable[]={0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88}; //延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//键盘扫描uchar Keys_Scan(){uchar sCode,kCode,i,k;//低4地位0,放入4行P1=0xf0;//若高4位消失0,则有键按下if((P1&0xf0)!=0xf0){DelayMS(2);if((P1&0xf0)!=0xf0){sCode=0xfe; //行扫描码初值for(k=0;k<4;k++) //对4行分离进行扫描{P1=sCode;if((P1&0xf0)!=0xf0){kCode=~P1;for(i=0;i<16;i++) //查表得到按键序号并返回if(kCode==KeyCodeTable[i])return(i);}elsesCode=_crol_(sCode,1);}}}return(-1);}//主程序void main(){uchar i,P2_LED,P3_LED;uchar KeyNo=-1; //按键序号,-1暗示无按键while(1){KeyNo=Keys_Scan(); //扫描键盘获取按键序号KeyNoif(KeyNo!=-1){P2_LED=0xff;P3_LED=0xff;for(i=0;i<=KeyNo;i++) //键值越大,点亮的LED越多{if(i<8)P3_LED>>=1;elseP2_LED>>=1;}P3=P3_LED; //点亮条形LEDP2=P2_LED;}}}17 数码管显示4X4矩阵键盘按键号/* 名称:数码管显示4X4矩阵键盘按键号解释:按下随意率性键时,数码管都邑显示其键的序号,扫描程序起首断定按键产生在哪一列,然后依据所产生的行附加不合的值,从而得到按键的序号.*/#include<reg51.h>#define uchar unsigned char#define uint unsigned int//段码uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00};sbit BEEP=P3^7;//前次按键和当前按键的序号,该矩阵中序号规模0~15,16暗示无按键uchar Pre_KeyNo=16,KeyNo=16;//延时void DelayMS(uint x){uchar i;while(x--) for(i=0;i<120;i++);}//矩阵键盘扫描void Keys_Scan(){uchar Tmp;P1=0x0f; //高4地位0,放入4行DelayMS(1);Tmp=P1^0x0f;//按键后0f变成0000XXXX,X中一个为0,3个仍为1,经由过程异或把3个1变成0,独一的0变成1switch(Tmp) //断定按键产生于0~3列的哪一列{case 1: KeyNo=0;break;case 2: KeyNo=1;break;case 4: KeyNo=2;break;case 8: KeyNo=3;break;default:KeyNo=16; //无键按下}P1=0xf0; //低4地位0,放入4列DelayMS(1);Tmp=P1>>4^0x0f;//按键后f0变成XXXX0000,X中有1个为0,三个仍为1;高4位转移到低4位并异或得到转变的值switch(Tmp) //对0~3行分离附加肇端值0,4,8,12{case 1: KeyNo+=0;break;case 2: KeyNo+=4;break;case 4: KeyNo+=8;break;case 8: KeyNo+=12;}}//蜂鸣器void Beep(){uchar i;for(i=0;i<100;i++){DelayMS(1);BEEP=~BEEP;}BEEP=0;}//主程序void main(){P0=0x00;BEEP=0;while(1){P1=0xf0;if(P1!=0xf0) Keys_Scan(); //获取键序号if(Pre_KeyNo!=KeyNo){P0=~DSY_CODE[KeyNo];Beep();Pre_KeyNo=KeyNo;}DelayMS(100);}}18 开关掌握LED/* 名称:开关掌握LED解释:开关S1和S2分离掌握LED1和LED2. */#include<reg51.h>sbit S1=P1^0;sbit S2=P1^1;sbit LED1=P0^0;sbit LED2=P0^1;//主程序void main(){while(1){LED1=S1;LED2=S2;}}19 继电器掌握照明装备/* 名称:继电器掌握照明装备解释:按下K1灯点亮,再次按下时灯熄灭*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit K1=P1^0;sbit RELAY=P2^4;//延时void DelayMS(uint ms){uchar t;while(ms--)for(t=0;t<120;t++);}//主程序void main(){P1=0xff;RELAY=1;while(1){if(K1==0){while(K1==0);RELAY=~RELAY;DelayMS(20);}}}20 数码管显示拨码开关编码/* 名称:数码管显示拨码开关编码解释:体系显示拨码开关所设置的编码000~255*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//各数字的数码管段码(共阴)uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示缓冲uchar DSY_Buffer[3]={0,0,0};//延时void DelayMS(uint ms){uchar t;while(ms--)for(t=0;t<120;t++);}//主程序void main(){uchar i,m,Num;P0=0xff;P2=0xff;while(1){m=0xfe;Num=P1; //读取拨码开关的值DSY_Buffer[0]=Num/100;DSY_Buffer[1]=Num/10%10;DSY_Buffer[2]=Num%10;for(i=0;i<3;i++)//刷新显示在数码管上{m=_crol_(m,1);P2=m;P0=DSY_CODE[DSY_Buffer[i]];DelayMS(10);}}}21 开关掌握报警器/* 名称:开关掌握报警器解释:用K1开关掌握报警器,程序掌握P1.0输出两种不合频率的声音,模仿很传神的报警后果*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit SPK=P1^0;sbit K1=P1^7;//发声函数void Alarm(uchar t){uchar i,j;for(i=0;i<200;i++){SPK=~SPK;for(j=0;j<t;j++); //由参数t行成不合的频率}}void main(){SPK=0;while(1){if(K1==1){Alarm(90);Alarm(120);}}}22 按键发音/* 名称:按键发音解释:按下不合的按键会是SOUNDER发出不合频率的声音.本例运用延时函数实现不合频率的声音输出,今后也可运用准时器*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit BEEP=P3^7;sbit K1=P1^4;sbit K2=P1^5;sbit K3=P1^6;sbit K4=P1^7;//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++); }//按周期t发音void Play(uchar t){uchar i;for(i=0;i<100;i++){BEEP=~BEEP;DelayMS(t);}BEEP=0;}void main(){P1=0xff;BEEP=0;while(1){if(K1==0)Play(1);if(K2==0) Play(2);if(K3==0) Play(3);if(K4==0) Play(4);}}23 播放音乐/* 名称:播放音乐解释:程序运行时播放诞辰快活歌, 未运用准时器中止,所有频率完整用延时实现*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit BEEP=P3^7;//诞辰快活歌的音符频率表,不合频率由不合的延时来决议uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};//诞辰快活歌节奏表,节奏决议每个音符的吹奏长短uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};//延时void DelayMS(uint x){uchar t;while(x--) for(t=0;t<120;t++);}//播放函数void PlayMusic(){uint i=0,j,k;while(SONG_LONG[i]!=0||SONG_TONE[i]!=0){ //播放各个音符,SONG_LONG为拍子长度for(j=0;j<SONG_LONG[i]*20;j++){BEEP=~BEEP;//SONG_TONE延时表决议了每个音符的频率for(k=0;k<SONG_TONE[i]/3;k++);}DelayMS(10);i++;}}void main(){BEEP=0;while(1){PlayMusic(); //播放诞辰快活DelayMS(500); //播放完后暂停一段时光}}24 INT0中止计数/* 名称:INT0中止计数解释:每次按下计数键时触发INT0中止,中止程序累加计数, 计数值显示在3只数码管上,按下清零键时数码管清零*/#include<reg51.h>#define uchar unsigned char#define uint unsigned int//0~9的段码uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00 };//计数值分化后各个待显示的数位uchar DSY_Buffer[]={0,0,0};uchar Count=0;sbit Clear_Key=P3^6;//数码管上显示计数值void Show_Count_ON_DSY(){DSY_Buffer[2]=Count/100; //获取3个数DSY_Buffer[1]=Count%100/10;DSY_Buffer[0]=Count%10;if(DSY_Buffer[2]==0) //高位为0时不显示{DSY_Buffer[2]=0x0a;if(DSY_Buffer[1]==0) //高位为0,若第二位为0同样不显示DSY_Buffer[1]=0x0a;}P0=DSY_CODE[DSY_Buffer[0]];P1=DSY_CODE[DSY_Buffer[1]];P2=DSY_CODE[DSY_Buffer[2]];}//主程序void main(){P0=0x00;P1=0x00;P2=0x00;IE=0x81; //许可INT0中止IT0=1; //降低沿触发while(1){if(Clear_Key==0) Count=0; //清0Show_Count_ON_DSY();}}//INT0中止函数void EX_INT0() interrupt{Count++; //计数值递增}。
单片机PROTEUS仿真100实例

《单片机C语言程序设计实训100例—基于8051+Proteus仿真》案例第01 篇基础程序设计01 闪烁的LED/* 名称:闪烁的LED说明:LED按设定的时间间隔闪烁*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P1^0;//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){while(1){LED=~LED;DelayMS(150);}}02 从左到右的流水灯/* 名称:从左到右的流水灯说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){P0=0xfe;while(1){P0=_crol_(P0,1); //P0的值向左循环移动DelayMS(150);}}03 8只LED左右来回点亮/* 名称:8只LED左右来回点亮说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果*/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;P2=0x01;while(1){for(i=0;i<7;i++){P2=_crol_(P2,1); //P2的值向左循环移动DelayMS(150);}for(i=0;i<7;i++){P2=_cror_(P2,1); //P2的值向右循环移动DelayMS(150);}}}04 花样流水灯/* 名称:花样流水灯说明:16只LED分两组按预设的多种花样变换显示*/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code Pattern_P0[]={0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe, 0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};uchar code Pattern_P2[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0xff,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff, 0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff};//延时void DelayMS(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//主程序void main(){uchar i;while(1){ //从数组中读取数据送至P0和P2口显示for(i=0;i<136;i++){P0=Pattern_P0[i];P2=Pattern_P2[i];DelayMS(100);}}}05 LED模拟交通灯/* 名称:LED模拟交通灯说明:东西向绿灯亮若干秒,黄灯闪烁5次后红灯亮,红灯亮后,南北向由红灯变为绿灯,若干秒后南北向黄灯闪烁5此后变红灯,东西向变绿灯,如此重复。
实验一:单片机仿真初步(二)-Proteus的使用

实验一:单片机仿真初步(二)-Proteus的使用用来仿真的单片机电路,如下图所示:电路的核心是单片机A T89C52,晶振X1和电容C1、C2构成单片机时钟电路,单片机的P1口接8个发光二极管,二极管的阳极通过限流电阻接到电源的正极。
特别注意:下面文中所有值为1K的电阻都修正成100 可以考虑把红色发光二极管换成黄色发光二极管一、新建一个设计。
单击“File”中“New Design……”,在Proteus中打开了一个空白的新电路图纸。
二、将需要用到的元器件加载到对象选择器窗口。
单击对象选择器按钮如图所示:弹出“Pick Devices”对话框,在“Category”下面找到“Mircoprocessor ICs”选项,鼠标左键点击一下,在对话框的右侧,我们会发现这里有大量常见的各种型号的单片机。
找到AT89C52,双击“AT89C52”。
这样在左侧的对象选择器就有了A T89C52这个元件了。
如果知道元件的名称或者型号我们可以在“Keywords”输入AT89C52,系统在对象库中进行搜索查找,并将搜索结果显示在“Results”中,如下图所示:在“Results”的列表中,双击“A T89C52”即可将AT89C52加载到对象选择器窗口内。
晶振CRY:无极性电容CAP:有极性电容CAP POL:红色发光二极管LED-RED:电阻RES经过前面的操作我们已经将A T98C52、晶振等元件加载到了对象选择器窗口内。
在对象选择器窗口内鼠标左键点击“AT89C52”会发现在预览窗口看到AT89C52的实物图,且绘图工具栏中的元器件按钮处于选中状态。
我们在点击“CRYSTAL”、“LED-RED”也能看到对应的实物图,按钮也处于选中状态,如图所示:三、将元器件放置到图形编辑窗口。
在对象选择器窗口内,选中A T89C52,如果元器件的方向不符合要求可使用预览对象方向控制按钮进行操作。
如用按钮对元器件进行顺时针旋转,用按钮对元器件进行逆时针旋转,用按钮对元器件进行左右反转,用按钮对元器件进行上下反转。
单片机c语言程序设计实例100例--基于805i+proteus仿真

以下是一个基于8051单片机和Proteus仿真环境的C语言程序设计实例:实例1:点亮LED灯
在这个例子中,我们将使用C语言编写一个简单的程序来控制8051单片机的一个I/O引脚,使其驱动一个LED灯。
c代码:
要使用Proteus进行仿真,你需要按照以下步骤操作:
1. 打开Proteus软件,创建一个新的设计工程。
2. 在元件库中搜索并添加相应的8051单片机型号(如AT89C51)和LED 元件到工作区。
3. 根据实际硬件连接,正确配置单片机的引脚和LED的连接。
4. 右键单击单片机元件,选择“Edit Component”打开编辑窗口。
5. 在“Program File(s)”区域,点击右侧的浏览按钮,选择你的C语言源文件(如上述的main.c)。
6. 点击“OK”关闭编辑窗口,然后点击工具栏上的“Play”按钮开始仿真。
在仿真过程中,你应该能看到LED灯被点亮,这表明你的C语言程序已经在Proteus环境中成功运行。
以上只是一个基础的例子,实际的"单片机C语言程序设计实例100例--基于8051+Proteus仿真"会包含更复杂和多样化的应用场景,包括定时器/计数器
应用、中断处理、串口通信、ADC/DAC转换、液晶显示等等。
每个实例都会详细介绍程序设计思路、代码实现以及如何在Proteus中进行仿真调试。
通过这些实例的学习和实践,你可以逐步掌握8051单片机的C语言编程技巧和Proteus仿真环境的使用方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
引言
单片机体积小,重量轻,具有很强的灵活性而且价格便宜,具有逻辑判断,定时计数等多种功能,广泛应用于仪器仪表,家用电器,医用设备的智能化管理和过程控制等领域。
以单片机为核心的嵌入式系统已经成为目前电子设计最活跃的领域之一。
在嵌入式系统的中,开发板成本高,特别是对于大量的初学者而言,还可能由于设计的错误导致开发板损坏。
利用Proteus我们可以很好地解决这个问题,由此我们可以快速地建立一个仿真系统。
2.Proteus介绍
Proteus是英国Labcenter Electro-nics公司开发的一款电路仿真软件,软件由两部分组成:一部分是智能原理图输入系统ISIS(Intelligent Schematic Input System)和虚拟系统模型VSM(Virtual Model System);另一部分是高级布线及编辑软件ARES(Adv-Ancd Routing And Editing Software)也就是PCB.
2.1 Proteus VSM的仿真
Proteus可以仿真模拟电路及数字电路,也可以仿真模拟数字混合电路。
Proteus可提供30多种元件库,超过8000种模拟、数字元器件。
可以按照设计的要求选择不同生产厂家的元器件。
此外,对于元器件库中没有的元件,设计者也可以通过软件自己创建。
除拥有丰富的元器件外,Proteus还提供了各种虚拟仪器,如常用的电流表,电压表,示波器,计数/定时/频率计,SPI调试器等虚拟终端。
支持图形化的分析功能等。
Proteus特别适合对嵌入式系统进行软硬件协同设计与仿真,其最大的特点是可以仿真8051,PIA,A VR,ARM等多种系列的处理器。
Protues包含强大的调试工具,具有对寄存器和存储器、断点和单步模式IAR C-SPY,Keil、MPLAB等开发工具的源程序进行调试的功能;能够观察代码在仿真硬件上的实时运行效果;对显示,按钮,键盘等外设的交互可视化进行仿真。
2.2 Proteus PCB
Proteus 的PCB设计除了有自动布线仿真功能外,还集成了PCB设计,支持多达16个布线层,可以任意角度放置元件和焊接连线;集成了高智能的布线算法,可以方便地进行PCB设计。
3. 基于Protesus的简单数据采集系统。
3.1 软件的编写
本例题采用可调电阻调节电压值作为模拟信号的输入量,通过A/D转换芯片AD0808把模拟信号转换为数字量传送到单片机的P1口,并在P0口把转换的结果显示出来。
软件的编写可以在Keil C51 环境下进行,芯片的型号选择AT89C51,编写data.c文件,利用Keil C51进行编译,编译成功后生成data.hex文件。
3.2 绘制电路图
运行Proteus的ISIS,进入仿真软件的主界面,如图1所示。
主界面分为菜单栏,工具栏,模型显示窗口,模型选择区,元件列表区等。
图1 ISIS启动界面
通过左侧的工具栏区的P(从库中选择元件)命令,在Pick devices窗口中选择系统所需元器件,还可以选择元件的类别,生产厂家等。
本例所需主要元器件有:A T89C51芯片,ADC0808芯片,一个四位七段数码显示器,一个可变电阻,详见表1。
表1 元器件清单
选择元器件后连接图2所示电路。
图2 电路原理图
Microproccessor ICs类的芯片的引脚与实际的芯片基本相同,唯一的差别是隐去了GND 和VCC引脚,系统默认的是把它们分别连接到地和+5V直流电源。
故在电路连线时可以不考虑电源和地的连接。
为了快速进行仿真,系统所需的时钟电路,复位电路可以省略。
电路连接完成后,选中AT89C51单击鼠标左键,打开“Edit Component”对话窗口如图3所示,可以直接在“Clock Frequency”后进行频率设定,设定单片机的时钟频率为12MHz。
在“Program File”栏中选择已经生成的data.hex文件,把在Keil编写的程序导入Proteus,然后单击“OK”按钮保存设计。
至此,就可以进行单片机的仿真。
图 3 单片机属性的设定
3.3 Proteus仿真结果
单片机的仿真结果图如图4,模拟信号经A/D转换后,结果送入单片机,再在数码管上显示;通过调节可调电阻的阻值,可以得到不同的显示结果。
仿真结果表明,系统达到了预先的设计要求。
在仿真的过程中每个管脚旁边会出现一个小方块,红色的方快表示高电平,蓝色的表示低电平。
通过方快颜色的变化可以很方便地知道每个管脚电平的变化,从而能对系统的运行有更直观的了解,这对程序的调试有很大的帮助。
图4 仿真结果
4.结束语
本文结合一个简单的数据采集系统详细说明了Proteus在单片机开发中的应用。
可以看出,Proteus功能十分强大,能仿真各种数字模拟电路,且操作简单,使用方便。
能快速地进行单片机仿真,加快系统开发的过程,降低开发成本。