OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6204|回复: 5

51PWM怎么同时控制两侧轮子调速啊

[复制链接]

2

主题

5

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2019-6-4
在线时间
11 小时
发表于 2019-6-4 14:50:11 | 显示全部楼层 |阅读模式
1金钱
#include <math.h>
#include "STC12C5A60S2.H"
# include <intrins.h>  
#include "oled.h"
# define uchar unsigned  char
# define uint  unsigned  int
        sbit A=P0^4;
sbit BD=P0^5;
sbit C=P0^6;
sbit D=P0^7;
unsigned char SHU;
unsigned char temp;
/*  -------------函数声明开始---------------  */
void init_adc(unsigned ChannelInit);
uint get_adc(unsigned Channel);
  /*  -------------函数声明结束---------------  */
typedef unsigned int u16;

sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;


unsigned char code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
                                                //????????
unsigned char code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
                                                //0-f???
u8 disp[4];  
u8 code smgduan[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void delay(u16 i)  
{
    while(i--);
}


void datapros()
{

    static u8 i;
    if(i==50){
        i=0;
        temp =get_adc(1);
    }
    i++;  
    disp[0] = smgduan[temp/1000];
    disp[1] = smgduan[temp%1000/100];  
    disp[2] = smgduan[temp%1000%100/10];  
    disp[3] = smgduan[temp%1000%100%10];  
}

void DigDisplay()
{
    u8 i;  
    for(i=0;i<4;i++){
        switch(i){
            case(0)SA=0;LSB=0;LSC=0;break;
            case(1)SA=1;LSB=0;LSC=0;break;
            case(2)SA=0;LSB=1;LSC=0;break;
            case(3)SA=1;LSB=1;LSC=0;break;
        }
        P0 = disp[i];
        delay(100);
        P0 = 0x00;
    }
}



void init_adc(unsigned ChannelInit)
{  
        P1ASF = ChannelInit;    //AD功能寄存器,设置I/O口作为AD转换实用。使用P1.0口。  
        ADC_RES = 0;    //清理结果寄存器的值
  ADC_RESL = 0;    //清理结果寄存器的值  
        ADC_CONTR = 0xA0;   //开启AD电源并设置转换周期为540个时钟周期转换一次。             
delay(3600);
}

        uint get_adc(unsigned Channel)
{
        uint d=0;  
        ADC_CONTR = 0X88|Channel;
        _nop_();  
        _nop_();
        _nop_();  
        _nop_();
  while(!(ADC_CONTR & 0X10));  
        ADC_CONTR &= ~0X10;
        d |= ADC_RES;
  d <<= 2;
        d |= ADC_RESL;  
        return d;
}  

void BlueteethInit()
{
SM0=0;
        SM1=1;
        REN=1;
        EA=1;
        ES=1;
        TMOD|=0X20;
        TH1=0XFD;
        TL1=0XFD;
        TR1=1;
}



int a=1;
void main (void)
{
        int h=0;
BlueteethInit();
        init_adc(0x00);  
while(1)
{   

       
h=get_adc(0)/10;

SBUF=h;
        while(!TI);
        TI=0;
        h=get_adc(1)/10+110;

SBUF=h;
        while(!TI);
        TI=0;
        delay(500000);

}

}
这串代码貌似只能控制两轮同速的情况,我想要实现转弯,就必须分别控制左右轮的速度,分别控制就需要两个定时中断,定时器还要同时计时,请问应该如何改写代码来实现啊





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2019-6-4
在线时间
11 小时
 楼主| 发表于 2019-6-4 14:51:16 | 显示全部楼层
刚刚那个是控制器的代码,附上,小车上的代码
#include <reg52.h>
sbit PWMOUT = P0^0;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit A=P2^0;
sbit BD=P2^1;
sbit C=P2^2;
sbit D=P2^3;
unsigned char HighRH = 0; //高电平重载值的高字节
unsigned char HighRL = 0; //高电平重载值的低字节
unsigned char LowRH = 0; //低电平重载值的高字节
unsigned char LowRL = 0; //低电平重载值的低字节
int k = 0;
int temp = 0;
int temp2 = 0;
void ConfigPWM(unsigned int fr, unsigned char dc);
void ClosePWM();
//控制小车移动//
int stop()
{
                A=0;
        BD=0;
        C=0;
        D=0;
}

int go()
{
        A=0;
        BD=1;
        C=1;
        D=0;
}
int back()
{
        A=1;
        BD=0;
        C=0;
        D=1;
}
int leftgo()
{
        A=0;
        BD=1;
}
int rightgo()
{
        C=1;
        D=0;
}
int leftstop()
{
        A=0;
        BD=0;
}
int rightstop()
{
        C=0;
        D=0;
}
void InitUART()//串口初始化
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFd;
    TL1 = 0xFd;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;
}

void main()
{
                                InitUART();//串口初始化
                                                        while (1)
                        {
                                                        int i;
                                                        /*控制小车向前*/
                                                        if(k<67)
                                                        {
                                                        temp=k*2;
                                                        ConfigPWM(100,temp);
                                                        for (i=0; i<400; i++)
                                                        {
                                                        if(PWMOUT == 1)
                                                                go();
                                                        else
                                                                stop();
                                                        }
                                                  ClosePWM();
                                                        }
                                                        /*控制小车向后*/
                                                        if((k>67)&&(k<102))
                                                        {
                                                        temp=(k-50)*2;
                                                        ConfigPWM(100,temp);
                                                        for (i=0; i<400; i++)
                                                        {
                                                        if(PWMOUT == 1)
                                                                back();
                                                        else
                                                                stop();
                                                        }
                                                  ClosePWM();
                                                        }                                               
                                                        /*转弯*/
                                                        if((k>102)&&(k<160))
                                                        {
                                                        ConfigPWM(100,temp);
                                                        for (i=0; i<400; i++)
                                                        {
                                                        if(PWMOUT == 1)
                                                        {go();leftstop();}
                                                        else
                                                                stop();
                                                        }
                                                  ClosePWM();       
                                                        }
                                                        if(k>180)
                                                        {
                                                        ConfigPWM(100,temp);
                                                        for (i=0; i<400; i++)
                                                        {
                                                        if(PWMOUT == 1)
                                                        {go();rightstop();}
                                                        else
                                                                stop();
                                                        }
                                                  ClosePWM();       
                                                        }
                                                }
                       
    }

/* 配置并启动 PWM,fr-频率,dc-占空比 */
void ConfigPWM(unsigned int fr, unsigned char dc){
    unsigned int high, low;
    unsigned long tmp;
   
    tmp = (11059200/12) / fr; //计算一个周期所需的计数值
    high = (tmp*dc) / 100; //计算高电平所需的计数值
    low = tmp - high; //计算低电平所需的计数值
    high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时
    low = 65536 - low + 12;//计算低电平的重载值并补偿中断延时
   
    HighRH = (unsigned char)(high>>8); //高电平重载值拆分为高低字节
    HighRL = (unsigned char)high;
    LowRH = (unsigned char)(low>>8); //低电平重载值拆分为高低字节
    LowRL = (unsigned char)low;
   
    TMOD &= 0xF0; //清零 T0 的控制位
    TMOD |= 0x01; //配置 T0 为模式 1
    TH0 = HighRH; //加载 T0 重载值
    TL0 = HighRL;
    ET0 = 1; //使能 T0 中断
    TR0 = 1; //启动 T0
    PWMOUT = 1; //输出高电平
       
}
/* 关闭 PWM */
void ClosePWM(){
    TR0 = 0; //停止定时器
    ET0 = 0; //禁止中断
    PWMOUT = 1; //输出高电平

}
/* T0 中断服务函数,产生 PWM 输出 */
void InterruptTimer0() interrupt 1{
    if (PWMOUT == 1){ //当前输出为高电平时,装载低电平值并输出低电平
        TH0 = LowRH;
        TL0 = LowRL;
        PWMOUT = 0;

    }else{ //当前输出为低电平时,装载高电平值并输出高电平
        TH0 = HighRH;
        TL0 = HighRL;
        PWMOUT = 1;
               
                       
    }
}

void UARTInterrupt(void) interrupt 4
{        
                k=SBUF;
                RI = 0;
                SBUF= k;//???????????????
                while(!TI);                         //????????
                TI=0;                                                 //?????????
   
}
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10553
金钱
10553
注册时间
2017-2-18
在线时间
1910 小时
发表于 2019-6-4 17:37:08 | 显示全部楼层
帮顶~~
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-11-1 10:48:43 | 显示全部楼层
要同时控制,肯定要同时给控制那两个轮子的IO口同时赋予占空比值啊
回复

使用道具 举报

5

主题

47

帖子

0

精华

高级会员

Rank: 4

积分
680
金钱
680
注册时间
2019-5-18
在线时间
101 小时
发表于 2019-11-1 10:52:37 | 显示全部楼层
一个定时器就可以了,实现转弯就是让一个轮子不转,另一个轮子转。你同时给控制两个轮子的IO口,一个赋定时器值,一个赋0。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2019-11-9 17:26:57 | 显示全部楼层
delay(500000);

这个代码的存在,基本上没有办法解决这个问题.先学习一下如何不使用DLEAY函数,把功能实现,这样子.你说的问题也就不存在了.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-1 04:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表