欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 定时器产生PWM控制直流电机正反转

定时器产生PWM控制直流电机正反转

2025/2/25 20:23:16 来源:https://blog.csdn.net/czhaii/article/details/143584105  浏览:    关键词:定时器产生PWM控制直流电机正反转

PWM 

EN

信号为高电平使能

程序需修改          

#include       <REG52.H>
              #include       <intrins.H>
              #define        uint unsigned int  
              #define        uchar unsigned char
                #define        IAP_ADDRESS_A    0x0000  //放气次数EEPROM首地址
              #define        IAP_ADDRESS_B    0x0200  //模具下降时间EEPROM首地址
              #define        IAP_ADDRESS_C    0x0400  //放气停留EEPROM首地址
              #define        IAP_ADDRESS_D    0x0600  //硫化时间EEPROM首地址
              #define        IAP_ADDRESS_E    0x0800  //分秒选择EEPROM地址
              typedef        uchar BYTE;
              typedef        uint WORD;
              #define        CMD_IDLE    0            //空闲模式
              #define        CMD_READ    1            //IAP字节读命令
              #define        CMD_PROGRAM 2            //IAP字节编程命令
              #define        CMD_ERASE   3            //IAP扇区擦除命令
              #define        ENABLE_IAP  0x82         //if SYSCLK<20MHz
              uchar          code disdt[11]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xa3};
              uchar          code disds[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
              uchar          timeA;                 //累加器
               uint           val1,vala,valb;           /*1压紧时间2下降时间3停留时间4开模时间*/
              uchar          kcounter;                       //按键计数器加一
              uchar          kstatus;                        //按键状态标志归零
              sbit           CS=P2^6;                 //12864PIN4     vala显示缓冲valb加减时间处理缓冲
              sbit           SID=P2^7;                //12864PIN5
              sbit           SCLK=P1^0;               //12864PIN6
              sbit           RST=P5^5;
              sbit           DATAUP=P3^2;             //加按键
              sbit           DATADOWN=P3^3;           //减按键
              sbit           OUT=P1^1;                //运行指示
              sbit           BP=P2^3;                  //指示
              sbit           L1_PWM=P3^5;             //
              sbit           L1_EN=P3^4;                 // 高电平使能 低电平关闭
                sbit           R1_PWM=P3^0;             //
              sbit           R1_EN=P3^1;                 //
              sbit           MOTORLEFT=P1^7;         //电机左行
              sbit           LEFTSTOP=P1^5;          //左行停止
              sbit           MOTORRIGHT=P1^4;        //电机右行
              sbit           RIGHTSTOP=P5^4;         //电机停止
              bit            MOTORRUN_L;             //
              bit            MOTORRUN_R;             //
              uint           l,m,n,s;                 /****个十百代码缓冲**/
              uint           t1,t2,t3,t4;             /****总数个十百千****/
              uint           aa=0;                      /****RUN FLAG****/
              void           delay(uint k);           /****延时****/
/*----关闭IAP----------------------------*/
               void IapIdle()
               {
               IAP_CONTR=0;                      //关闭IAP功能
               IAP_CMD=0;                        //清除命令寄存器
               IAP_TRIG=0;                       //清除触发寄存器
               IAP_ADDRH=0x80;                   //将地址设置到非IAP区域
               IAP_ADDRL=0;
               }
/*-从ISP/IAP/EEPROM区域读取一字节-*/
               BYTE IapReadByte(WORD addr)
               {
               BYTE dat;                         //数据缓冲区
               IAP_CONTR=ENABLE_IAP;             //使能IAP
               IAP_CMD=CMD_READ;                 //设置IAP命令
               IAP_ADDRL=addr;                   //设置IAP低地址
               IAP_ADDRH=addr>>8;                //设置IAP高地址
               IAP_TRIG=0x5a;                    //写触发命令(0x5a)
               IAP_TRIG=0xa5;                    //写触发命令(0xa5)
               _nop_();                          //等待ISP/IAP/EEPROM操作完成
               dat=IAP_DATA;                     //读ISP/IAP/EEPROM数据
               IapIdle();                        //关闭IAP功能
               return dat;                       //返回
               }
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
               void IapProgramByte(WORD addr, BYTE dat)
               {
               IAP_CONTR=ENABLE_IAP;         //使能IAP
               IAP_CMD=CMD_PROGRAM;          //设置IAP命令
               IAP_ADDRL=addr;               //设置IAP低地址
               IAP_ADDRH=addr>>8;            //设置IAP高地址
               IAP_DATA=dat;                 //写ISP/IAP/EEPROM数据
               IAP_TRIG=0x5a;                //写触发命令(0x5a)
               IAP_TRIG=0xa5;                //写触发命令(0xa5)
               _nop_();                      //等待ISP/IAP/EEPROM操作完成
               IapIdle();                     //关闭IAP
               }
/*---扇区擦除---------------*/
               void IapEraseSector(WORD addr)
               {
               IAP_CONTR=ENABLE_IAP;         //使能IAP val=IapReadByte(IAP_ADDRESS+1);
               IAP_CMD=CMD_ERASE;            //设置IAP命令
               IAP_ADDRL=addr;               //设置IAP低地址
               IAP_ADDRH=addr>>8;            //设置IAP高地址
               IAP_TRIG=0x5a;                //写触发命令(0x5a)
               IAP_TRIG=0xa5;                //写触发命令(0xa5)
               _nop_();                      //等待ISP/IAP/EEPROM操作完成
               IapIdle();                     //关闭IAP
               }
/**************************************/
               void Red_Data(void)
               {
               val1=IapReadByte(IAP_ADDRESS_A);    /*放气次数*/
               }
/*********写入EEPROM占空比***********/
               void write1(uchar val)
               {
               IapEraseSector(IAP_ADDRESS_A);
               IapProgramByte(IAP_ADDRESS_A,val);/*占空比*/
               }  
/*------------------延时子程序------------------------*/
               void delay(uint t)
               {
                uint i,j;
                for(i=0;i<t;i++)
                for(j=0;j<500;j++);
               }
/*------------------延时子程序------------------------*/
               void delay_1ms(uint x)
               {
               int i,j;
               for(i=0;i<x;i++)
               for(j=0;j<1500;j++);
               }
/*------------------写命令到LCD-----------------------*/
               void write_com(uchar cmdcode)
               {
               uchar i;
               uchar i_data,temp_data1,temp_data2;
               EA=0;
               i_data=0xf8;
               delay_1ms(10);
               CS=1;
               SCLK=0;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               i_data=cmdcode;
               i_data&=0xf0;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               i_data=cmdcode;
               temp_data1=i_data&0xf0;
               temp_data2=i_data&0x0f;
               temp_data1>>=4;
               temp_data2<<=4;
               i_data=temp_data1|temp_data2;
               i_data&=0xf0;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               CS=0;
               EA=1;
               }
/*-------------------写数据到LCD----------------------*/
               void write_data(uchar Dispdata)
               {
               uchar i;
               uchar i_data,temp_data1,temp_data2;
               EA=0;
               i_data=0xfa;
               delay_1ms(10);
               CS=1;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               i_data=Dispdata;
               i_data&=0xf0;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               i_data=Dispdata;
               temp_data1=i_data&0xf0;
               temp_data2=i_data&0x0f;
               temp_data1>>=4;
               temp_data2<<=4;
               i_data=temp_data1|temp_data2;
               i_data&=0xf0;
                for(i=0;i<8;i++)
                {
                SID=(bit)(i_data&0x80);
                SCLK=0;
                SCLK=1;
                i_data=i_data<<1;
                }
               CS=0;
               EA=1;
               }
/****************按键计数器状态寄存器归零*************/
               void RstKey()
               {
               kcounter=0;                       //按键计数器归零
               kstatus=0;                        //状态寄存器归零
               }
/*****************按键低电平检测函数*****************/
               void   LowVoltKey(void)           //按键计数器状态标志加一
               {
               kcounter++;                       
               kstatus++;     
               delay(5);                         //延时                  
               }
/*****************按键高电平检测函数*****************/
               void    HighVoltKey(void)         //按键计数器加一 状态标志归零
               {
               kcounter++;                       //按键计数器加一
               kstatus=0;                        //按键状态标志归零
               delay(5);                         //延时
               }
/*------------------初始化LCD屏-----------------------*/
               void lcd_init()
               {
               uchar comdata;
               RST=0;
               delay(10);
               RST=1;
               comdata=0x30;
               write_com(comdata); /*功能设置:一次送8位数据,基本指令集*/
               comdata=0x04;
               write_com(comdata); /*点设定:显示字符/光标从左到右移位,DDRAM地址加1*/
               comdata=0x0f;
               write_com(comdata); /*显示设定:开显示,显示光标,当前显示位反白闪动*/
               comdata=0x01;
               write_com(comdata); /*清DDRAM*/
               comdata=0x02;
               write_com(comdata); /*DDRAM地址归位*/
               comdata=0x80;
               write_com(comdata); /*把显示地址设为0X80,即为第一行的首位*/
               }
/**************显示左行*********************/    
               void   LEFT_ON()
               {
                write_com(0x91);
                write_data(0xD7);
                write_data(0xF3);                /*---左----*/
                write_com(0x92);
                write_data(0xD0);
                write_data(0xD0);                /*---行----*/
               }     
/**************显示右行*********************/    
               void   RIGHT_ON()
               {
                write_com(0x91);
                write_data(0xD3);
                write_data(0xD2);                /*---右----*/
                write_com(0x92);
                write_data(0xD0);
                write_data(0xD0);                /*---行----*/
               }     
/**************显示停止*********************/    
               void   STOP()
               {
                write_com(0x91);
                write_data(0xCD);
                write_data(0xA3);                /*---停----*/
                write_com(0x92);
                write_data(0xD6);
                write_data(0xB9);                /*---止----*/
               }     
/**************复位引脚*********************/
               void Rst_Io()
               {
                L1_PWM=1;             //
                L1_EN=1;                 // 高电平使能 低电平关闭
                R1_PWM=1;             //
                R1_EN=1;                 //
                MOTORRUN_L=0;             //
                MOTORRUN_R=0;                   //
                MOTORLEFT=1;         //电机左行
                LEFTSTOP=1;          //左行停止
                MOTORRIGHT=1;        //电机右行
                RIGHTSTOP=1;         //电机9
               }
/*---------------------*/
               void display(uchar vala)                    /*显示参数值*/
               {
                l=vala/100;                      /**/
                m=(vala-l*100)/10;               /*减t1x1000再减t2X100*/
                n=vala-l*100-10*m;               /*分离千 百 十 个三位*/  
                write_com(0X95);                 /*地址*/
                write_data(0xA3);                /*半个字符*/
                write_data(disdt[l]);            /*百位*/                                                
                write_com(0X96);                 /*地址*/
                write_data(0xA3);                /*半个字符*/
                write_data(disdt[m]);            /*百位*/
                write_com(0X97);                 /*地址*/
                write_data(0xA3);                /*半个字符*/
                write_data(disdt[n]);            /*十?/
               }
/**************定时中断*************************/
               void timer0() interrupt 1
               {
                aa++;
                if(aa>=30)
                {
                OUT=~OUT;
                aa=0;
                }
                if(MOTORRUN_L==1)
                 {
                  timeA++; //计数加
                  if(timeA<val1) //time=20
                  {
                   L1_PWM=0;
                  }
                  else if(timeA>val1&&timeA<99)
                  {
                  L1_PWM=1;
                  timeA=0;
                  }
                  else if(timeA>99)
                  {
                  L1_PWM=0;
                  timeA=0;
                  }
                 }
                 else  if(MOTORRUN_L==0)
                 {
                  L1_PWM=1;
                  L1_EN=1;
                 }
                 if(MOTORRUN_R==1)
                 {
                  timeA++; //计数加
                  if(timeA<val1) //time=20
                  {
                   R1_PWM=0;
                  }
                  else if(timeA>val1&&timeA<99)
                  {
                  R1_PWM=1;
                  timeA=0;
                  }
                  else if(timeA>99)
                  {
                  R1_PWM=0;
                  timeA=0;
                  }
                 }
                 else  if(MOTORRUN_R==0)
                 {
                  R1_PWM=1;
                  R1_EN=1;
                 }
               }
/*------------------主循环程序----------------*/      
              void   main( )                    /*主程序开始*/
              {  
               lcd_init() ;                      /*液晶复位*/
               AUXR=0X80;                        //STC系列的1T 设置
               TMOD=0X01;
               TH0=0X53;
               TL0=0X32;
               ET0=1;
               TR0=1;
               EA=1;      
                Red_Data();                       /*读EEPROM数据*/
               Rst_Io();                         /*复位*/
               display(val1);                     //
               STOP();                           //
               while(1)                          /*主函数循?/
               {                                 /*开始*/
/***************参数加*************/
                RstKey();                        //按键复位
                for(;kcounter<5;)                //按键循环5次
                {
                 if(!DATAUP)                     //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!DATAUP)               //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                   /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                val1++;
                if(val1>99)
                val1=1;
                write1(val1);
                display(val1);
                }
/****************参数减******************/
                RstKey();                        //按键复位
                for(;kcounter<5;)                //按键循环5次
                {
                 if(!DATADOWN)                   //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!DATADOWN)             //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                   /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                val1--;
                if(val1<1)
                val1=99;
                write1(val1);
                display(val1);
                }
/****************电机左行******************/
                 RstKey();                       //按键复位
                 for(;kcounter<5;)               //按键循环5次
                 {
                  if(!MOTORLEFT)                 //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!MOTORLEFT)           //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=4)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 MOTORRUN_L=1;                      //电机左运行标志
                 MOTORRUN_R=0;                      //电机右运行标志
                 BP=0;                           //指示
                 L1_EN=0;
                 LEFT_ON();
                 }
/*****************左行停止*****************/
                 RstKey();                       //按键复位
                 for(;kcounter<5;)               //按键循环5次
                 {
                  if(!LEFTSTOP)                  //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!LEFTSTOP)            //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=4)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 MOTORRUN_L=0;                      //电机左运行标志
                 BP=1;                           //指示
                 STOP();
                 }
/*****************电机右行*****************/
                 RstKey();                       //按键复位
                 for(;kcounter<5;)               //按键循环5次
                 {
                  if(!MOTORRIGHT)                //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!MOTORRIGHT)          //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=4)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 MOTORRUN_R=1;                      //电机右运行标志
                 MOTORRUN_L=0;                      //电机左运行标志
                 BP=0;                           //指示
                 R1_EN=0;
                 RIGHT_ON();
                 }
/*****************电机停止*****************/
                 RstKey();                       //按键复位
                 for(;kcounter<5;)               //按键循环5次
                 {
                  if(!RIGHTSTOP)                 //按键低电平
                  {
                  LowVoltKey();
                  }
                  else if(~!RIGHTSTOP)           //按键高电平
                  {
                  HighVoltKey();
                  }
                 }
                 if(kstatus>=4)                  /*按键状态标志大于等于3为有效值*/
                 {                               /*循环检测 */
                 MOTORRUN_R=0;                   //电机右运行标志
                 BP=1;                           //指示
                 STOP();
                 }
/**********************************/             //
                }                                //while 循环
               }                                 //L501 CODE 14772024 11 7

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词