久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2035|回復: 6
打印 上一主題 下一主題
收起左側

STC8A單片機輸出任意路(8路以內)同頻率同占空比不同相位的pwm波怎么實現啊?求指點

[復制鏈接]
回帖獎勵 5 黑幣 回復本帖可獲得 5 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
用定時器1查詢延時和中斷延時都試過了,示波器上顯示的都是相位一樣的PWM波。求大神指點。每路的相位差值是打算弄成(一個周期的時間/pwm路數)。
PWM波是直接用STC8A上pwm寄存器生成的代碼如下(這個生成pwm波應該沒有問題示波器上顯示是正確的):
void PWM_init(int pin,long f,int pwm)  //PWM初始化函數
{
        switch(pin%10)
        {
                case 0:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==10) PWM0CR=0x08;
                        if(pin==20) PWM0CR=0x00;
                        if(pin==60) PWM0CR=0x10;
                        PWM0_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數(精度)
                        PWMC = PWM0_T;                        //設置PWM周期時鐘數
                        PWM0T1= (long)pwm*PWM0_T/10000;              //PWM0在計數值為15000地方輸出低電平
                        PWM0T2= 0;                             //PWM0在計數值為0地方輸出高電平                        
                        PWM0CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 1:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==11) PWM1CR=0x08;
                        if(pin==21) PWM1CR=0x00;
                        if(pin==61) PWM1CR=0x10;
                        PWM1_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM1_T;                        //設置PWM周期時鐘數
                        PWM1T1= (long)pwm*PWM1_T/10000;              //PWM1在計數值為100H地方輸出低電平
                        PWM1T2= 0;                             //PWM1在計數值為700H地方輸出高電平                        
                        PWM1CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM1
                }
                case 2:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==12) PWM2CR=0x08;
                        if(pin==22) PWM2CR=0x00;
                        if(pin==62) PWM2CR=0x10;
                        PWM2_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM2_T;                        //設置PWM周期時鐘數
                        PWM2T1= (long)pwm*PWM2_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM2T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM2CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 3:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==13) PWM3CR=0x08;
                        if(pin==23) PWM3CR=0x00;
                        if(pin==63) PWM3CR=0x10;
                        PWM3_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM3_T;                        //設置PWM周期時鐘數
                        PWM3T1= (long)pwm*PWM3_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM3T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM3CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 4:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==14) PWM4CR=0x08;
                        if(pin==24) PWM4CR=0x00;
                        if(pin==64) PWM4CR=0x10;
                        PWM4_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM4_T;                        //設置PWM周期時鐘數
                        PWM4T1= (long)pwm*PWM4_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM4T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM4CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 5:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==15) PWM5CR=0x08;
                        if(pin==25) PWM5CR=0x00;
                        if(pin==65) PWM5CR=0x10;
                        PWM5_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM0_T;                        //設置PWM周期時鐘數
                        PWM5T1= (long)pwm*PWM5_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM5T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM5CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 6:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==16) PWM6CR=0x08;
                        if(pin==26) PWM6CR=0x00;
                        if(pin==66) PWM6CR=0x10;
                        PWM6_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM6_T;                        //設置PWM周期時鐘數
                        PWM6T1= (long)pwm*PWM6_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM6T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM6CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
                case 7:
                {
                        //STORE=P_SW2;
                        P_SW2 |= 0x80; //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1                        
                        PWMCKS = 0x0f;                              // PWM時鐘為系統時鐘/16 ,以適應不同PWM頻率。   
                        PWMCFG = 0x00;                                                                                          //PWM配置寄存器,PWM無中斷,PWM不與ADC關聯
                        if(pin==17) PWM7CR=0x08;
                        if(pin==27) PWM7CR=0x00;
                        if(pin==67) PWM7CR=0x10;
                        PWM7_T = Main_Fosc16/f;                   //計算PWM一個周期總脈沖數
                        PWMC = PWM7_T;                        //設置PWM周期時鐘數
                        PWM7T1= (long)pwm*PWM7_T/10000;              //PWM0在計數值為100H地方輸出低電平
                        PWM7T2= 0;                             //PWM0在計數值為700H地方輸出高電平                        
                        PWM7CR|=0x80;                          //使能PWM輸出
                        P_SW2  &= ~0x80;                       //PSW2寄存器最高位清0   
                        PWMCR  |= 0x80;   //使能PWM波形發生器,PWM計數器開始工作
                        break;   //PWM0
                }
        }        
}void PWM_change(int pin,int pwm)    //改變PWM模塊占空比
{
        //STORE=P_SW2;
        P_SW2 |= 0x80;  //以下寄存器為擴展sfr,訪問前需先將PSW2寄存器最高位置1        
        switch(pin%10)
        {
                case 0:        PWM0T1= (long)pwm*PWM0_T/10000;        //PWM0在計數值為100H地方輸出低電平
                                                break;
                case 1:        PWM1T1= (long)pwm*PWM1_T/10000;        //PWM1在計數值為100H地方輸出低電平                                       
                                                break;
                case 2:        PWM2T1= (long)pwm*PWM2_T/10000;        //PWM2在計數值為100H地方輸出低電平                                       
                                                break;
                case 3:        PWM3T1= (long)pwm*PWM3_T/10000;        //PWM3在計數值為100H地方輸出低電平                                       
                                                break;
                case 4:        PWM4T1= (long)pwm*PWM4_T/10000;        //PWM4在計數值為100H地方輸出低電平
                                                break;
                case 5:        PWM5T1= (long)pwm*PWM5_T/10000;        //PWM5在計數值為100H地方輸出低電平
                                                break;
                case 6:        PWM6T1= (long)pwm*PWM6_T/10000;        //PWM6在計數值為100H地方輸出低電平
                                                break;
                case 7:        PWM7T1= (long)pwm*PWM7_T/10000;        //PWM7在計數值為100H地方輸出低電平
                                                break;
        }
        P_SW2  &= ~0x80;  //以上寄存器為擴展sfr,訪問后需將PSW2寄存器最高位置0
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2022-10-27 08:44 | 只看該作者
同頻就更好處理了:
設計有N個通道要做PWM,用變量TB計時PWM的周期,各通道再用變量TB1,TB2......,TBN計時負脈沖的時間。
用定時器定個基本時鐘,中斷服務程序做下列兩個動作:
1、對周期計時:TB-1。
PWM計滿時各通道清0,TB重置,TB1,TB2......,TBN復位置數成各自的負脈沖的時間。
2、如果TBx<>0,就 -1,當TBx計滿時(TBx=0時),x通道就置1,TBx不重置保持0。
如果TBx=0,就不處理了。
這樣就成了。程序很簡單。
回復

使用道具 舉報

板凳
ID:57657 發表于 2022-10-27 09:35 | 只看該作者
具體要看PWM控制什么,用邏輯分析儀捕捉。
回復

使用道具 舉報

地板
ID:1005634 發表于 2022-10-27 09:50 | 只看該作者
npn 發表于 2022-10-27 09:35
具體要看PWM控制什么,用邏輯分析儀捕捉。

作業 并沒有要求要控制什么,就是輸出一個相位差是周期時間/pwm路數的這么幾路pwm矩形波
回復

使用道具 舉報

5#
ID:491577 發表于 2022-10-27 10:30 | 只看該作者
你認真計算了嗎,你設置的PWM0-7全部都是一樣的。你連自己的算法都搞不清楚
回復

使用道具 舉報

6#
ID:1034262 發表于 2022-10-27 10:34 | 只看該作者
STC8A8K64S4A12 或 STC8A8K64D4做樓主要求的PWM太方便了。
8路增強型PWM都是15位長度,同頻率,每路PWM都可以獨立的設置輸出高電平和低電平的時刻,所以可以設置任意相位。
回復

使用道具 舉報

7#
ID:213173 發表于 2022-10-27 21:03 | 只看該作者
yjx156 發表于 2022-10-27 09:50
emmm課程作業 并沒有要求要控制什么,就是輸出一個相位差是周期時間/pwm路數的這么幾路pwm矩形波


就按這個套路可以增加N路同頻不同相PWM。
  1. #include<reg51.h>

  2. typedef unsigned int u16;
  3. typedef unsigned char u8;

  4. u8 i;

  5. sbit out1=P2^0;
  6. sbit out2=P2^1;
  7. sbit out3=P2^2;
  8. sbit out4=P2^3;


  9. void main()
  10. {   
  11.         TMOD= 0x01;                //設置定時器模式
  12.         TL0 = 0x18;                //設置定時初始值
  13.         TH0 = 0xFC;                //設置定時初始值
  14.         TF0 = 0;                //清除TF0標志
  15.         TR0 = 1;                //定時器0開始計時
  16.         ET0=1;        //開T0中斷
  17.         EA=1;        //開總中斷
  18.         while(1);
  19. }

  20. //定時器T1的中斷服務函數
  21. void T0_time()  interrupt 1
  22. {   
  23.         TL0 = 0x18;                //設置定時初始值
  24.         TH0 = 0xFC;                //設置定時初始值
  25.         switch(i)
  26.         {
  27.                 case 0: out1=~out1; break;
  28.                 case 1: out2=~out2; break;
  29.                 case 2: out3=~out3; break;
  30.                 case 3: out4=~out4; break;
  31.         }
  32.         i=++i%4;
  33. }
復制代碼



回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天夜天天操 | 欧美理论片在线观看 | 精品久久久久久久久久久 | 国产激情一区二区三区 | 亚洲最大福利网 | 播放一级黄色片 | av一区二区在线观看 | 国产精品久久精品 | 成人在线h| 亚洲精品一区二三区不卡 | 99精品网| 在线免费观看黄视频 | 日韩午夜| 女人毛片a毛片久久人人 | 亚洲国产精品99久久久久久久久 | 久久久这里只有17精品 | 不卡一区二区三区四区 | 国产精品久久久久久久久图文区 | 五月婷婷激情网 | 日本一区二区不卡视频 | 欧美日韩电影免费观看 | 99精品一区二区 | 国产98色在线 | 日韩 | 黄色成人免费在线观看 | 黄色免费网址大全 | 国产免费视频在线 | 国产中文字幕网 | 日本一区二区三区在线观看 | 欧美精品一区二区三区在线播放 | 色综合激情 | 精品国产一区一区二区三亚瑟 | 日本在线免费视频 | www久久久| 91免费在线看| 亚洲精品久久久一区二区三区 | 国产成人精品一区二区三区四区 | 精品视频免费在线 | 五月天婷婷久久 | 国产日韩欧美一区二区 | 亚洲区一 | 日韩视频一区二区在线 |