⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainad_usart.c

📁 PIC单片机实现的串口通信
💻 C
📖 第 1 页 / 共 2 页
字号:
//编程时间:07-4-8~4-18                    
//作者:WWS /////////////////////////////////////////////////////////////////////////
/////////////////////////////利用串行口实现直流电机的调速程序////////////////////////
///基本要求如下:////////////////////////////////////////////////////////////////////
///1.////////////////////////////////////////////////////////////////////////////////
/////实现直流电机的恒电流控制,也就是说,要控制直流电机的电流恒定,实现这个任务需要//
///利用板子上的电机驱动模块、AD模块测电流,同时,还需要你看一些直流电机控制方面的资料
///2.////////////////////////////////////////////////////////////////////////////////
///将测量得到的电机相电流、速度等数据通过串行口发送出去,串行口的参数设置为:57600,/
///1起始位+8数据位+1停止位,波特率可以通过拨码开关或按键在57600或112000之间切换;//
///同时,通过串行口,用户可以设定电流值,以便于电机调节://///////////////////////////
///3.////////////////////////////////////////////////////////////////////////////////
//电机的电流或速度在数码管上显示,可通过按键切换显示内容;///////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#include<pic.h>
/*****************************************************************************
                          数据定义部分
****************************************************************************/
bit ADFLAG=0,RECEFLAG=0,FUNCTION=0,UsartallowFLAG=0;    
///AD中断标志位,串口数据标志位,电机在运转中标志位,串口数据存储计数值,模拟串口允许发送位
bank1 static char  led[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
	///////////无小数点的段码
bank1 static char  led1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
	///////////有小数点的段码
bank1 static char  s[4]={0,0,0,0},Saveval[9]={0,0,0,0,0,0,0,0},k;
   //显示数码管服务数组,采集电压转换电流速度中间变量,循环使用值
bank1 static int  elecurt,speed;
    //////////显示函数调用相电流值,速度值   
bank1 const char  x1=0,x2=1,x3=2,x4=3;
    ///////////串口发送比较值 
bank1 static unsigned char  tab,number=0;
    //////////取LED[]数组中的值用tab,键盘服务程序使用计数值number
bank1 static unsigned char  key=0,RECE=0,tab;
    /////////按键值,串口接收到的数据,数码管段码
bank1 static unsigned int Adresult,ADsmp,i,time;
    /////////AD采样结果和当前采样值,延时函数循环值,子显示程序显示时间计数值
bank1 static unsigned  char Usartallow=0,Savechar=0;
    /////////发送串口数据允许位产生-时间计数值-计数到100即10S,串口发送数据允许时间计数值
    
/******************************************************************************
                          函数定义部分                                    
****************************************************************************/
void Portinit();          //端口初始化函数
void ADinit();            //AD初始化函数
void T1inti();            //T1初始化函数
void Usartinit();         //串口初始化函数

void dis(int data);      //数据拆分函数,服务于四段数码管
void speaker(char data); 
void keyscan();          //键盘服务  
void yw1641(char z);
void yw1642(char z);
void yw1643(char z);
void yw1644(char z);

void MOTOrun();    //电机运行控制程序
void MOTOstop();   //电机停止控制程序
void addspeed();   //电机加速控制程序
void midspeed();   //电机减速控制程序

void ChangeBAUD();  //波特率改变函数
void Saveusart();
void dealad();      //AD数据处理函数
void dealV();

void DELAY1();
void DELAY2();
void DELAY3();
/*********************************************************************
=================================主函数===============================
*********************************************************************/
void main()
{     
      Portinit();    //端口初试化
      Usartinit();   //串口初试化
      ADinit();      //AD相关寄存器初试化
      T1inti();      //采样周期与发送数据至串口时间控制器T1初始化
      TMR1IE=1;      //打开采样时钟中断标志位
      ADIE=1;        //打开AD采样中断允许位
      while(1)
       {
/////////////////////////////////////////////////////////////////////////////////////
	         ChangeBAUD(); ///////拨码开关改变当前波特率                        /////
////////////////当有AD采样完成则进行AD数据转化与电压转变电流速度值///////////////////
             if(ADFLAG==1)                                                       ////
                    {                                                            ////
                        dealad();   ////AD采样结果处理,送显示函数                ////
                        dealV();    ////处理电压值,转变为电流与速度值           ////
                    }                                                            ////
////////////////////////如果串口有数据发送过来///////////////////////////////////////
             if(RECEFLAG==1)                                                     ////
                                                                                 ////
 	                 {                                                           ////
                         RECEFLAG=0;        //清除串口接收到数据标志位           ////
                         switch(Saveval[Savechar])    //寻找相互匹配的串口命令  /////
                               {                                                 ////
                                  case  1 :  MOTOrun();                          ////
                                              break;  //当串口发来X1时,启动电机/////
                                  case  2 :  MOTOstop();                         ////
                                              break;  //当串口发来X2时,停止电机/////
                                  case  3 :  addspeed();                         ////
                                             break;   //当串口发来X3时,电机加速/////
                                  case  4 :  midspeed();                         ////
                                              break;  //当串口发来X4时,电机减速/////
                               }                                                 ////
                     }                                                           ////
////////////////每间隔10S钟发送一次当前速度值和电流值////////////////////////////////
             if(UsartallowFLAG==1)                                               ////
                       {                                                         ////
                          TXREG=speed;      //发送当前速度值                     ////
                          while(TRMT);      //等待发送完毕                       ////
                          TXREG=elecurt;    //发送当前电流值                     ////
                          UsartallowFLAG=0; //置允许发送位为零                   ////
                       }                                                         ////
////////////////////////////////////显示当前电机相电流///////////////////////////////
             dis(elecurt);                                                       ////
             keyscan();       /////键盘扫描程序,扫描键值                         ////
             yw1641(s[3]);    /////数码管显示函数,显示数码管第一段,显示当前电流值////
             DELAY2();        ///延时函数,决定数码管显示时间,长短影响主循环和亮度////
             yw1642(s[2]);    //数码管显示函数,显示数码管第二段                  ////
             DELAY2();                                                           ////
             yw1643(s[1]);    ///数码管显示函数,显示数码管第三段                 ////
             DELAY2();                                                           ////
             yw1644(s[0]);    ///数码管显示函数,显示数码管第四段                 ////
             DELAY2();                                                           ////
////////////////////////////键盘切换显示内容-显示当前速度值///////////////////////////////////
             while(key==1)                                                                /////
                    {                                                                     /////
	                  time++;                                                             /////
	                  dis(speed);                                                         /////
	                  keyscan();       /////键盘扫描程序,扫描键值                         /////
                      yw1641(s[3]);    /////显示数码管第一段,显示当前电流值               /////
                      DELAY2();        ///延时函数,决定数码管显示时间,长短影响主循环和亮度/////
                      yw1642(s[2]);    //显示数码管第二段                                 /////
                      DELAY2();                                                           /////
                      yw1643(s[1]);    ///显示数码管第三段                                /////
                      DELAY2();                                                           /////
                      yw1644(s[0]);    ///显示数码管第四段                                /////
                      DELAY2();                                                           /////
                      if(key==4|RECEFLAG==1|time>2000)   break;                           /////
                     ////当按键4,串口中接收到数据,执行子显示时间到都将跳出子显示循环    /////
                    }                                                                     /////
///////////////////////////////////////////////////////////////////////////////////////////////
        }
} 
/**************************************************************************
初始化函数:AD初始化    void  ADinit()                                
           端口初始化  void initport()                                  
           T1初始化    void T1inti()                                      
**************************************************************************/
void  ADinit()          
 {       
          ADCON1=0x82;       //转换结果右移,及ADRESH 寄存器的高6 位为"0"
          ADCON0=0x55;         
          //10 010 000选择A/D 通道为RA2,打开A/D转换器,等待中断打开标志位ADGO
                             //在工作状态,且使AD 转换时钟为Fosc/8
          INTCON=INTCON|0xc0;//ADGO位至1,启动AD转换
          ADIF=0;
         // ADON=1; 
        
               
}
void Portinit()
{	     
	      ADCON1=0x07;         //打开AD采集端口
	      TRISA=0x0f;          //相应的位作为AD采集位   
	      TRISB3=1;            //按键服务位RB3
          TRISD=0x00;          //数码管显示服务口
          TRISE=0X00;          //电机驱动服务口
          PORTD=0x00;          //关断显示,防止电平干扰 

 }  
void T1inti()
{        INTCON=0xc0;         //打开总中断与外围中断 
         TMR1H=0xf3;          //给T1赋值,32K晶振,计数值为0.1S
         TMR1L=0x34;          //给T1赋值   
         T1CON=0x0f;          //T1为异步计数器
         TMR1ON=1;            //打开T1进行计数 
} 
void Usartinit()
{
        TRISC=0X80;               //设置C口方向全为输出   
        BRGH=1;                   //高速
        SPBRG=21;                 //设置波特率为2400BPS
        SYNC=0;                   //选择异步模式
        SPEN=1;                   //设置串口引脚 
        TXEN=1;                   //允许串口接收
        CREN=1;                   //允许串口发送
        TXIE=0;                   //禁止串口发送中断 
        RCIE=1;                   //允许串口接收中断
}  
/*************************************************************
中断处理函数INTinterrupt INT()
功能:处理时钟T1和AD转换
**************************************************************/
void interrupt ISR()
{
      if(TMR1IF==1&&TMR1IE==1)
        {
	      TMR1H=0xf3;           //每间隔100Ms-AD采集一次
          TMR1L+=0x34;          //时钟计数中断则再低八位中采用加赋值,防止冲掉已经记录值
          TMR1IF=0;             //清除中断标志
          ADON=1;               //打开AD转换,次部可有可无
          ADCON0=ADCON0|0x04;   //中断产生后至AD标志位ADGO位为以一再次启动AD转换
          Usartallow++;
          if(Usartallow>100)
             {
               UsartallowFLAG=1;
              }
        }	    
      if(ADIF==1&&ADIE==1)
         {
	        ADIF=0;
	        ADFLAG=1;              //AD中断完成后返回标志位,至1
	        }
	  if(RCIF&&RCIE)
         {
            RECEFLAG=1;
            Saveusart();          //调用存储串口数据函数
         }
}
/************************************************************
函数名称:void dealad()                                     
功能:    处理AD转换的值,变为标准电压值,同时扩大1000倍     
调用:    当AD采样完毕时,调用此函数               
返回值:   返回AD采样结果int Adresult                 
*************************************************************/
void dealad()
{   
     ADFLAG=0;	
     ADsmp=ADRESL+(ADRESH<<8);          //取采样结果
     Adresult=((((ADsmp*50)>>6)*50)>>4)*2;  //标准值Adresult=(((ADsmp*50)>>8)*10)>>2;
     /*
     middle[2]=Adresult/100;
     middle[1]=Adresult%100/10;
     middle[0]=Adresult%100%10+ Adresult%3;
     */
}
/**************************************************************
函数名称:void ChangeBAUD();                                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -