基于PIC16F73的下位机串口通讯设计备忘

发布时间:2016-9-13 11:20    发布者:designapp
关键词: PIC16F73 , 串口通讯
  基本功能要求:
  接收上位机所给的设定命令,并根据命令进行相应的操作,同时下位机将采集到的信息上传给上位机处理显示等。
  具体细节设计:
  由于本设计主要针对本公司的高压电源的,关于采集到的输出高压反馈值的模拟量可以利用单片机内部集成的8位AD转换模块,
  而电源的设定电压采用单片机内部的PWM模块来实现8位的DA转换,
  具体程序如下:(初稿)
  //***********************************************************
  //-------------- 源文件名为:RS232.c-----
  //监控高压源71520的工作,开启高压,上位机可以设定高压值
  //同时可以监控反馈高压值,采用最简通讯模式
  //
  //******************************************
  #include
  #include
  __CONFIG(XT & WDTDIS& PWRTDIS & BORDIS & PROTECT );//配置字
  void DELAY(int time);
  void initPORTB();
  void initPORTA();
  void initPORTC();
  void inittmr2();
  void initCCP1();
  //变量定义
  unsigned char recdata,RX[8],i,j,k,AD_result; //0-255
  unsigned char TX[8]={0x42,0x72,0x55,0x32,0x35,0x35,0x46,0x50};//BrU255FP
  //int AD_result;
  //------------------初始化 PORTB--------
  void initPORTB()
  { TRISB=0xe0; //设置portb口高3位为输入,低5位为输出
  RBIE=1; //关闭B口的中断
  PORTB=0x00; //RB口先送高电平清除干扰
  }
  //-----------------初始化 PORTA----------
  void initPORTA() //包含AD转换初始化
  { TRISA=0x3f; //设置portA口 输入
  ADCON1=0x00; //A口全为AD口,RA0,1,2,3,5为模拟口,考电压VDD
  ADCON0=0x85; //fosc/32,通道0-85,8D-chanl1,开启转换
  ADIE=1; //允许中断
  }
  //------------------初始化 PORTC--------
  void initPORTC() //包含波特率设置
  { TRISC=0xC0; //设置portC口状态,RC7/RX为输入
  TXSTA=0XA6;
  RCSTA=0XB0; //使能串口,8位连续接收,B0连续接受
  PIR1=0X00; //清标志位
  RCIE=1; //接受中断
  TXIE=1; //发送中断
  PORTC=0x00; //RC口赋初值
  SPBRG=25; //9600-25(10进制)
  }
  //---------------初始化 tmr2------------------
  void inittmr2()
  { TMR2 =0; //赋初值,
  T2CON=0x72; //0x72后分频为1:8,预分频为1:16,先关闭.,31-4后分频,4预分频
  // TMR2IE=1; //开/关定时器2中断,清标志位
  TMR2IF=0;
  TMR2ON=1; //启动定时器2
  }
  //---------------初始化 CCP1 ------------------
  void initCCP1()
  {
  CCP1IF=0; //清标志位
  CCP1CON=0X0c; //设置工作模式
  //Pwm模式
  CCP1IE=1; //关闭中断
  PR2=0XFF; //定时器2的最大周期 245hZ
  CCPR1L=0X0f; //预制一个数
  CCPR1H=0; //,通过改变CCPR1L的值即可实现占空比的改变
  }
  void interrupt all_int()
  {
  //首先判断中断的类型,执行不同的中断子程序
  //中断优先级依次为接收中断、AD转换中断、发送中断
  if(RCIF&&RCIE) //判断是否是串口接收中断
  {
  // RB1=1;
  RCIF=0;//清干扰
  recdata=RCREG; // 接收数据并存储
  RX[i]=recdata;
  i=i+1;
  }
  //------AD转换中断----
  if(ADIF&&ADIE)
  {
  ADIF=0;//清干扰
  RB2=1;
  k=55;
  AD_result=ADRES;
  ADCON0=0x85;
  ;
  }
  //-------发送中断-----
  if(TXIF&&TXIE)
  {
  RB3=1;
  TXIF=0;//清干扰
  TXREG=TX[j];
  j=j+1;
  if(j>=8)
  {j=0;}
  }
  }
  //软件延时子程序
  void DELAY(int time)
  {
  int x,y;
  for(x=0;x=8)//全部接受完毕
  {
  RB1=1;
  i=0;
  if((RX[0]==66)&&(RX[6]==88)) //校验传输字符正确性
  {
  CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
  }
  ADCON0=0x85;//开启转换
  }
  ADCON0=0x85;//开启转换
  ;
  ;
  }
  }
  终极版本出炉!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  //***********************************************************
  //-------------- 源文件名为:rs232sample1.c-----
  //最简单的程序框架
  //RB口输出程序执行标签
  //将通道0的模拟量对其进行AD转换其值送至串口输出
  //将串口上位机设定的值送给PWM输出,
  //******************************************
  #include
  #include
  __CONFIG(XT & WDTDIS& PWRTDIS & BORDIS & PROTECT );//配置字
  void DELAY(int time);
  void initPORTB();
  void initPORTA();
  void initPORTC();
  void inittmr2();
  void initCCP1();
  //变量定义
  unsigned char recdata,RX[8],i,j,k,t; //0-255
  unsigned char TX[8]={0x42,0x72,0x55,0x30,0x30,0x30,0x46,0x50};//BrU000FP
  int AD_result;
  //------------------初始化 PORTB--------
  void initPORTB()
  { TRISB=0xe0; //设置portb口高3位为输入,低5位为输出
  RBIE=0; //关闭B口的中断
  PORTB=0x00; //RB口先送低电平清除干扰
  }
  //-----------------初始化 PORTA----------
  void initPORTA() //包含AD转换初始化
  { TRISA=0x3f; //设置portA口 输入
  ADCON1=0x00; //A口全为AD口,RA0,1,2,3,5为模拟口,考电压VDD
  ADCON0=0x85; //fosc/32,通道0-85,89-chanl1,开启转换
  ADIE=1; //允许中断
  }
  //------------------初始化 PORTC--------
  void initPORTC() //包含波特率设置
  { TRISC=0xC0; //设置portC口状态,RC7/RX为输入
  TXSTA=0XA6;
  RCSTA=0XB0; //使能串口,8位连续接收,B0连续接受
  PIR1=0X00; //
  RCIE=1; //接受中断
  TXIE=1; //发送中断
  PORTC=0x00; //RC口赋初值
  SPBRG=25; //9600-25(10进制)
  }
  //---------------初始化 tmr2------------------
  void inittmr2()
  { TMR2 =0; //赋初值,
  T2CON=0x72; //0x72后分频为1:8,预分频为1:16,先关闭.,31-4后分频,4预分频
  // TMR2IE=1; //开/关定时器2中断,清标志位
  TMR2IF=0;
  TMR2ON=1; //启动定时器2
  }
  //---------------初始化 CCP1 ------------------
  void initCCP1()
  {
  CCP1IF=0; //清标志位
  CCP1CON=0X0c; //设置工作模式
  //Pwm模式
  CCP1IE=0; //关闭中断
  PR2=0XFF; //定时器2的最大周期 245hZ
  CCPR1L=0X0f; //预制一个数
  CCPR1H=0; //,通过改变CCPR1L的值即可实现占空比的改变
  }
  void interrupt all_int()
  {
  //首先判断中断的类型,执行不同的中断子程序
  //中断优先级依次为接收中断、AD转换中断、发送中断
  if(RCIF&&RCIE) //判断是否是串口接收中断
  {
  // RB1=1;
  RCIF=0;//清干扰
  recdata=RCREG; // 接收数据并存储
  RX[i]=recdata;
  i=i+1;
  if(i>=8)//全部接受完毕
  {
  RB4=1;
  i=0;
  if((RX[0]==66)&&(RX[6]==88)) //校验传输字符正确性
  {
  CCPR1L=(RX[3]-48)*100+(RX[4]-48)*10+(RX[5]-48);
  if(CCPR1L==0)
  {
  RB4=0;
  }
  }
  }
  }
  //------AD转换中断----
  if(ADIF&&ADIE)
  {
  ADIF=0;//清干扰
  RB2=1;
  t=t+1;
  AD_result=AD_result+ADRES;
  if (t==16)
  {
  t=0;
  AD_result=AD_result>>4;
  TX[3]=(AD_result/100)+48;
  TX[4]=((AD_result%100-AD_result%10)/10)+48;
  TX[5]=(AD_result%10)+48;
  AD_result=0;
  }
  ADCON0=0x85;
  }
  //-------发送中断-----
  if(TXIF&&TXIE)
  {
  TXREG=TX[j];
  RB3=1;
  j=j+1;
  if(j>=8)
  {j=0;}
  }
  }
  //软件延时子程序
  void DELAY(int time)
  {
  int x,y;
  for(x=0;x<50;x++)
  {
  for(y=0;y }
  }
  //--------------------主程序------------------------
  main()
  {
  initPORTB(); //PORTB初始化
  initPORTA(); //PORTA初始化
  initPORTC(); //PORTC初始化
  inittmr2();
  initCCP1();
  GIE=1;
  PEIE=1;
  AD_result=0;
  while(1)
  {
  RB1=1;
  DELAY(10);
  ADCON0=0x85;
  }
  }
                               
                                                               
                               
               
本文地址:https://www.eechina.com/thread-173697-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表