找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4745|回复: 16
打印 上一主题 下一主题
收起左侧

stc8a单片机10位PWM,0-1023,直接可以输出一个固定的PMW但是pwm10w++这样就不能0-1023

[复制链接]
跳转到指定楼层
楼主
ID:316880 发表于 2020-3-5 12:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "reg51.h"
#include "intrins.h"

typedef unsigned char u8;
typedef unsigned int u16;

u16 pwm10w;
sbit  P32 = P3^2;
sbit  P22 = P2^2;
//测试工作频率为11.0592MHz
sfr     P_SW1       =   0XA2;
sfr     CCON        =   0xd8;
sbit    CF          =   CCON^7;
sbit    CR          =   CCON^6;
sbit    CCF3        =   CCON^3;
sbit    CCF2        =   CCON^2;
sbit    CCF1        =   CCON^1;
sbit    CCF0        =   CCON^0;
sfr     CMOD        =   0xd9;
sfr     CL          =   0xe9;
sfr     CH          =   0xf9;
sfr     CCAPM0      =   0xda;
sfr     CCAP0L      =   0xea;
sfr     CCAP0H      =   0xfa;
sfr     PCA_PWM0    =   0xf2;
sfr     CCAPM1      =   0xdb;
sfr     CCAP1L      =   0xeb;
sfr     CCAP1H      =   0xfb;
sfr     PCA_PWM1    =   0xf3;
sfr     CCAPM2      =   0xdc;
sfr     CCAP2L      =   0xec;
sfr     CCAP2H      =   0xfc;
sfr     PCA_PWM2    =   0xf4;
sfr     CCAPM3      =   0xdd;
sfr     CCAP3L      =   0xed;
sfr     CCAP3H      =   0xfd;
sfr     PCA_PWM3    =   0xf5;
void Delay100ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 5;
        j = 52;
        k = 195;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}



void main()
{
    P_SW1 |=0X10;
    CCON = 0x00;
    CMOD = 0x08;                                //PCA时钟为系统时钟
    CL = 0x00;
    CH = 0x00;
    CCAPM0 = 0x42;                              //PCA模块0为PWM工作模式
    PCA_PWM0 = 0x80;                            //PCA模块0输出6位PWM
    CCAP0L = 0x20;                              //PWM占空比为50%[(40H-20H)/40H]
    CCAP0H = 0x20;
    CCAPM1 = 0x42;                              //PCA模块1为PWM工作模式
    PCA_PWM1 = 0x40;                            //PCA模块1输出7位PWM
    CCAP1L = 0x20;                              //PWM占空比为75%[(80H-20H)/80H]
    CCAP1H = 0x20;
    CCAPM2 = 0x42;                              //PCA模块2为PWM工作模式
    PCA_PWM2 = 0x00;                            //PCA模块2输出8位PWM
    CCAP2L = 0x20;                              //PWM占空比为87.5%[(100H-20H)/100H]
    CCAP2H = 0x20;
    CCAPM3 = 0x42;                              //PCA模块3为PWM工作模式
    PCA_PWM3 = 0xc0;                           //PCA模块3输出10位PWM
    CCAP3L = 0x20;                              //PWM占空比为96.875%[(400H-20H)/400H]
    CCAP3H = 0x20;



    CR = 1;                                     //启动PCA计时器

    while (1)
        {
                if(P32==0)
                {
                   Delay100ms();
                   //重载值更新
                   PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
                   //比较值更新
                   PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
               CCAP3L =pwm10w;//低8位CCAPnL[7:0],重载值低8位
                  if(++pwm10w>=1023)   pwm10w =0;
                }
       
                   if(P22==0)
                {
                   Delay100ms();
                   //重载值更新
                   PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
                   //比较值更新
                   PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
               CCAP3L =pwm10w;//低8位CCAPnL7:0],重载值低8位         
                 
                   if(pwm10w==0)   pwm10w =1023;
                   else                          pwm10w--;
                }
        }

}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:316880 发表于 2020-3-5 12:18 | 只看该作者
如何才能现实pwm10w 这个寄存器0-1023,电压0-5V可调,应该寄存器设置不对,还是赋值不对,pwm10w++清0以后就只能0-1.3V如何就清0了,还是0-5V, pwm10w--到0v,以后也是0-1.3v,到底是什么问题如何现实0-1023-0-1023,这样
回复

使用道具 举报

板凳
ID:267719 发表于 2020-3-5 14:39 | 只看该作者
u16 Dpwm10w;
                   if(pwm10w==1)   pwm10w =1024;
                   else                          pwm10w--;
                   Dpwm10w=pwm10w-1;
你用Dpwm10w不就结了?
回复

使用道具 举报

地板
ID:316880 发表于 2020-3-5 15:19 | 只看该作者
carpcarey 发表于 2020-3-5 14:39
u16 Dpwm10w;
                   if(pwm10w==1)   pwm10w =1024;
                   else              ...

      你这个试了也不行   
      
           //重载值更新
                   PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
                   //比较值更新
                   PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
               CCAP3L =pwm10w;//低8位CCAPnL7:0],重载值低8位   
   
              pwm10w  = 512;这样送数据可以出2.5V;
              但是想pwm10w++; pwm10w--;这样现实0-5V实现不了
回复

使用道具 举报

5#
ID:267719 发表于 2020-3-5 15:54 | 只看该作者
    while (1)
        {
                if(P32==0)
                {
                   Delay100ms();
                   //重载值更新
                   PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
                   //比较值更新
                   PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
               CCAP3L =pwm10w;//低8位CCAPnL[7:0],重载值低8位
               pwm10w++;
               pwm10w&=0x03ff;
                }
      
                   if(P22==0)
                {
                   Delay100ms();
                   //重载值更新
                   PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
                   //比较值更新
                   PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
               CCAP3L =pwm10w;//低8位CCAPnL7:0],重载值低8位         
                 
                   pwm10w--;
                   pwm10w&=0x03ff;
                }
        }
回复

使用道具 举报

6#
ID:267719 发表于 2020-3-5 18:57 | 只看该作者
    while (1)
    {
       if(P32==0)
       {
           Delay100ms();
           //重载值更新
           PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
           //比较值更新
           PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
           CCAP3L =pwm10w;//低8位CCAPnL[7:0],重载值低8位
           pwm10w++;
           pwm10w&=0x03ff;
        }
   
        if(P22==0)
        {
           Delay100ms();
           //重载值更新
           PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
           //比较值更新
           PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
           CCAP3L =pwm10w;//低8位CCAPnL7:0],重载值低8位         
           pwm10w--;
           pwm10w&=0x03ff;
        }
    }
你是这意思么?
回复

使用道具 举报

7#
ID:267719 发表于 2020-3-5 18:58 | 只看该作者
余生不负 发表于 2020-3-5 15:19
你这个试了也不行   
      
           //重载值更新

    while (1)
    {
       if(P32==0)
       {
           Delay100ms();
           //重载值更新
           PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
           //比较值更新
           PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
           CCAP3L =pwm10w;//低8位CCAPnL[7:0],重载值低8位
           pwm10w++;
           pwm10w&=0x03ff;
        }
   
        if(P22==0)
        {
           Delay100ms();
           //重载值更新
           PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
           //比较值更新
           PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
           CCAP3L =pwm10w;//低8位CCAPnL7:0],重载值低8位         
           pwm10w--;
           pwm10w&=0x03ff;
        }
    }
回复

使用道具 举报

8#
ID:316880 发表于 2020-3-5 22:36 | 只看该作者
carpcarey 发表于 2020-3-5 18:57
while (1)
    {
       if(P32==0)

太难了,10位的只能送固定数据,8位的CCAP3H = CCAP3L = 一个字节的数据++;   这样就可以了,10位的搞不了,实在不行就不研究了,搞了1天了,搞不定,看以后有没有大神遇到这样的问题在这留下正确答案了。
回复

使用道具 举报

9#
ID:316880 发表于 2020-3-5 22:38 | 只看该作者
carpcarey 发表于 2020-3-5 18:58
while (1)
    {
       if(P32==0)

   pwm10w--;
   pwm10w&=0x03ff;

这样也不行,直接就没反应了
回复

使用道具 举报

10#
ID:267719 发表于 2020-3-6 13:14 | 只看该作者
那就是你按键的问题了。去抖。你可以用排除法,先用程序控制,不用按键。看看占空比会不会变。
while (1)
    {
           for (i=0;i<10;i++)
           {
               Delay100ms();
           }
           //重载值更新
           PCA_PWM3|=(0x30&(pwm10w>>4));//高两位XCCAPnH[1:0],重载值高2位
           CCAP3H =pwm10w;//低8位CCAPnH[7:0],重载值低8位
           //比较值更新
           PCA_PWM3|=(0x0c&(pwm10w>>6));//高两位XCCAPnL[1:0],重载值高2位
           CCAP3L =pwm10w;//低8位CCAPnL[7:0],重载值低8位
           pwm10w++;
           pwm10w&=0x03ff;
   }
回复

使用道具 举报

11#
ID:316880 发表于 2020-3-6 14:33 | 只看该作者
carpcarey 发表于 2020-3-6 13:14
那就是你按键的问题了。去抖。你可以用排除法,先用程序控制,不用按键。看看占空比会不会变。
while (1)
...

我是一直按着按键不放的,应该不存在抖动这个问题,我用万用表一直测电压没有反应,没有反应的可能是没有限制,这个是双字节的寄存器,pwm10w++超了1023以后就过了,10位的范围吧,另外确实 试过很多方法仍然不行
回复

使用道具 举报

12#
ID:267719 发表于 2020-3-20 19:58 | 只看该作者
硬件电路提供下?一直测电压没有反应,那是多少伏?按键松了电压变不变?
回复

使用道具 举报

13#
ID:499088 发表于 2020-3-23 13:22 | 只看该作者
余生不负 发表于 2020-3-5 12:18
如何才能现实pwm10w 这个寄存器0-1023,电压0-5V可调,应该寄存器设置不对,还是赋值不对,pwm10w++清0以后 ...

                {
                        PCA_PWM3 = ((i>>4)&0x0030)|((i>>6)&0x000c)|0xc0;
                        CCAP3H = i;
                       
                }


你把i替换了就可以了,只赋装载值。
回复

使用道具 举报

14#
ID:316880 发表于 2020-3-24 12:30 | 只看该作者
carpcarey 发表于 2020-3-20 19:58
硬件电路提供下?一直测电压没有反应,那是多少伏?按键松了电压变不变?

注意我切换了IO口的,//  P_SW1 = 0x10;                               //ECI_2/P2.2, CCP0_2/P2.3, CCP1_2/P2.4, CCP2_2/P2.5,CCP3_2/P2.6, 看看参手册  按着按键就可以,




#include "reg51.h"
#include "intrins.h"


sfr     P_SW1       =   0xa2;
sfr     CCON        =   0xd8;
sbit    CF          =   CCON^7;
sbit    CR          =   CCON^6;
sbit    CCF3        =   CCON^3;
sbit    CCF2        =   CCON^2;
sbit    CCF1        =   CCON^1;
sbit    CCF0        =   CCON^0;
sfr     CMOD        =   0xd9;
sfr     CL          =   0xe9;
sfr     CH          =   0xf9;
sfr     CCAPM0      =   0xda;
sfr     CCAP0L      =   0xea;
sfr     CCAP0H      =   0xfa;
sfr     PCA_PWM0    =   0xf2;
sfr     CCAPM1      =   0xdb;
sfr     CCAP1L      =   0xeb;
sfr     CCAP1H      =   0xfb;
sfr     PCA_PWM1    =   0xf3;
sfr     CCAPM2      =   0xdc;
sfr     CCAP2L      =   0xec;
sfr     CCAP2H      =   0xfc;
sfr     PCA_PWM2    =   0xf4;
sfr     CCAPM3      =   0xdd;
sfr     CCAP3L      =   0xed;
sfr     CCAP3H      =   0xfd;
sfr     PCA_PWM3    =   0xf5;
unsigned char aa;
unsigned int aaa;
void main()
{
    P_SW1 = 0x10;            //ECI_2/P2.2, CCP0_2/P2.3, CCP1_2/P2.4, CCP2_2/P2.5,CCP3_2/P2.6
    CCON = 0x00;
        //        CMOD=0x08;                   //sysclk
        //        CMOD=0x02;                   //sysclk/2
        //        CMOD=0x0a;                   //sysclk/4
        //        CMOD=0x0c;                   //sysclk/6
        //        CMOD=0x0e;                   //sysclk/8
                CMOD=0x00;                   //sysclk/12
        //        CMOD=0x04;             //定时器T0溢出作为时钟源 可以做出频率可变
    CL = 0x00;
    CH = 0x00;

    CCAPM0 = 0x42;                              //PCA模块0为PWM工作模式
//    PCA_PWM0 = 0xc0;                            //PCA模块0输出10位PWM
//            PCA_PWM0 = 0xc0;                            //PCA模块0输出10位PWM
//                  PCA_PWM0 = 0xD4;                            //PCA模块0输出10位PWM
//            PCA_PWM0 = 0xE8;                            //PCA模块0输出10位PWM        
//            PCA_PWM0 = 0xFC;                            //PCA模块0输出10位PWM        
    CCAP0L = 0x20;                              //PWM占空比为96.875%[(400H-20H)/400H]
    CCAP0H = 0x20;
    CR = 1;                                     //启动PCA计时器
                 TMOD|=0X00;//选择为定时器0模式,工作方式1,。
        TL0 = 0x4C;                //设置定时初值
        TH0 = 0xFF;                //设置定时初值        
        ET0=1;//打开定时器0中断允许
        TR0=1;//打开定时器        //2毫秒@12.000MHz
                 EA=1;//打开总中断
    while (1)
                {

                }
}
void time1() interrupt 1                 //20毫秒@24.000MHz
  {          //uint a1;

        TL0 = 0xC0;                //设置定时初值
        TH0 = 0x63;                //设置定时初值
        aa++;
if(aa>5){aa=0;aaa++;}
if(aaa<256)         PCA_PWM0 = 0xc0;                            //PCA模块0输出10位PWM
if(aaa>256&&aaa<512)PCA_PWM0 = 0xd4;                            //PCA模块0输出10位PWM               
if(aaa>512&&aaa<768)PCA_PWM0 = 0xe8;                            //PCA模块0输出10位PWM        
if(aaa>768)         PCA_PWM0 = 0xfc;                            //PCA模块0输出10位PWM                        

    CCAP0L = aaa;
    CCAP0H = aaa;               
if(aaa>1023)aaa=0;               
}


这个可以0-1023,不过波形不太稳定,一会快一会慢,不是很明显
回复

使用道具 举报

15#
ID:499088 发表于 2020-3-24 22:54 | 只看该作者
CCAP0L = aaa;这个不要,你试一下看。
回复

使用道具 举报

16#
ID:681989 发表于 2021-5-6 17:20 | 只看该作者
看了下你程序,写的太复杂了,没必要,看规格书编写的,注意初始化IO设置脚为输出端口,默认是输入,硬件触摸按键,程序调试OK,
void Dimmer_PWMC(unsigned int DAT_PWM)          //PWM频率 = PCA时钟/1024 = 22.1184MHz/1024=21.6KHZ
{
        unsigned int FDD_PWM;
        unsigned char XCCAP0H;
        unsigned char XCCAP0L;
        FDD_PWM = 0X03FF - DAT_PWM;
        XCCAP0H = (FDD_PWM>>4)&0X30;
        XCCAP0L = (FDD_PWM>>6)&0X0C;
        if(FDD_PWM == 0X03FF)
            PCA_PWM0 |= 0x3f;
        else if(FDD_PWM == 0X0000)
                PCA_PWM0 &= 0xc0;       
        else
                PCA_PWM0 = (0xc0 | XCCAP0H | XCCAP0L);       
        CCAP0L = FDD_PWM&0XFF;                              
    CCAP0H = FDD_PWM&0XFF;
}
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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