MCS51 串口编程 proteus 仿真
1. 下载proteus 8.9 中文版,按网上的安装指导破解安装,安装后的sample目录下有很多例子,可以先调出来仿真看看
2. 安装后一些常见的MCU的C语言编译器需要在源代码界面的 系统/编译器配置 菜单中下载。否则只有汇编编译器。
3. 在proteus的编译器配置界面中下载 SDCC51。默认安装即可。如果用自己其他的编译环境,也可以导入HEX文件仿真,但不能源文件调试。
4. MCS51 配置简单,程序简洁,如果是学习proteus本身或接口电路,用这个最方便。
5. 调整源码编辑器配置,用Tahoma 字体比较美观
6. MCU的晶振和复位电路似乎不能仿真。
7. 双击MCU,设置时钟频率;点编辑固件,进入源码界面,选择编译工具,自动生成程序框架。
8. 改写main.c 仿真调试
9. 可以增加数字示波器,串口虚拟终端,配合激励源 仿真很直观。
先画原理图
双击MCU元器件,编辑固件,就能进入代码界面,编写代码
MCS51 应该是资料最多的MCU了,编程也很方便,在网上查找一些例子,改动成为自己的测试程序/* Main.c file generated by New Project wizard
* * Created: 2022-12-17 * Processor: AT89C52 * Compiler: SDCC for 8051 */ #include <mcs51reg.h>
//SDCC51 这些关键字不加下划线会有告警,干脆先定义好 #define xdata __xdata #define interrupt __interrupt #define using __using //SDCC51 端口位的定义方法 __sbit __at 0x97 LED_P1_7 ; //P1_7
//外部RAM 变量的定义方法,程序还是用的small模式,默认定义变量为内部RAM,用xdata定义外部指针或数据
//外部接口芯片挂在数据总线上,访问和外部静态ram一样。
unsigned char xdata * pdata1; unsigned char xdata xdata2[10]; unsigned char xdata * p8255; void delay(int k) { int i; if(k< 0) return; for(i=0; i<k; i++); } int i=0; char rxc; __bit flag = 0; /*
MCS51 的中断号和向量地址
No: int0, T0, Int1, T1, Uart vect address: reset 0, 3, B, 13, 1B, 23, T2 2B */
//定时T0 16位手工装填, 中断,在P17管脚产生方波 void timer0(void) interrupt 1 using 1 { EA =0; flag = !flag; if(flag) { //P1_7=0; LED_P1_7 = 0; i=0; } else { //P1_7=1; LED_P1_7 = 1; } TH0=0xff; // mode 1 TL0=0x80; EA =1; }
//外部中断 INT1 ,边缘触发, 按键产生中断, 在串口输出一个字符 ‘W' void int1(void) interrupt 2 using 2 { EA =0; SBUF = 'W'; while(TI==0); TI=0; EA =1; }
//串口接收中断,串口管脚靓仔虚拟终端上,收到虚拟终端发出的字符后放到外部RAM中,发送给虚拟终端回显,也可在调试窗口观察外部地址中的数据变化 void serial(void) interrupt 4 using 3 { EA =0; if(RI ==1) { rxc = SBUF; RI = 0; i++; *pdata1 =rxc; xdata2[2] =rxc+1; SBUF = rxc; while(TI==0); TI=0; } EA =1; } void send(unsigned char c) { SBUF = c; while(TI==0); TI=0; } void main(void) { EA=0; // disable all int //设置串口9600 波特率,晶振 11059200, TMOD = 0X21; // 0010 0010 T1,8bit auto timer, T0 16bit timer SCON = 0X50; // 0101 0000 mode1 TH1=0XFD; // 9600, 2^SMOD/32·T1 , 2^0/32*11059200 /12 /(256-0xfd)= 9600 TL1=TH1; PCON=0x00; //SMOD=0 , 0x80 SMOD=1 double ES=1; TR1=1; //设置T0,16位计数, 装初值,后面在中断服务程序中装填计数初始值 // timer0 int TH0=0xff; // +1 TL0=0x80; TR0=1; //T0 start ET0 =1; //enable T0 int
//开外部中断 INT1 // ex int1 IT1 = 1; // 1 -> 0 EX1=1; //enable int1
//开中断
EA =1; // enable all int
//先向虚拟中断发个字符 send('>');
//外部RAM的地址0 pdata1 = 0;
//初始化8255A,地址在138的 Y1脚上,占用 0x2000-0x2fff地址段,配置B口输出 p8255 = (unsigned char xdata * )0x2000; //0x2 000-0x2 FFF 0010 0000 0000 0000 *(p8255+3) = 0x95; // 100 1 - 0 1 0 1 A Mode0 IN, CH OUT, B Mode1 OUT, CL IN
//在8255A的PB0脚输出方波 while (1) { *(p8255+1) = 0x1; //B OUT 1 delay(10); *(p8255+1) = 0x0; //B OUT 0 delay(10); } ; }
仿真运行
也可以设置断点,或单步调试程序,观察变量。
对于业余爱好者来说,感觉比实物的DEMO板还好用,因为有各种虚拟仪表,改电路也方便。只是有些功能不能仿真,如晶振,复位电路之类的。