PIC单片机实例三:基于PROTEUS模拟的双机异步通信

发布者:dfdiqc最新更新时间:2016-11-02 来源: eefocus关键字:PIC单片机  PROTEUS模拟  双机异步通信 手机看文章 扫描二维码
随时随地手机看文章
公司的数控面板和控制板的连线是25芯的,但没有既细又长的配套线,所以一向都是自己用细线做的,但问题也就多了,乘着这几天正学串口通信,用PIC单片机改装了两块板,实现了双机之间的异步通信,并用PROTEUS模拟了出来,跟有兴趣的朋友共享.

一.原理图

功能介绍:

(1).U1单片机控制4X5的矩阵键盘和十个指示灯,名称按图所示.

(2).U2单片机控制18个继电器.

(3).按键”选择枪1”,”选择枪2”,”选择枪3”,”选择枪4”,”PREHEAT”,”CUTTING”,”HEIGHT”,”RETRACE”,”PLASMA”这9个按键是一键控制相对应的继电器的开关.就是说按一下为开,送开保持原先状态,再按一下为关,送开保持,即实现一个D触发器的电平翻转功能.

(4).按键”1 UP”,”1 DOWN”,”2 UP”,”2 DOWN”,”3 UP”,”3 DOWN”,”4 UP”,”4 DOWN”,”ALL UP”,”ALL DOWN”,”IGNITION”为点动按键,即按下为开,继电器吸合,送开为关,继电器放开.

(5).所用单片机为P16F873A

二.程序

为观察方便,特把图分为发送部分和接收部分,并分别编程.

1.       发送部分

 原理图如下所示

/***********************************************************************

*   文件标题:CNC-USART-1                                            *

*   编制日期:2007.12.19                                                  *

*   编制人:  wujieflash                                                      *

*   程序用途:用于数控切割机上的面板通信(发送部分) *

*   配套图纸:CNC-02                                                       *

*   版本号:  V1.0                                                             *

***********************************************************************/

#include

 

//函数声明

void initial();

void delay();

void key_scan();

void key_serve();

void send_usart();

 

//定义变量

unsigned int i,j,k1,k2,k3,k4,k5,k6,k7,k8,k9,k10;

 

//子程序

//初始化子程序

void initial()

{

       ADCON1=0x06;//设置为普通数字引脚

      

       TRISC0=0;//键盘四根行线设置为输出

       TRISC1=0;

       TRISC2=0;

       TRISC3=0;

       TRISC4=1;//键盘五根列线设置为输入

       TRISC5=1;

       TRISA2=1;

       TRISA3=1;

       TRISA4=1;

      

       TRISB=0;

       PORTB=0;

       TRISA0=0;

       RA0=0;

       TRISA1=0;

       RA1=0;

      

       RC0=0;//四根行线先送低电平

       RC1=0;

       RC2=0;

       RC3=0;

      

       //USART部件初始化

       SPBRG=0x19;//设置波特率为9600bps

       TXSTA=0x04;//选择异步高速8位数据传输模式

       RCSTA=0x80;//允许串行端口工作

       TRISC6=1;//设置为高阻态,防止干扰

       TRISC7=1;

}

 

//延时子程序

void delay()

{

       for(i=2000;i--;)

       continue;

}

      

//键盘扫描子程序

void key_scan()

{

       while(1)

       {

              if((RC4==0)||(RC5==0)||(RA2==0)||(RA3==0)||(RA4==0))//是否有键按下

              {

                     break;

              }

       }

       delay();

       if((RC4==0)||(RC5==0)||(RA2==0)||(RA3==0)||(RA4==0))//确认有键按下

       {

              key_serve();

       }

       else

       {

              j=0x00;

              send_usart();

       }

}

 

//按键服务子程序

void key_serve()

{

       RC1=1;//先置RC0为低电平,剩余三根行线为高电平

       RC2=1;

       RC3=1;

       RC0=0;

       if(RC4==0)//按键1 “select 1"

       {

              k1++;

              k1=k1%2;

              if(k1==1)//奇数次为开

              {

                     j=0x01;

                     send_usart();

                  RB0=1;//指示灯亮

           }

           if(k1==0)//偶数次为关

           {

                  j=0x15;

                  send_usart();

                  RB0=0;//指示灯灭

              }

       }

       if(RC5==0)//按键2 "1 up"

       {

              j=0x02;

              send_usart();

       }

       if(RA2==0)//按键3 "1 down"

       {

              j=0x03;

              send_usart();

       }

       if(RA3==0)//按键4 "select 2"

       {

              k2++;

              k2=k2%2;

              if(k2==1)//奇数次为开

              {

                     j=0x04;

                     send_usart();

                     RB1=1;

              }

              if(k2==0)//偶数次为关

              {

                     j=0x16;

                     send_usart();

                     RB1=0;

              }

       }

       if(RA4==0)//按键5 “2 up"

       {

              j=0x05;

              send_usart();

       }

      

       RC0=1;//置RC1为低电平,剩余行线为高

       RC2=1;

       RC3=1;

       RC1=0;

       if(RC4==0)//按键6 "2 down"

       {

              j=0x06;

              send_usart();

       }

       if(RC5==0)//按键7 "select 3"

       {

              k3++;

              k3=k3%2;

              if(k3==1)

              {

                     j=0x07;

                     send_usart();

                     RB2=1;

              }

              if(k3==0)

              {

                     j=0x17;

                     send_usart();

                     RB2=0;

              }

       }

       if(RA2==0)//按键8 "3 up"

       {

              j=0x08;

              send_usart();

       }

       if(RA3==0)//按键9 "3 down"

       {

              j=0x09;

              send_usart();

       }

       if(RA4==0)//按键10 "select 4"

       {

              k4++;

              k4=k4%2;

              if(k4==1)

              {

                     j=0x0a;

                     send_usart();

                     RB3=1;

              }

              if(k4==0)

              {

                     j=0x18;

                     send_usart();

                     RB3=0;

              }

       }

      

       RC0=1;//置RC2为低电平,剩余为高

       RC1=1;

       RC3=1;

       RC2=0;

       if(RC4==0)//按键11 "4 up"

       {

              j=0x0b;

              send_usart();

       }

       if(RC5==0)//按键12 "4 down"

       {

              j=0x0c;

              send_usart();

       }

       if(RA2==0)//按键13 "all up"

       {

              j=0x0d;

              send_usart();

       }

       if(RA3==0)//按键14 "all down"

       {

              j=0x0e;

              send_usart();

       }

       if(RA4==0)//按键15 "preheat"

       {

              k5++;

              k5=k5%2;

              if(k5==1)

              {

                     j=0x0f;

                     send_usart();

                     RB4=1;

              }

              if(k5==0)

              {

                     j=0x19;

                     send_usart();

                     RB4=0;

              }

       }

      

       RC0=1;//置RC3为低,剩余为高

       RC1=1;

       RC2=1;

       RC3=0;

       if(RC4==0)//按键16 "cutting"

       {

              k6++;

              k6=k6%2;

              if(k6==1)

              {

                     j=0x10;

                     send_usart();

                     RB5=1;

              }

              if(k6==0)

              {

                     j=0x1a;

                     send_usart();

                     RB5=0;

              }

       }

       if(RC5==0)//按键17 "height"

       {

              k7++;

              k7=k7%2;

              if(k7==1)

              {

                     j=0x11;

                     send_usart();

                     RB6=1;

              }

              if(k7==0)

              {

                     j=0x1b;

                     send_usart();

                     RB6=0;

              }

       }

       if(RA2==0)//按键18 "ignition"

       {

                     j=0x12;

                     send_usart();

                     RB7=1;

       }

       if(RA3==0)//按键19 "retrace"

       {

              k9++;

              k9=k9%2;

              if(k9==1)

              {

                     j=0x13;

                     send_usart();

                     RA0=1;

              }

              if(k9==0)

              {

                     j=0x1d;

                     send_usart();

                     RA0=0;

              }

       }

       if(RA4==0)//按键20 "oxy/plasma"

       {

              k10++;

              k10=k10%2;

              if(k10==1)

              {

                     j=0x14;

                     send_usart();

                     RA1=1;

              }

              if(k10==0)

              {

                     j=0x1e;

                     send_usart();

                     RA1=0;

              }

       }

       RC0=0;//置四根行线为低电平

       RC1=0;

       RC2=0;

       RC3=0;

       while(1)

       {

              if((RC4==1)&&(RC5==1)&&(RA2==1)&&(RA3==1)&&(RA4==1))//等键松开

              break;

       }

       RB7=0;//关“IGNITION”指示灯

       j=0x00;

       send_usart();

}

      

//命令发送子程序

void send_usart()

{

       TXEN=1;//发送允许

       CREN=1;//接收允许

       TXREG=j;

       while(1)

       {

              if(TXIF==1)break;//等待发送完成

       }

       while(1)

       {

              if(RCIF==1)break;//等待接收完成

       }

       RCREG=RCREG;//读响应字节,清RCIF

}

      

//主程序

void main(void)

{

       initial();

       while(1)

       {

              key_scan();

       }

}

           

2.接收部分

原理图如下所示

/***********************************************************************

*   文件标题:CNC-USART-2                                              *

*   编制日期:2007.12.19                                                   *

*   编制人:  吴杰                                                                *

*   程序用途:用于数控切割机上的面板通信(接收部分)   *

*   配套图纸:CNC-01                                                         *

*   版本号:  V1.0                                                               *

***********************************************************************/

#include

 

//函数声明

void initial();

void recevie_usart();

void rece_serve();

 

//定义变量

unsigned int rece;

 

//子程序

//初始化子程序

void initial()

{

       ADCON1=0x06;//设置RA口为普通数字端口

       TRISA=0;

       PORTA=0;

       TRISB=0;

       PORTB=0;

       TRISC=0;

       PORTC=0;

      

       //USART部件初始化

       SPBRG=0x19;//设置波特率为9600bps

       TXSTA=0x04;//选择异步高速8位数据传输模式

       RCSTA=0x80;//允许串行端口工作

       TRISC6=1;//设置为高阻态,防止干扰

       TRISC7=1;

}

 

//接收子程序

void recevie_usart()

{

       CREN=1;

       TXEN=1;

       while(1)

       {

              if(RCIF==1)break;//接收完毕

       }

       rece=RCREG;//读取接收到的数据,并清RCIF

       TXREG=rece;//待发送的数据

       while(1)

       {

              if(TXIF==1)break;//发送完毕

       }

}

 

//接收服务子程序

void rece_serve()

{

       switch(rece)

       {

              case 0x00:{

                            RC2=0;//继电器“1 up"关

                            RC3=0;//继电器"1 down"关

                            RC4=0;//继电器”2 up"关

                            RC5=0;//继电器“2 down"关

                            RA0=0;//继电器”3 up"关

                            RA1=0;//继电器“3 down"关

                            RA2=0;//继电器”4 up"关

                            RA3=0;//继电器“4 down"关

                            RB7=0;//继电器“ignition"关

                            break;

                       }

              case 0x01:{

                            RB0=1;//继电器”1 select"开

                            break;

                      }

              case 0x15:{

                            RB0=0;//继电器“1 select"关

                            break;

                      }          

              case 0x02:{

                            RC2=1;//继电器”1 up"开

                            break;

                            }

              case 0x03:{

                            RC3=1;//继电器”1 down"开

                            break;

                            }

              case 0x04:{

                            RB1=1;//继电器”2 select"开

                            break;

                            }

              case 0x16:{

                            RB1=0;//继电器”2 select"关

                            break;

                            }

              case 0x05:{

                            RC4=1;//继电器”2 up"开

                            break;

                            }

              case 0x06:{

                            RC5=1;//继电器”2 down"开

                            break;

                            }

              case 0x07:{

                            RB2=1;//继电器”3 select"开

                            break;

                            }

              case 0x17:{

                            RB2=0;//继电器”3 select"关

                            break;

                            }

              case 0x08:{

                            RA0=1;//继电器”3 up"开

                            break;

                            }

              case 0x09:{

                            RA1=1;//继电器”3 down"关

                            break;

                            }

              case 0x0a:{

                            RB3=1;//继电器”4 select"开

                            break;

                            }

              case 0x18:{

                            RB3=0;//继电器”4 select"关

                            break;

                            }

              case 0x0b:{

                            RA2=1;//继电器”4 up"开

                            break;

                            }

              case 0x0c:{

                            RA3=1;//继电器”4 down"开

                            break;

                            }

              case 0x0d:{

                            RC6=1;//继电器”all up"开

                            RC4=1;

                            RC2=1;

                            RA0=1;

                            break;

                            }

              case 0x0e:{

                            RA1=1;//继电器”all down"开

                            RC3=1;

                            RC5=1;

                            RC7=1;

                            break;

                            }

              case 0x0f:{

                            RB4=1;//继电器”preheat"开

                            break;

                            }

              case 0x19:{

                            RB4=0;//继电器”preheat"关

                            break;

                            }

              case 0x10:{

                            RB5=1;////继电器”cutting"开

                            break;

                            }

              case 0x1a:{

                            RB5=0;//继电器”cutting"关

                            break;

                            }

              case 0x11:{

                            RB6=1;////继电器”height"开

                            break;

                            }

              case 0x1b:{

                            RB6=0;//继电器”height"关

                            break;

                            }

              case 0x12:{

                            RB7=1;//继电器”ignition"开

                            break;

                            }

              /*case 0x1c:{

                            RB7=0;//继电器”ignition"关

                            break;

                            }*/

              case 0x13:{

                            RC0=1;//继电器”retrace"开

                            break;

                            }

              case 0x1d:{

                            RC0=0;//继电器”retrace"关

                            break;

                            }

              case 0x14:{

                            RC1=1;//继电器”plasma"开

                            break;

                            }

              case 0x1e:{

                            RC1=0;//继电器”plasma"关

                            break;

                            }    

       }

}

 

//主程序

void main()

{

       initial();

       while(1)

       {

              recevie_usart();

              rece_serve(); 

       }

}

三,总结

    虽然板子用用也没啥问题,但程序毕竟考虑的简单了一些,如:没有考虑故障处理的问题,我打算写进一段自动提示故障的程序,在两板之间通信线出现问题不通的时候,闪烁指示灯提示.还有什么欠考虑的地方请大家一起帮忙!

关键字:PIC单片机  PROTEUS模拟  双机异步通信 引用地址:PIC单片机实例三:基于PROTEUS模拟的双机异步通信

上一篇:PIC单片机实例五:基于PROTEUS模拟的精美万年历
下一篇:PIC单片机实例二:基于I2C的SAA1064数码管显示

推荐阅读最新更新时间:2024-03-16 15:19

PIC单片机控制的遥控防盗报警器
AG9900型智能遥控机车防盗系统电路如图1、图2所示。单片机PIC16C54单片机为主控器,VD5026、VD5027是编解码电路。该报警器具有声光三级连锁防盗、闪光滚动报警、防抢劫、免匙驾驶、超车寻车、解除熄火和灵敏度调节等功能,其全遥控操作非常适合在机动车辆上安装使用。 一、发射电路 图1中的VD5026、T4等组成遥控发射单元。12V电源一路直接供给高频发射电路,另一路在按下发射键K1~K4时,经D10、R24~R27分压得到约5V电压,通过D6~D9供给VD5026。按下发射键K1~K2之一时,{17}脚会输出编码脉冲串,经T4高频调制后发射出去(T4组成的高频振荡器频率约在180MHz左右)。VD5026的
[单片机]
<font color='red'>PIC单片机</font>控制的遥控防盗报警器
PIC单片机的IIC接口程序
PIC单片机的IIC接口程序 IniTI2CBusMaster ;************************************************************TxmtStartBit bsf Bus_Busy ; on a start condiTIon bus is busy bsf STATUS, RP0 ; Select page 1 bsf _SDA ; set SDA high bsf _SCL ; clock is high call Delay40uSec
[单片机]
运用PIC单片机产生SPWM信号控制逆变桥的方法在UPS电源
1 前 言 随着信息技术的不断发展和计算机应用的日益普及,高新技术设备对供电质量的要求越来越高,很多设备都要求 电源 能够持续提供恒频恒压、无崎变的纯正弦波交流电,不间断电源UPS就是用来给这些设备供电的。UPS一般采用正弦脉宽 调制 (S PWM )的控制方法将直流电逆变成正弦波交流电。目前,SPWM控制波形的产生一般有三种方式:1、用分立元件 电路 产生,主要由三角波发生器、正弦波发生器和比较器组成。分立元件电路复杂,调试困难,成本高,可靠性差,因此一般很少采用。2、用专用集成芯片产生,专用集成芯片功能强大,输出波形质量高,应用比较广泛。3、用 单片机 实现,现在许多单片机都具有产生SPWM波的功能,采用单片机可使电路
[单片机]
运用<font color='red'>PIC单片机</font>产生SPWM信号控制逆变桥的方法在UPS电源
采用PIC单片机芯片的三相半控整流电路设计
  三相半控整流桥电路结构是一种常见的整流电路,其容易控制,成本较低。本文中介绍了一种基于 PIC690单片机与专用集成触发芯片TC787的三相半控整流电路,它结合专用集成触发芯片和数字触发器的优点 ,获得了高性能和高度对称的触发脉冲。它充分利用单片机内部资源 ,集相序自适应、系统参数在线调节和各种保护功能于一体,可用于对负载的恒电压控制。主电路采用了三相半控桥结构,直流侧采用LC滤波结构来提高输出的电压质量。      系统总体设计   本系统通过PIC690单片机作为主控制芯片,用晶闸管作为主要开关器件。设计的目标是保持输出的直流电压稳定,输出电压纹波小,交流输出测电流THD较低,性能可靠。   系统主要电路包括:三相
[单片机]
采用<font color='red'>PIC单片机</font>芯片的三相半控整流电路设计
PIC单片机的外接电压检测复位电路举例
1.6.5 PIC单片机的外接电压检测复位电路举例   1.设计思路   有许多型号单片机的内部均不具备掉电复位功能,即使对于内部包含该功能的PIC单片机,其复位门槛电压值是固定不可更改的,有时不能满足用户的需求,因此,外加电压检测复位电路也是较常见的设计方案。   对于片内带有掉电复位功能BOR的PIC单片机,在使用外接电压检测复位电路时,就必须将内部BUR功能禁止,方法是将系统配置字的BUDEN位设置为0。   对于内部不带BOR功能的PIC单片机,其电源控制寄存器PCUN没有BOR标志位,无法准确识别由外接电压检测复位电路引起的单片机复位,因此在程序执行过程中在MCLR引脚施加了人工复位信号引起的复位。   与外接电压检测复
[单片机]
<font color='red'>PIC单片机</font>的外接电压检测复位电路举例
PIC单片机的AT24C64通讯设计
该程序实现的功能是: 将I2C_A,I2C_B.。...I2C_K内容写入EEPROM中 同时在EEPROM中读出数据从新写入各个寄存器 LISTP=16C74B #include ERRORLEVEL-302 I2C_AEQU0X20 I2C_BEQU0X21 I2C_CEQU0X22 I2C_DEQU0X23 I2C_EEQU0X24 I2C_FEQU0X25 I2C_GEQU0X26 REG1EQU0X2B REG2EQU0X2C COUN TE QU0X71;I2C BCOUNTEQU0X72;I2C TXBUFEQU0X73;I2C RXBUFEQU0X74;I2C BUSCONEQU0X75;I2C BUSS
[单片机]
<font color='red'>PIC单片机</font>的AT24C64通讯设计
PIC单片机模/数转换器ADC模块的设计思路及电路设计
PIC16F877单片机的ADC内部结构如图1所示。40引脚封装芯片与28引脚封装芯片的区别主要在于模拟口的数量不同,28引脚封装芯片没有AN5~AN7模拟量输入通道,其他各部分的功能和组成关系相同。PIC16F877单片机的ADC内部结构图如图2所示。   图1 主程序及中断程序流程   图2 PIC16F877单片机的ADC内部结构图   PIC16F877单片机内部嵌入的ADC模块具有10位数字量精度,共有8个模拟通道,与ADO模块有关的寄存器共有11个,其专用的4个寄存器分别为:ADCCON0、ADCCON1、ADRESH及ADRESL。   源阻抗(RS)和内部采样开关(RSS)阻抗直接影响所要求的充
[单片机]
<font color='red'>PIC单片机</font>模/数转换器ADC模块的设计思路及电路设计
基于PIC单片机的新型冲水器的设计
  1. 引言   传统的手按式厕所冲水器冲水系统采用的是全机械构造,冲水时需要人工手按,既浪费了时间和水资源,又因手的接触而造成不卫生,还会因忘记冲水而造成环境污染,为适应日益加快的现代生活的节奏,节约水资源,创造一个干净、舒适、卫生的环境,稳定、可靠、方便的感应式冲水器亟待出现,特别是在大型商场、车站、学校等人员流动比较大的卫生间,节水型感应式冲水器显得尤为重要 。   然而,一般的感应式冲水器因其硬件电路的设计、单片机的选择及冲水阀门的选择不是非常恰当,会造成制造成本高,电量消耗大,易出现误感应、不冲水等不稳定因素,不仅浪费了能源还给使用者造成一些不必要的麻烦。针对这些问题,我们设计了一套制造成本低且稳定性高的冲水系统。
[单片机]
基于<font color='red'>PIC单片机</font>的新型冲水器的设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved