void PWM_Out(unsigned char pwmi,unsigned char duty)//PWM调用,输入参数:PWM号,占空比 {PIN_SW2 |= 0x80;                //使能访问XSFR
PWMCFG = 0x00;
PWMCKS = 0x00;                  //选择PWM的时钟为Fosc/(0+1)     PWMC = CYCLE;                   //设置PWM周期
if(pwmi==3) {      ;
PWM3T1 = 0x0000;                //设置PWM3第1次反转的PWM计数    PWM3T2 = CYCLE * duty / 100;    //设置PWM3第2次反转的PWM计数                                      //占空比为(PWM3T2-PWM3T1)/PWMC
PWM4T1 = 0x0000;                  //设置PWM4第1次反转的PWM计数    PWM4T2 = CYCLE *(100-duty)/ 100;  //设置PWM4第2次反转的PWM计数                                      //占空比为(PWM4T2-PWM4T1)/PWMC     }
void Uart_init() {
PCON &= 0x7F;  SCON = 0x50;  AUXR |= 0x40;  AUXR &= 0xFE;  TMOD &= 0x0F;  TMOD |= 0x20;  TL1 = 0xDC; TH1 = 0xDC; ET1 = 0;  TR1 = 1;
ES    = 1;      //打开串口中断
//波特率不倍速 //8位数据,可变波特率 //定时器1时钟为Fosc,即1T //串口1选择定时器1为波特率发生器 //清除定时器1模式位
//设定定时器1为8位自动重装方式 //设定定时初值9600
PWM4CR = 0x00;      //选择PWM2输出到P2.2,不使能PWM4中断  PWMCR |= 0x04;   }
PWMCR |= 0x80;
PWM3CR = 0x00;                  //选择PWM3输出到P2.1,不使能PWM3 PWMCR |= 0x02;   }
else if(pwmi==4) { 中断
PIN_SW2 &= ~0x80;
//设定定时器重装值   //禁止定时器1中断   //启动定时器1
}
EA    = 1;      //打开总中断 IP=0x10;
void Uart_Interrupt (void) interrupt 4 using 1 //串行中断服务程序 {
if(RI)                        //判断是接收中断产生      {
RI=0;                      //标志位清零
switch(SBUF)    {
case'1':{Left=0;Right=0;PWM_Out(3,30);PWM_Out(4,30);Speed=30;Buzzer=1;} break;//前进
case '2':{Left = 1;Right = 1;PWM_Out(3,70);PWM_Out(4,70);Speed=30;} break;//后退
case'3':{Left = 0;Right = 0;PWM_Out(3,10);PWM_Out(4,70);Speed=40;} break;//左转
case'4':{Left = 0;Right = 0;PWM_Out(3,70);PWM_Out(4,10);Speed=40;} break;//右转
case '5':{Left = 0;Right = 0;PWM_Out(3,1); PWM_Out(4,1); Speed=0;}  break;//停止     }
//********************LCD系统初始化***********************// /*------------------------------------------------  uS延时函数,含有输入参数 unsigned char t,无返回值  unsigned char 是定义无符号字符变量,其值的范围是  0~255 这里使用晶振12M,精确延时请使用汇编,大致延时  长度如下 T=tx2+5 uS
------------------------------------------------*/ void DelayUs2x(unsigned char t)
default: ;break;    }  }
Buzzer=0;
{
while(--t); }
/*------------------------------------------------  mS延时函数,含有输入参数 unsigned char t,无返回值  unsigned char 是定义无符号字符变量,其值的范围是  0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) {        while(t--)  {
//大致延时1mS      DelayUs2x(245);   } }
/*------------------------------------------------               写入命令函数
------------------------------------------------*/  void LCD_Write_Com(unsigned char com)   {           }
/*------------------------------------------------               写入数据函数
------------------------------------------------*/
DelayMs(5);  RS_CLR;   RW_CLR;   EN_SET;   DataPort= com;   _nop_();   EN_CLR;
DelayUs2x(245);
void LCD_Write_Data(unsigned char Data)   {          }
/*------------------------------------------------                 清屏函数
------------------------------------------------*/  void LCD_Clear(void)   {     }
/*------------------------------------------------               写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)   {
if (y == 0)    {
LCD_Write_Com(0x80 + x);        }  else    {
LCD_Write_Com(0xC0 + x);        }          while (*s)    {
LCD_Write_Data( *s);       LCD_Write_Com(0x01);   DelayMs(5);  DelayMs(5);  RS_SET;   RW_CLR;   EN_SET;
DataPort= Data;   _nop_();  EN_CLR;
}
s ++;        }
/*------------------------------------------------               写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)   {                }
/*------------------------------------------------               初始化函数
------------------------------------------------*/  void LCD_Init(void)   {
LCD_Write_Com(0x38);    /*显示模式设置*/     DelayMs(5);
LCD_Write_Com(0x38);     DelayMs(5);
LCD_Write_Com(0x38);     DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08);    /*显示关闭*/     LCD_Write_Com(0x01);    /*显示清屏*/     LCD_Write_Com(0x06);    /*显示光标移动设置*/     DelayMs(5);
LCD_Write_Com(0x0C);    /*显示开及光标设置*/
if (y == 0)    {
LCD_Write_Com(0x80 + x);        }      else    {
LCD_Write_Com(0xC0 + x);        }
LCD_Write_Data( Data);
}
void LCD_Dis() {     switch(SBUF)  //pwm3 pwm4
左轮PWM        右轮PWM
{
case '1':LCD_Write_String(10,0,\"Toward  \");  break;//  case '2':LCD_Write_String(10,0,\"Backward\");  break;//  case '3':LCD_Write_String(10,0,\"Left    \");  break;//  case '4':LCD_Write_String(10,0,\"Right   \");  break;//  case '5':LCD_Write_String(10,0,\"Stop    \");  break;//  default: LCD_Write_String(10,0,\"INIT    \");   ;  break;
}
LCD_Write_String(6,0,num2char(Speed));
}
unsigned char str[3];
unsigned char *num2char(int num) {  unsigned char shi,ge,n;  shi=num/10;  ge=num%10;  n=0;  if(shi!=0)  {   str[n]=shi+48;
n++;
}
str[n]=ge+48;  n++;
str[n]='\\0';  return str;
}
前进后退左转右转停止     5 系统调试运行结果说明计分析
本系统在PC端win7系统下,使用KEIL2软件调试,C代码,运用STC烧录经KEIL2编译生成.hex文件,打开.hex文件实现在线调试仿真。 仿真时,设置内部时钟为11.0.92Mhz
电源模块接5V电压测得输出电压4.96V,通过串口助手,在波特率为600时,选择正确的com口,发送不同的case命令,通过改变C语言程序片段,可以实现以下功能:
最小系统,小车控制,码管显示模块
调试程序可以看到数码管上显示出直流电机对应的速度和方向,小车对应的实现正转、反转,左转,右转,停止功能。实现了实验预期的4个功能。
实验中:发现小车的转速不够,需要用手触碰一下才开始缓慢转动,分析原因后发现,因为电机驱动是依靠两个引脚中间的电位差,而实验中的电位差不够,无法产生足够的电流使得马达转速低,无法正常驱动,在更改占空比之后,小车转速慢的问题得到了解决。
6 结论
在焊接初期因为分析电路不仔细导致错误频出,多次不得不拆卸元件,经过慢慢地熟悉,焊接工作也渐渐步入正轨,有计划地布置电路元件,有规划地布线,最终焊完的板子并且进行调试,实现以下的功能:
1源模块:可以正常为电路供电。
2小系统模块:实现了芯片引脚的合理分配给数码管和小车的驱动模块。 3码管显示功能:显示小车前进速度,方向。 4车控制功能:转向,前进,后退,加速,停止。
本次实践电子电路系统基本成功实现题目设计要求功能。硬件电路焊接部分,总体布线整体性相对较好,调试过程中虽然出现过一定的障碍,但通过了解电路原理和合理的调试方法,也都得到了较好的解决。在实验中遇到了一些问题,经过思考与请教老师,得到了很好的解决。这也体现了对于一些知识的掌握不够透彻,以后还要多加练习,丰富自己的知识储备。