找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10901|回復: 11
打印 上一主題 下一主題
收起左側(cè)

發(fā)一個pwm直流電機調(diào)速程序,LCD段碼屏顯示的程序

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:77707 發(fā)表于 2015-4-22 13:34 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
寫這個程序是要實現(xiàn),用按鍵+,-使電機調(diào)速,并在LCD段碼屏上
出現(xiàn)累加的兩位數(shù)字顯示。
****************************************
段式LCD驅(qū)動和電機調(diào)速實驗            
外部晶體:12MHz                    
作者:dpj555                 
郵箱:            
日期:2015.03.26                  
******************************************/
#include <reg52.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
/*管腳定義*/
sbit COM1=P1^7;
sbit COM2=P1^6;
sbit BI_4=P1^5;
sbit RTC_CLK=P1^4;
sbit RTC_IO=P1^3;
sbit RTC_RST=P1^2;   //復用
/*P3口模式寄存器*/
sfr P3M1=0xb1;
sfr P3M0=0xb2;
/* 開機默認顯示*/
unsigned char ClockBuffer[8]={0x34,0x12,0x08,0x20,0x03,0x05,0x09};
/********************************
0~9的段碼查詢表
位序 D7 D6 D5 D4 D3 D2 D1 D0
段   A  B  C  D  E  F  G  DOT
*********************************/
code unsigned char seg_code[10]={~0x03,~0x9f,~0x25,~0x0d,~0x99,~0x49,~0x41,~0x1f,~0x01,~0x09};
unsigned char ScanCoun=0;                  //動態(tài)掃描顯示位數(shù)計數(shù)器
unsigned char DisplayBuf[2]={1,2 };               //2位數(shù)字對應(yīng)的顯示暫存
/*段碼緩沖區(qū)*/
unsigned char SegBuf[2]={0x00,0x00};//COM1、COM2 的段碼
bit bi_4a=0; //COM1對應(yīng)的4a
bit bi_4b=0; //COM2對應(yīng)的4b
/*延時*/
void dly(unsigned char x)
   {unsigned char i;
    for (i=0; i<x; i++);
    }
/*ds1302寫1字節(jié)*/
void rtc_wt_byte(unsigned char sent_buf)
         {unsigned char i;
          for (i=0; i<8; i++)
              {RTC_CLK=0;
               if (sent_buf&0x01) RTC_IO=1;
               else RTC_IO=0;
               RTC_CLK=1;
               dly(5);
               sent_buf=sent_buf>>1;
               }
              RTC_CLK=0;
              dly(5);
           }
/*ds1302讀1字節(jié)*/
unsigned char rtc_rd_byte(void)
          {unsigned char i,read_buf;
           RTC_IO=1;         //RTC_IO置1,保證為輸入狀態(tài)
           for (i=0; i<8; i++)
               {read_buf=read_buf>>1;
                       RTC_CLK=0;
                       dly(5);
                if (RTC_IO) read_buf=read_buf|0x80;
                else read_buf=read_buf&0x7f;
                RTC_CLK=1;
                dly(5);
               }
           RTC_CLK=0;
           dly(5);
           return read_buf;
          }
/*ds1302寫入時間*/
void rtc_wr_time(unsigned char *p_wt_time)
           {unsigned char i;
            unsigned char tmp1;
            dly(30);
            RTC_RST=1;
            rtc_wt_byte(0xbe);         //burst寫入時間
            for (i=0; i<8; i++)
                  {tmp1=*p_wt_time++;
                   rtc_wt_byte(tmp1);
                   }
            RTC_CLK=0;
            RTC_RST=0;
           }
/*ds1302讀出時間*/
void rtc_rd_time(unsigned char *p_rd_time)
           {unsigned char i;
            unsigned char tmp1;
            dly(30);
            RTC_RST=1;
            rtc_wt_byte(0xbf);        //burst讀取時間
            RTC_IO=1;
            for (i=0; i<8; i++)
                  {tmp1=rtc_rd_byte();
                   *p_rd_time++=tmp1;
                  }
            RTC_CLK=0;
            RTC_RST=0;
           }
/*ds1302初始化*/
void ini_rtc()
         {RTC_CLK=0;
          RTC_RST=0;
          dly(30);
          RTC_RST=1;               
          rtc_wt_byte(0x8e);        //寫CONTROL寄存器
          rtc_wt_byte(0x00);        //值:去掉寫保護
          RTC_RST=0;                //復位
          RTC_RST=1;                //正常工作
          rtc_wt_byte(0x90);        //寫TRICKLE CHARGER寄存器
          rtc_wt_byte(0xa9);        //值:使能充電,串聯(lián)2個二極管,串聯(lián)2k歐姆的電阻
          RTC_CLK=0;
          RTC_RST=0;
         }
/***********************************************************************************
把2位數(shù)字的SEG放到COM1、COM2 對應(yīng)的段碼
LCD的管腳定義與LED不同,它不是一個COM對應(yīng)一位數(shù)字,而是對應(yīng)每個數(shù)字的一部分SEG
1   2   3   4   5   6   7   8  
<  1f  1a  2f  2a      3f  3a  4f  4a   >          --       ---- COM1
<  1g  1b  2g  2b      2g  3b  4g  4b   >          --       ---- COM2
***********************************************************************************/
void Seg2Seg()
{unsigned char SegXX;

SegBuf[1]=0;
SegBuf[2]=0x08;
bi_4a=0;
bi_4b=0;
SegXX=seg_code[DisplayBuf[0]];      //第1位數(shù)字
if (SegXX&0x80) SegBuf[0]|=0x40;
if (SegXX&0x40) SegBuf[1]|=0x40;
if (SegXX&0x20) SegBuf[2]|=0x40;
if (SegXX&0x10) SegBuf[3]|=0x80;
if (SegXX&0x08) SegBuf[2]|=0x80;
if (SegXX&0x04) SegBuf[0]|=0x80;
if (SegXX&0x02) SegBuf[1]|=0x80;
if (SegXX&0x01) SegBuf[3]|=0x40;
  SegXX=seg_code[DisplayBuf[1]];    //第2位數(shù)字
if (SegXX&0x80) SegBuf[0]|=0x10;
if (SegXX&0x40) SegBuf[1]|=0x10;
if (SegXX&0x20) SegBuf[2]|=0x10;
if (SegXX&0x10) SegBuf[3]|=0x20;
if (SegXX&0x08) SegBuf[2]|=0x20;
if (SegXX&0x04) SegBuf[0]|=0x20;
if (SegXX&0x02) SegBuf[1]|=0x20;
if (SegXX&0x01) SegBuf[3]|=0x10;
}
/*一個BCD碼轉(zhuǎn)化成兩個十進制數(shù)(如:0x79轉(zhuǎn)化成0x07和0x09)*/
BcdToDec(unsigned char BcdValue,unsigned char *pDecValue)
       {//if (BcdValue>=0x9a||(BcdValue&0x0f)>=0x0a) return 0;
               *pDecValue++=(BcdValue&0xf0)>>2;
        *pDecValue=BcdValue&0x0f;
        //return 1;
       }
//初始化MCS51內(nèi)部資源
InitInterResource()
       {IE=0;       //關(guān)全部中斷
        TCON=0;     //清全部中斷請求
        IP=0;       //清中斷優(yōu)先級
        TMOD=0x01;  //T0工作方式1(16位定時器)
        TH0=0x00;   //T0定時器輔初值
        TL0=0x00;
        TR0=1;      //允許T0定時
        ET0=1;      //允許T0中斷
        EA=0;       //關(guān)全局中斷
        RTC_RST=0;
       }
void main()
    {   
     InitInterResource();
     ini_rtc();                    //初始化DS1302
     rtc_wr_time(ClockBuffer);     //寫入時間初始值
     EA=1;         //開全局中斷
     while(1)
        {         
        }
    }
//定時器0中斷服務(wù)程序,5ms定時器,4位數(shù)碼管動態(tài)顯示驅(qū)動
void tmr0_p(void) interrupt 1
    {
     TL0=0x78;     //重新定時5ms
     TH0=0xec;
     Seg2Seg();
     P3M1=0x3c;
     P3M0=0x00;
          switch(ScanCoun)                //動態(tài)掃描顯示
         {

          case 1:                       //COM1正向驅(qū)動
          P1= SegBuf[1];
          BI_4= bi_4a;
          COM1=0;            
          P3M1=0x2c;
          P3M0=0x00;
          break;
          case 2:                       //COM1反向驅(qū)動
          P1= ~SegBuf[1];
          BI_4= ~bi_4a;
          COM1=1;                  
          P3M1=0x2c;
          P3M0=0x00;
          break;
          case 3:                       //COM2正向驅(qū)動
          P1= SegBuf[2];
          BI_4= bi_4b;
          COM2=0;                  
          P3M1=0x34;
          P3M0=0x00;
          break;
          case 4:                       //COM2反向驅(qū)動
          P1= ~SegBuf[2];
          BI_4= ~bi_4b;
          COM2=1;                  
          P3M1=0x34;
          P3M0=0x00;
          break;
         }
     ScanCoun++;       //下一位
     if (ScanCoun>2) ScanCoun=0;      
     }
/*使單片機輸出PWM調(diào)速*/
/************************************************************************
為了使大家徹底掌握此方面,下面再給出一個復雜一點的程序,實現(xiàn)的功能為
通過按鍵使之可以在0到20級之間調(diào)速的程序。
/***********************************************************************/
/* 程序名:PWM直流電機調(diào)速 */
/* 晶振:11.00592 MHz CPU型號:STC12C2051 */
/* 直流電機的PWM波控制,可以通過按鍵控制正反轉(zhuǎn)并在0到20級之間調(diào)速 */
/*****************************************************************/
uchar time,count=50,flag=1;//低電平的占空比

sbit PWM1=P3^5;//PWM 通道 1,反轉(zhuǎn)脈沖
sbit PWM2=P3^7;//PWM 通道 2,正轉(zhuǎn)脈沖
sbit key_add=P1^1;//電機加速
sbit key_dec=P1^2;//電機減速
/************函數(shù)聲明**************/
void delayxms(uint z);
void Motor_turn();
void Motor_add();
void Motor_dec();
void timer0_init();
/****************延時處理**********************/
void delayxms(uint z)//延時xms程序
{
    uint x,y;
        for(y=z;x>0;x--)
        for(y=110;y>0;y--);
/*********主函數(shù)********************/
        timer0_init();
        while(1)
        
                Motor_turn();
                Motor_add();
                Motor_dec();
        
}
void Motor_add()//電機加速
{
        if(key_add==0)
        {
                  delayxms(2);//此處時間不能太長,否者會的中斷產(chǎn)生沖突
                  if(key_add==0)
                  {
                    count+=5;
                        if(count>=100)
                        {
                                count=0;
                        }
                  }
                  while(!key_add);
        }
}
void Motor_dec()//電機加減速
{
        if(key_dec==0)
        {
                  delayxms(2);//此處時間不能太長,否者會的中斷產(chǎn)生沖突
                  if(key_dec==0)
                  {
                    count-=5;
                        if(count>=100)
                        {
                                count=0;
                        }
                  }
                  while(!key_dec);
        }
}

/***********定時器0初始化***********/
void timer0_init()
{
        TMOD=0x01; //定時器0工作于方式1
        TH0=(65536-10)/256;
        TL0=(65536-10)%256;
        TR0=1;
        ET0=1;
        EA=1;
}
/**************定時0中斷處理******************/
void timer0_int() interrupt 1
{        
        TR0=0;//設(shè)置定時器初值期間,關(guān)閉定時器
        TH0=(65536-10)/256;
        TL0=(65536-10)%256;
        TR0=1;        
        if(flag==1)//電機正轉(zhuǎn)
        {
                PWM1=0;
                   time++;
                  if(time<count)
                  {
                    PWM2=1;
                  }
            else
            PWM2=0;
        
            if(time>=100)
            {
                    time=0;
            }
        }
        else //電機反轉(zhuǎn)
        {
                PWM2=0;
                  time++;
            if(time<count)
            {
                    PWM1=1;
            }
            else
                    PWM1=0;
            
            if(time>=100)
            {
                    time=0;
            }
        }
}

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的積分獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:77707 發(fā)表于 2015-4-22 14:09 | 只看該作者
再附張簡圖


回復

使用道具 舉報

板凳
ID:61876 發(fā)表于 2015-4-22 14:33 | 只看該作者
資料不錯 不過簡圖中的R2R3中間的一顆線 和R4R5中間的一顆線都接在P1.6上嗎?
回復

使用道具 舉報

地板
ID:76408 發(fā)表于 2015-4-22 20:40 | 只看該作者
最好有圖容易看得懂。
回復

使用道具 舉報

5#
ID:76408 發(fā)表于 2015-4-22 20:42 | 只看該作者
圖在下面沒注意到,對不起
回復

使用道具 舉報

6#
ID:77707 發(fā)表于 2015-4-23 09:06 | 只看該作者
gaozhaohong 發(fā)表于 2015-4-22 14:33
資料不錯 不過簡圖中的R2R3中間的一顆線 和R4R5中間的一顆線都接在P1.6上嗎?

抱歉!錯了應(yīng)該p1.7上有一個,給com2 位供2.5v電壓。
回復

使用道具 舉報

7#
ID:77707 發(fā)表于 2015-4-23 09:08 | 只看該作者
本帖最后由 dpj555 于 2015-4-24 08:14 編輯

更改后的圖


回復

使用道具 舉報

8#
ID:77707 發(fā)表于 2015-4-23 09:14 | 只看該作者
感謝版主加分鼓勵。
回復

使用道具 舉報

9#
ID:76929 發(fā)表于 2015-4-24 07:08 | 只看該作者
謝謝分享
回復

使用道具 舉報

10#
ID:71535 發(fā)表于 2015-4-24 07:59 | 只看該作者
感謝版主加分鼓勵
回復

使用道具 舉報

11#
ID:1095483 發(fā)表于 2023-11-10 18:05 | 只看該作者

感謝版主
回復

使用道具 舉報

12#
ID:1099381 發(fā)表于 2023-11-12 04:24 | 只看該作者
好資料,整好用的上
回復

使用道具 舉報

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

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

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