欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3793|回復: 0
收起左側

為什么89c52單片機不能用串口控制Pwm方波的占空比?

[復制鏈接]
ID:67093 發表于 2014-10-8 14:00 | 顯示全部樓層 |閱讀模式
各位大能:

我想編寫一個89c52下控制舵機運行的c程序,實現從串口逐次控制pwm方波占空比的功能。比如,從串口向單片機發送一次ff010aff后,方波的寬度就增大一點;發送多次ff010aff后,方波的寬度就可以增大到最多2毫秒。如果發送ff010bff,方波寬度就應該減小,發送多次ff010bff后,方波的寬度就可以減小到最少0.5毫秒。
我在網上找到了一個程序,把它修改了一下后用proteus仿真,但我發現并不能象我想的那樣逐次控制pwm方波:從串口輸出了命令ff010aff后,方波的寬度一下就變到2毫秒了,從串口輸出了命令ff010bff后,方波的寬度一下就變到0.5毫秒了。
我想請教各位大能,為什么我的程序不能象一些51的按鍵控制程序那樣逐次地控制pwm方波的寬度?如何修改才能達到目的呢?請各位不吝賜教。
下面是我的程序:附件里是我的proteus仿真文件。

#include<reg52.h>
#include<math.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar Buffer =0;      //從串口接收的數據
uint i=0,j,URTAReceivedCount=0,n=1;
uchar flag=0;
uchar data Tempdatatable[4],CommandDatatable[4];//數據包
sbit servo0=P0^0;

uchar serVal[2];
uint pwm[]={1382,1382,1382,1382,1382,1382,1382,1382}; //初始90度,(實際是1382.4,取整得1382)
uchar pwm_flag=0;
uint code ms0_5Con=461; //0.5ms計數 (實際是460.8,取整得461)
uint code ms2_5Con=2304; //2.5ms計數

/********************************************************************
* 名稱 : Delay_1ms()
* 功能 : 延時子程序,延時時間為 1ms * x
* 輸入 : x (延時一毫秒的個數)
* 輸出 : 無
***********************************************************************/
void Delay_1ms(uint i)//1ms延時
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}

/********************************************************************
* 名稱 : Send_Data()
* 功能 : 向上位機傳送字符
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Send_Data(uchar data type,uchar data cmd)
{
   uchar data Buffer[4];
      //構建數據包
      uchar *p;
    uint Send_Count=0;
       p = Buffer;
    Buffer[0]=0XFF;
    Buffer[1]=type;
    Buffer[2]=cmd;
    Buffer[3]=0XFF;
      
   while(1){
      if(*p==0XFF){
      Send_Count++;  //0XFF標志統計位
   }
    SBUF = *p;  //發送
   while(!TI)  //如果發送完畢,硬件會置位TI,等待發送完畢
   {
      _nop_();
     }
    p++;
   
    TI = 0;
    if(Send_Count == 2)  //當統計到兩次出現0XFF,則認為一個數據包發送完畢,跳出循環
   {
       TI = 0;
         break;
    }  
   }
}
/********************************************************************
* 名稱 : Com_Int()
* 功能 : 串口中斷子函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Com_Int(void) interrupt 4
{
uchar temp;
ES=0; //關串口中斷
    RI=0; //軟件清除接收中斷
temp=SBUF;
    if(temp==0XFF && URTAReceivedCount<2)
   {
     
   Tempdatatable[0]==0XFF;  //包頭
  URTAReceivedCount++;
   }
   else
   {
      Tempdatatable[n]=temp;
    n++;   
   }
   if(URTAReceivedCount==2)//包尾
  {
      Tempdatatable[0]=0XFF;
      Tempdatatable[3]=0XFF;
    n=1;
      URTAReceivedCount=0;  //組包完畢
   temp="";
   //Send_Data(Tempdatatable[1],Tempdatatable[2]);  //發送組成的數據包回去
  }
   CommandDatatable[0]=Tempdatatable[0];
   CommandDatatable[1]=Tempdatatable[1];
   CommandDatatable[2]=Tempdatatable[2];
   CommandDatatable[3]=Tempdatatable[3];
   ES=1;//開串口中斷
}
/********************************************************************
* 名稱 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中斷
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Com_Init(void)
{
      TMOD |= 0x20;
      PCON = 0x00;
      SCON = 0x50;   
      TH1 = 0xFd;    //設置波特率 9600
      TL1 = 0xFd;
      TR1 = 1;  //啟動定時器1
   
    ES = 1;  //開串口中斷
  EA = 1;  //開總中斷
  IT0=0;
   EX0=1;
}

/********************************************************************
* 功能 : 舵機PWM中斷初始化
***********************************************************************/
void Timer0Init() {
//0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
//2.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)  
TMOD |= 0x01;  //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
TH0=-ms2_5Con>>8;      //給定初值,17ms中斷
TL0=-ms2_5Con;
EA=1;            //總中斷打開
ET0=1;           //定時器0中斷打開
TR0=1;           //定時器0開關打開                                   
}

/********************************************************************
* 功能 : 舵機PWM中斷, //舵機控制函數 周期為20ms 一個循環20MS  = 8*2.5ms
***********************************************************************/
void SteeringGear() interrupt 1 {
     switch(pwm_flag)
     {
         case 1:  
    servo0=1;
    TH0=-pwm[0]>>8;
    TL0=-pwm[0];
    break;
         case 2:  
    servo0=0;
    TH0=-(ms2_5Con-pwm[0])>>8;
    TL0=-(ms2_5Con-pwm[0]);
    break;
   //...
   default:
    TH0=0xff;
    TL0=0x80;
    pwm_flag=0;         
   }
     pwm_flag++;
}

void SteeringGearUp(uchar i) {
     if(pwm>ms0_5Con)
  pwm=pwm-10;
}

void SteeringGearDown(uchar i) {
     if(pwm<ms2_5Con)
   pwm=pwm+10;
}

void main()
{   
   
     Delay_1ms(200);
     Com_Init();//串口初始化
    Timer0Init();//舵機初始化
   
   while(1)
   {
      if(CommandDatatable[0]==0XFF && CommandDatatable[3]==0XFF){

            switch (CommandDatatable[1])      //根據鍵值不同,執行不同的內容
           {
            case 0X01:    //類型位0X01,表明是舵機數據包,進入舵機case  
           switch(CommandDatatable[2]) {
              case 0X0A:
         SteeringGearUp(0);
                   break;
              case 0X0B:
          SteeringGearDown(0);
          break;
            }
            break;
        default :  TR0=0;TR2=0;
               break;
       }
     }
   }
}
drivertest01截圖00.png

driverictest01.rar

26.89 KB, 下載次數: 397, 下載積分: 黑幣 -5

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表