weixin_52317575 2023-06-05 19:17 采纳率: 0%
浏览 21

有没有会九齐的大•神指导下

写的是pwm输出,但是需要经常改变波形。
用仿真器在我使用的电脑上边出来波形是正常的和我算的差不多有一点偏差但是问题不大
烧上芯片在芯片上读pwm输出就变得不准很奇怪。
我使用的是8M/2T/16分频 就像定一个周期600高电平480的,他在芯片真正跑的时候出来时变成周期600或者650 高电平450/500,我就很疑惑不知道是哪里出了问题

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-06-05 22:22
    关注
    • 这篇博客: 简单易上手 51蓝牙 PWM调速 避障 循迹小车(最强小车)中的 三、软件 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 完整代码可在本文末尾下载

      main.c

      #include <REGX52.H>
      #include "UART.h"
      #include "Timer0.h"
      #include "Nixie.h"
      #include "Delay.h"
      
      sbit IN1 = P1^0; // 左上
      sbit IN2 = P1^1; // 左下
      sbit IN3 = P1^2; // 右上
      sbit IN4 = P1^3; // 右上
      sbit ENA = P2^6; //使能A
      sbit ENB = P2^7; //使能B
      
      sbit out0 = P2^0; // 右边避障,有障碍物就亮,输出0
      sbit out1 = P2^1; // 左边避障,有障碍物就亮,输出0
      
      sbit outleft = P1^6; //左边循迹,亮灯返回值为1
      sbit outright = P1^7; //右边循迹,检测到黑线灭灯,返回0
      
      unsigned char PWM; //PWM波
      unsigned char date;//输入缓冲区
      static unsigned char speed = 100; //设置速度初始值
      
      void stop() // 停
      {
      	IN1=0;
      	IN2=0;
      	IN3=0;
      	IN4=0;
      }
      
      void forward() // 向前
      {
      	IN1=1;
      	IN2=0;
      	IN3=1;
      	IN4=0;	  
      }
      
      void back() // 向后
      {
      	IN1=0;
      	IN2=1;
      	IN3=0;
      	IN4=1;	
      }
      
      void left() // 向左,只有左轮动
      {
      	IN1=1;
      	IN2=0;
      	IN3=1;
      	IN4=1;
      }
      
      void avoid_left()//向左,左右伦同时转动
      {
      	IN1=1;
      	IN2=0;
      	IN3=0;
      	IN4=1;
      }
      
      void right() // 向右,只有右轮动
      {
      	IN1=1;
      	IN2=1;
      	IN3=1;
      	IN4=0;
      }
      
      void avoid_right()//向左,左右伦同时转动
      {
      	IN1=0;
      	IN2=1;
      	IN3=1;
      	IN4=0;
      }
      
      void increase(void)//加速
      {
      	speed += 5; // 每次增加5
      	if(speed >= 100) // 上限是100
      	{
      		speed = 100;
      	}
      }
      	
      void reduce(void)//减速
      {
      	speed -= 5; // 每次减少5
      	if(speed <= 0) // 下限是0
      	{
      		speed = 0;
      	}
      }
      
      void avoid(void)//避障模式
      {
      	if(out0 == 0) // 右边有障碍物,左转
      	{
      		avoid_left();
      	}
      	if(out1 == 0) // 左边有障碍物,右转
      	{
      		avoid_right();
      	}
      	if(out0 == 1 && out1 == 1) // 没有障碍物,前进
      	{
      		 forward();
      	}
      	if(out0 == 0 && out1 == 0) // 有障碍物,停止
      	{
      		 stop();
      	}
      }
      
      void Follow_the_trail (void)
      {
      	if(outleft == 0 && outright == 0)//悬空,停止移动
      	{
      		stop();
      	}
      	if(outleft == 1 && outright == 1) //在赛道上,直线行驶
      	{
      		forward();
      	}
      	if(outleft == 1 && outright == 0) //偏离赛道向右,因向左行驶
      	{
      		left();
      	}
      	if(outleft == 0 && outright == 1) //偏离赛道向左,因向右行驶
      	{
      		right();
      	}
      }
      
      //串口中断
      void Time_Int () interrupt 4
      {
      	if(RI == 1) // RI为1时软件置0
      	{
      		RI = 0; // 清除接受标志
      		date = SBUF; // 接收数据缓存在date中
      		switch (date)
      		{
      			case ('1'):
      			{
      				forward();
      				break;
      			}
      			case ('2'):
      			{
      				back();
      				break;
      			}
      			case ('3'):
      			{
      				left();
      				break;
      			}
      			case ('4'):
      			{
      				right();
      				break;
      			}
      			case ('0'):
      			{
      				stop();
      				break;
      			}
      			case ('5'):
      			{
      				increase();
      				break;
      			}
      			case ('6'):
      			{
      				reduce();
      				break;
      			}
      		}
      	}
      }
      
      //定时器0
      void time_control() interrupt 1
      	{
      		TL0 = 0x66;		//设置定时初值
      		TH0 = 0xFC;		//设置定时初值
      		PWM++;
      		if (PWM == 100)
      		{
      			PWM = 0;
      		}
      		if(PWM <= speed)//大于PWM波则打开使能
      		{
      			ENA = 1;
      			ENB = 1;
      		}
      		if(PWM > speed)//小于PWM波则关闭使能
      		{
      			ENA = 0;
      			ENB = 0;
      		}
      	}
      
      void main ()
      {
      	UsartConfiguration(); // 串口初始化
      	Timer0Init();//定时器0初始化
      	while(1)
      	{
      		//在数码管可以看到当前的速度是多少
      		Nixie(1, speed/100);
      		Delay(5);
      		Nixie(2, (speed/10)%10);
      		Delay(5);
      		Nixie(3, speed%10);
      		Delay(5);
      		//启动避障模式,将此模式存放在主函数当中
      		if(date == '7')
      		{
      			avoid();
      		}
      		//启动循迹模式,将此模式存放在主函数当中
      		if(date == '8')
      		{
      			Follow_the_trail();
      		}
      	}
      }

      UART.h(中断)

      #ifndef __UART_H__
      #define __UART_H__
      
      void UsartConfiguration(void);
      void UART_SendByte(unsigned char byte);
      
      #endif

      UART.c

      #include <REGX52.H>
      
      /**
         * @brief  串口初始化,9600bps@11.0592MHz
         * @param  无
         * @retval 无
         */
      
      void UsartConfiguration(void)		//9600bps@11.0592MHz
      {
      	PCON &= 0x7F;		//波特率不倍速
      	SCON = 0x50;		//8位数据,可变波特率
      	TMOD &= 0x0F;		//清除定时器1模式位
      	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
      	TL1 = 0xFD;		//设定定时初值
      	TH1 = 0xFD;		//设定定时器重装值
      	ET1 = 0;		//禁止定时器1中断
      	TR1 = 1;		//启动定时器1
      	ES = 1;        //开启串口中断
          EA = 1; 		//开启总中断
      }
      
      /**
         * @brief  串口发送一个字节数据
         * @param  byte 是接收的数据
         * @retval 无
         */
      
      void UART_SendByte(unsigned char byte)
      {
      	SBUF = byte;
      	while (TI == 0);
      	TI = 0;
      }

      Timer0.h(定时器0)

      #ifndef __TIMER0_H__
      #define __TIMER0_H__
      
      void Timer0Init(void);
      
      #endif

      Timer0.c

      #include <REGX52.H>
      
      /**
         * @brief  定时器0,1毫秒@11.0592MHz
         * @param  无
         * @retval 无
         */
      
      void Timer0Init(void)		//1毫秒@11.0592MHz
      {
      	TMOD &= 0xF0;		//设置定时器模式
      	TMOD |= 0x01;		//设置定时器模式
      	TL0 = 0x66;		//设置定时初值
      	TH0 = 0xFC;		//设置定时初值
      	TF0 = 0;		//清除TF0标志
      	TR0 = 1;		//定时器0开始计时
      	ET0 = 1;		//定时器开关
      	EA = 1;			//总开关
      }
      
      
      
      /*模板
      	void time_control() interrupt 1
      	{
      		static unsigned int counst;//局部变量,静态变量,防止每次进入中断,都将counst置为0
      		TL0 = 0x66;		//设置定时初值
      		TH0 = 0xFC;		//设置定时初值
      		counst++;
      		if (counst == 1000)
      		{
      			counst = 0;
      			
      		}
      	
      	}
      */

      Nixie.h(数码管)

      #ifndef __NIXIE_H__
      #define __NIXIE_H__
      
      void Nixie(unsigned char Location,Number);
      
      #endif
      

      Nixie.c

      #include <REGX52.H>
      #include "Delay.h"
      
      //数码管段码表
      unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
      
      /**
        * @brief  数码管显示
        * @param  Location 要显示的位置,范围:1~8
        * @param  Number 要显示的数字,范围:段码表索引范围
        * @retval 无
        */
      void Nixie(unsigned char Location,Number)
      {
      	switch(Location)		//位码输出
      	{
      		case 1:P2_4=1;P2_3=1;P2_2=1;break;
      		case 2:P2_4=1;P2_3=1;P2_2=0;break;
      		case 3:P2_4=1;P2_3=0;P2_2=1;break;
      		case 4:P2_4=1;P2_3=0;P2_2=0;break;
      		case 5:P2_4=0;P2_3=1;P2_2=1;break;
      		case 6:P2_4=0;P2_3=1;P2_2=0;break;
      		case 7:P2_4=0;P2_3=0;P2_2=1;break;
      		case 8:P2_4=0;P2_3=0;P2_2=0;break;
      	}
      	P0=NixieTable[Number];	//段码输出
      	Delay(1);				//显示一段时间
      	P0=0x00;				//段码清0,消影
      }
      

      Delay.h(延时)

      #ifndef __DELAY_H__
      #define __DELAY_H__
      
      void Delay(unsigned int xms);
      
      #endif
      

      Delay.c

      
      /**
        * @brief  毫秒延时
        * @param  xms输入的毫秒
        * @retval 无
        */
      void Delay(unsigned int xms)	//@11.0592MHz
      {
      	unsigned char i, j;
      	while(xms--)
      	{
      		i = 2;
      		j = 199;
      		do
      		{
      			while (--j);
      		} while (--i);
      	}
      }
      
      
      
      
      
    评论

报告相同问题?

问题事件

  • 创建了问题 6月5日

悬赏问题

  • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
  • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
  • ¥15 clousx6整点报时指令怎么写
  • ¥30 远程帮我安装软件及库文件
  • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
  • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
  • ¥15 Arduino的wifi连接,如何关闭低功耗模式?
  • ¥15 Android studio 无法定位adb是什么问题?
  • ¥15 C#连接不上服务器,
  • ¥15 angular项目错误