找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机ADC准换的值作为PWM的占空比!弄很久一直没有弄出来!

[复制链接]
跳转到指定楼层
楼主
ID:655504 发表于 2020-5-5 09:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
求大佬帮看一下,ADC准换的值作为PWM的占空比!弄很久一直没有弄出来!时钟用的单片机内部22.1184mhz  身边没有示波器!ADC已通过串口调试过了没有问题!唯独PWM没有搞定,还有一个问题想请教一下大佬们,直流电机用PWM调速一般用多大的频率合适?STC8位PWM如果采用定时器0的溢出值作为PCA的时钟,那么定时器的初始值该怎么计算,之前参考过好多篇文章,始终没有解决   源程序已经打包了,所以在这里求一个具体的计算方法   最后谢谢各位大佬了!!!
  1. #include <STC8.H>
  2. #include <math.h>
  3. #include <uart.H>        // 导入串口库文件
  4. //#include <PWM.H>
  5. #include <intrins.h>
  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. void adc_init(void);
  9. void delay100ms(void);  //误差 -0.000000000013us
  10. void PWM_init(void);
  11. void PWM_u8init(void);
  12. void PWM_set(uchar PWM);
  13. void InitTimer0(void);
  14. #define uchar unsigned char
  15. #define uint unsigned int
  16. sbit PWM = P1^1;
  17. /******************************************************************

  18.                                                 主函数

  19. ******************************************************************/
  20. char Data;

  21. void main(void)
  22. {
  23.         AUXR = AUXR|0x80;  // T0, 1T Mode
  24.         InitTimer0();
  25.         adc_init(); //ADC 初始化
  26.         UartInit(); // Uart 初始化
  27. //        PWM_init();
  28.         PWM_u8init();
  29.         UartSendStr("Uart test\r\t");//Uart 发送测试
  30.         while(1)
  31.         {
  32. //                SBUF = Data;
  33.                 PWM_set(Data);
  34. //                PWM = 1;
  35. //                delay100ms();   
  36. //                PWM = 0;
  37.                 delay100ms();
  38.         }
  39. }


  40. /******************************************************************

  41.                                         ADC启动函数

  42. ******************************************************************/


  43. void adc_init(void)
  44. {
  45.         P1M0 = 0x00;
  46.         P1M1 = 0x01;       //设置P1.0口为高阻输入
  47.         ADC_CONTR = 0x80; // 打开ADC电源    P1.0作为ADC转换引脚
  48.         ADCCFG  = 0x0f;
  49.         EADC = 1;        // 打开ADC 中断
  50.         EA = 1;          // 打开总中断
  51.         ADC_CONTR |= 0x40;//启动ADC转换
  52. }


  53. /******************************************************************

  54.                                         ADC中断函数

  55. ******************************************************************/
  56. void adc_zhonduan() interrupt 5 using 1
  57. {
  58.         ADC_CONTR &= ~0x20;//清楚ADC中断溢出标志位
  59.         Data = ADC_RES;//P2读取ADC的值
  60.         ADC_CONTR |=0x40;//继续ADC转换
  61. }

  62. /******************************************************************

  63.                                         软件延时函数

  64. ******************************************************************/

  65. void delay100ms(void)   //误差 -0.000000000013us
  66. {
  67.     unsigned char a,b,c;
  68.     for(c=254;c>0;c--)
  69.         for(b=229;b>0;b--)
  70.             for(a=8;a>0;a--);
  71.     _nop_();  
  72.     _nop_();  
  73. }

  74. /******************************************************************

  75.                                         PWM初始化函数
  76.                                            16位PWM

  77. ******************************************************************/
  78. void PWM_init(void)
  79. {
  80.         P_SW2 = 0x80;
  81.         PWMCKS = 0x00;      //PWM时钟为系统时钟
  82.         PWMC = 0x5667;      //设置PWM周期为1000H个PWM时钟    约1khz
  83.         PWM0T1 = 0x5215;        //在计数值为100h地方输出低电平
  84.         PWM0T2 = 0x0452;        //在计数值为500h地方输出高电平
  85.         PWM0CR = 0x80;        //使能
  86.         P_SW2 = 0x00;
  87.         PWMCR = 0x80;        //启动PWM模块
  88. }


  89. /******************************************************************

  90.                                         PWM初始化函数
  91.                                            8位PWM
  92. *******************************************************************
  93.                                         寄存器说明
  94. CCON  PCA控制寄存器
  95. B7        B6        B5        B4        B3        B2        B1        B0
  96. CF        CR        -        -        CCF3        CCF2        CCF1        CCF0
  97. CF;计数器溢出中断标志
  98. CR:PCA计数允许位(1/on)
  99. CCFn:PCA模块中断标志

  100. ********************************************************************
  101. CMOD  PCA模式寄存器
  102. B7        B6        B5        B4        B3        B2        B1        B0
  103. CIDL -         -         -           CPS[2:0]        ECF
  104. CIDL  空闲模式下是否停止计数  0继续,1停止
  105. CPS[2:0]:PCA的输入时钟  【000|系统时钟/12】【001|系统时钟/2】【010|定时器0的溢出脉冲】【100|系统时钟】
  106. ECF:PCA计数器溢出中断允许位  0禁止,1允许

  107. ********************************************************************
  108. CCAPMN  PCA模块模式控制寄存器
  109. B7        B6                B5                B4                B3                B2                B1                B0
  110. -   ECOM0    CCAPP0                CCAPN0        MAT0         TOG0                PWM0                ECCF0
  111. ECOMn:允许PCA模块n的比较功能
  112. CCAPPN:允许PCA模块n进行上升沿捕获
  113. CCAPNn:允许PCA模块n进行下降沿捕获
  114. MATn:允许PCA的匹配功能
  115. TOG0:允许PCA模块n的高速脉冲是输出功能
  116. PWMn:允许PCA模块n的脉宽输出调制功能
  117. ECCFn:允许PCA模块n的匹配/捕获中断
  118. ******************************************************************/

  119. void PWM_u8init(void)
  120. {
  121.         CCON = 0x00;        
  122.                                        
  123.         CMOD = 0x08;        //PCA时钟为系统时钟
  124.         CL = 0x00;
  125.         CH = 0x00;
  126.         CCAPM0 = 0x42;                //PCA模块0为PWM工作方式
  127.         PCA_PWM0 = 0x00;   //PCA模块0输出8位PWM
  128.         CCAP0L = 0x10;     // 占空比
  129.         CCAP0H = 0x10;     //占空比
  130.         CR = 1;            //启动PCA计时器
  131. }


  132. /*********************************************************************************************
  133. 函数名:PWM占空比设置函数
  134. 调  用:PWM_set(uchar PWM);
  135. 参  数:无
  136. 返回值:无
  137. 结  果:无
  138. 备  注:无
  139. /**********************************************************************************************/
  140. void PWM_set(uchar PWM)
  141. {
  142.         CCAP0L = PWM;     // 占空比
  143.         CCAP0H = PWM;     //占空比
  144. }


  145. /*********************************************************************************************
  146. 函数名:定时器初始化函数
  147. 调  用:InitTimer0();
  148. 参  数:无
  149. 返回值:无
  150. 结  果:将定时器计数器初始化为定时器,工作方式0
  151. 备  注:无
  152. /**********************************************************************************************/

  153. void InitTimer0(void)
  154. {
  155.     TMOD = 0x00;
  156.     TH0 = (65536-86)/256;//1khz
  157.     TL0 = (65536-86)%256;
  158.     EA = 1;
  159.     ET0 = 1;
  160.     TR0 = 1;
  161. }

  162. /*********************************************************************************************
  163. 函数名:定时器0中断处理函数
  164. 调  用:无需调用
  165. 参  数:无
  166. 返回值:无
  167. 结  果:无
  168. 备  注:无
  169. /**********************************************************************************************/
  170. void Timer0Interrupt(void) interrupt 1
  171. {
  172.     TH0 = (65536-86)/256;
  173.     TL0 = (65536-86)%256;
  174. }



复制代码


ADC.zip

75.31 KB, 下载次数: 8

源程序

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

使用道具 举报

沙发
ID:655504 发表于 2020-5-5 09:39 | 只看该作者
发出的程序格式乱了,就请各位大佬看一下源程序把,谢谢大家了
回复

使用道具 举报

板凳
ID:655504 发表于 2020-5-6 16:56 | 只看该作者
不要沉了呀,我顶
回复

使用道具 举报

地板
ID:213173 发表于 2020-5-7 08:22 | 只看该作者
不用写那么多,就把STC的ADC和PWM官方示例整合一下就行。以下程序只是提供编程思路,不代表可以直接使用。
#include <STC8.H>
#include "intrins.h"

void delay100ms(void)
{
    unsigned char a,b,c;
    for(c=254;c>0;c--)
        for(b=229;b>0;b--)
            for(a=8;a>0;a--);
    _nop_();  
    _nop_();  
}

void main()
{
        //初始化PWM
        CCON = 0x00;
        CMOD = 0x08;                                //PCA时钟为系统时钟
        CL = 0x00;
        CH = 0x00;       
        CCAPM0 = 0x42;                              //PCA模块0为PWM工作模式
        PCA_PWM0 = 0x00;                            //PCA模块0输出8位PWM
        CCAP0L = 0xff;                              //PWM占空比为0%
        CCAP0H = 0xff;
        CR = 1;                                     //启动PCA计时器
        //初始化ADC
        P1M0 = 0x00;                                //设置P1.0为ADC口
        P1M1 = 0x01;
        ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16/16
        ADC_CONTR = 0x80;                           //使能ADC模块
       
        while (1)
        {
                ADC_CONTR |= 0x40;                      //启动AD转换
                _nop_();
                _nop_();
                while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
                ADC_CONTR &= ~0x20;                     //清完成标志

                CCAP0H = ADC_RES;                       //读取ADC结果控制PWM,默认P0.0输出
//                CCAP0H = ~ADC_RES;                      //读取ADC结果取反控制PWM
                delay100ms();
        }
}
回复

使用道具 举报

5#
ID:261802 发表于 2020-5-13 23:33 | 只看该作者
楼主,我想产生10khz的pwm波应该怎么修改呢?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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