打印
[PIC®/AVR®/dsPIC®产品]

求助,单片机PIC16F877A模拟PWM输出程序,谢谢!

[复制链接]
2356|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gentleyidao|  楼主 | 2014-9-23 11:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 gentleyidao 于 2014-9-23 11:15 编辑

单片机PIC16F877A,由于CCP模块不够用,需模拟一个20KHz的占空比可调的PWM,时钟为20M。RB1---按键增加占空比(10%),RB2-----按键减少占空比(10%),PWM输出-----RC0。初学急用,请老师们赐教程序,谢谢!!!!!
沙发
Rain_King| | 2014-9-23 11:56 | 只看该作者
模拟???20KHZ的PWM,卧槽,你这程序基本就废了.....大概25us中断一次,中断里面还要处理几句话吧....你这程序几乎啥都不用做了....

使用特权

评论回复
板凳
Rain_King| | 2014-9-23 11:57 | 只看该作者
还占空比可调....那就说中断里面句子要更多.....唉,几乎就么得用了....

使用特权

评论回复
地板
mohanwei| | 2014-9-23 12:23 | 只看该作者
Rain_King 发表于 2014-9-23 11:56
模拟???20KHZ的PWM,卧槽,你这程序基本就废了.....大概25us中断一次,中断里面还要处理几句话吧....你 ...

不是你这么算的……
20KHz,周期是50us;现在还需要知道PWM分辨率……
从主贴描述估测为100(还不到7位分辨率)吧,那么定时中断周期就是:50us/100=0.5us
MCU每0.5us进入定时中断,刷新输出……几乎是不可能完成的任务

使用特权

评论回复
5
zhimagod| | 2014-9-23 12:56 | 只看该作者
20K周期是50us
每次变化10%就是1/10喽?5us入一次中断的
单片机时钟频率20M,指令频率就是5MHz,指令周期的话……0.2us对吧?
5us/0.2us=25
25个指令周期进入中断一次
虽然不是不可能,不过很玄,很极限了

使用特权

评论回复
6
Rain_King| | 2014-9-23 14:41 | 只看该作者
本帖最后由 Rain_King 于 2014-9-23 14:45 编辑
mohanwei 发表于 2014-9-23 12:23
不是你这么算的……
20KHz,周期是50us;现在还需要知道PWM分辨率……
从主贴描述估测为100(还不到7位分 ...

你这个是一个比较懒的占空比的分配(如果资源充足,这样分配比较好),为了比较好的设置而已.......取得一个最小公约数....可以改定时器的时间的嘛....,不过每次都改定时器时间,估计有点误差吧....

使用特权

评论回复
7
gentleyidao|  楼主 | 2014-9-24 09:16 | 只看该作者
谢谢大家的回复和指导分析,我也在网上搜索了一些程序,并做了下修改,但是按键无效,不知道哪儿出错了,请指导!
#define _16F877a
#include<pic.h>
//脚位定义***********************************************************
#define       key_up       RB1                      //按键输入(增加键)
#define       key_down     RB2                      //按键输入(减少键)
#define       PWM          RC0                      //输出指示

//*******************************************************************
//函数名称:port_init();
//输入参数:无
//输出参数:无
//功能描述:端口设置
//*****************************************************************
void PortInit(void)
{
     PORTB = 0xfd;                                         //   
     TRISB = 0xfd;                                         //B 口设置   
      
     PORTC = 0x00;                                         //
     TRISC = 0x00;                                         //C 口设置
}
  
//*******************************************************************
//函数名称:KeyInt(*p);
//输入参数:占空比地址
//输出参数:无
//功能描述:按键处理函数
//*******************************************************************
void KeyInt(unsigned char *p)
{     
     static bit valid = 0;                                 //有效标志
     static bit finish = 0;                                //完成标志
//按增加键处理  
     if (valid == 1)
      {
       if (key_up == 0)
        {
         if (finish == 0)
          {
           finish = 1;                                     //完成置位
            
           if (*p == 250)
            {
             *p = 0xFF;                                    //按键有效  
            }
   
           else
            {
             *p += 25;                                     //按键有效
            }
          }
        }
      
       else
        {
         valid = 0;                                        //有效清零
         finish = 0;                                       //完成清零  
        }   
      }
        
     else
      {
       if (key_up == 0) valid = 1;                            //有效置位
      }
//按减少键处理
    if (valid == 1)
      {
       if (key_down == 0)
        {
         if (finish == 0)
          {
           finish = 1;                                     //完成置位
            
           if (*p == 5)
            {
             *p = 0x01;                                    //按键有效  
            }
   
           else
            {
             *p -= 25;                                     //按键有效
            }
          }
        }
      
       else
        {
         valid = 0;                                        //有效清零
         finish = 0;                                       //完成清零  
        }   
      }
        
     else
      {
       if (key_down == 0) valid = 1;                            //有效置位
      }   
}

//*******************************************************************
//函数名称:LedPwm(Pwm);
//输入参数:占空比
//输出参数:无
//功能描述:led 脉冲调宽输出
//*******************************************************************
void LedPwm(unsigned char Pwm)
{
     unsigned char PwmH;
     unsigned char PwmL;
     unsigned char i;
   
      
     for (i = 0; i < 20; i++)
      {
       PwmH = Pwm;                                         //脉冲高位
       PwmL = 255 - PwmH;                                  //脉冲低位

       PWM = 1;                                            //  
       while (PwmH--);                                     //高位输出
      
       PWM = 0;                                            //  
       while (PwmL--);                                     //低位输出
      }         
}

//*******************************************************************
//函数名称:main();
//输入参数:无
//输出参数:无
//功能描述:主要程序
//*******************************************************************
void main(void)                                            //
{   
     unsigned char Pwm = 0x01;                             //占空初值      

     PortInit();                                           //脚位设置
     
     while (1)
      {
       KeyInt(&Pwm);                                       //按键处理
       LedPwm(Pwm);                                        //脉冲输出
      }   
}
另外不知道这个程序的PWM输出频率是多少?

使用特权

评论回复
8
gentleyidao|  楼主 | 2014-9-24 09:19 | 只看该作者
另外,模拟输出PWM信号的频率最高为20Khz,范围为0~20KHz,经大家分析,不知道频率在什么范围内比较好?

使用特权

评论回复
9
PIGYONG801| | 2014-9-24 10:31 | 只看该作者
用STM8吧,又便宜又多外设

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

7

帖子

0

粉丝