找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 395|回复: 2
收起左侧

STC8H系列MCU的PWM做呼吸灯

[复制链接]
ID:961114 发表于 2024-3-20 10:13 | 显示全部楼层 |阅读模式
  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/

  4. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  5. /*---------------------------------------------------------------------*/


  6. /*************  功能说明    **************

  7. 本例程基于STC8H8K64U为主控芯片的实验箱9进行编写测试,STC8H系列芯片可通用参考.

  8. 高级PWM定时器 PWM1P/PWM1N,PWM2P/PWM2N,PWM3P/PWM3N,PWM4P/PWM4N 每个通道都可独立实现PWM输出,或者两两互补对称输出.

  9. 8个通道PWM设置对应P6的8个端口.

  10. 通过P6口上连接的8个LED灯,利用PWM实现呼吸灯效果.

  11. PWM周期和占空比可以根据需要自行设置,最高可达65535.

  12. 下载时, 选择时钟 24MHZ (用户可自行修改频率).

  13. ******************************************/

  14. #include "stc8h.h"       //包含此头文件后,不需要再包含"reg51.h"头文件
  15. #include "intrins.h"

  16. #define     MAIN_Fosc       24000000L   //定义主时钟

  17. typedef     unsigned char   u8;
  18. typedef     unsigned int    u16;
  19. typedef     unsigned long   u32;

  20. /****************************** 用户定义宏 ***********************************/

  21. #define Timer0_Reload   (65536UL -(MAIN_Fosc / 1000))       //Timer 0 中断频率, 1000次/秒

  22. /*****************************************************************************/

  23. #define PWM1_1      0x00        //P:P1.0  N:P1.1
  24. #define PWM1_2      0x01        //P:P2.0  N:P2.1
  25. #define PWM1_3      0x02        //P:P6.0  N:P6.1

  26. #define PWM2_1      0x00        //P:P1.2/P5.4  N:P1.3
  27. #define PWM2_2      0x04        //P:P2.2  N:P2.3
  28. #define PWM2_3      0x08        //P:P6.2  N:P6.3

  29. #define PWM3_1      0x00        //P:P1.4  N:P1.5
  30. #define PWM3_2      0x10        //P:P2.4  N:P2.5
  31. #define PWM3_3      0x20        //P:P6.4  N:P6.5

  32. #define PWM4_1      0x00        //P:P1.6  N:P1.7
  33. #define PWM4_2      0x40        //P:P2.6  N:P2.7
  34. #define PWM4_3      0x80        //P:P6.6  N:P6.7
  35. #define PWM4_4      0xC0        //P:P3.4  N:P3.3

  36. #define ENO1P       0x01
  37. #define ENO1N       0x02
  38. #define ENO2P       0x04
  39. #define ENO2N       0x08
  40. #define ENO3P       0x10
  41. #define ENO3N       0x20
  42. #define ENO4P       0x40
  43. #define ENO4N       0x80

  44. #define PWM_PERIOD  1023    //设置周期值

  45. /*************  本地变量声明    **************/
  46. bit B_1ms;          //1ms标志

  47. u16 PWM1_Duty;
  48. u16 PWM2_Duty;
  49. u16 PWM3_Duty;
  50. u16 PWM4_Duty;

  51. bit PWM1_Flag;
  52. bit PWM2_Flag;
  53. bit PWM3_Flag;
  54. bit PWM4_Flag;

  55. void UpdatePwm(void);

  56. /******************** 主函数 **************************/
  57. void main(void)
  58. {
  59.     P_SW2 |= 0x80;  //扩展寄存器(XFR)访问使能

  60.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  61.     P1M1 = 0x30;   P1M0 = 0x30;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
  62.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
  63.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  64.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  65.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  66.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  67.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

  68.     PWM1_Flag = 0;
  69.     PWM2_Flag = 0;
  70.     PWM3_Flag = 0;
  71.     PWM4_Flag = 0;

  72.     PWM1_Duty = 0;
  73.     PWM2_Duty = 256;
  74.     PWM3_Duty = 512;
  75.     PWM4_Duty = 1024;

  76.     //  Timer0初始化
  77.     AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
  78.     TH0 = (u8)(Timer0_Reload / 256);
  79.     TL0 = (u8)(Timer0_Reload % 256);
  80.     ET0 = 1;    //Timer0 interrupt enable
  81.     TR0 = 1;    //Tiner0 run

  82.     PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道
  83.     PWMA_CCER2 = 0x00;
  84.     PWMA_CCMR1 = 0x68; //通道模式配置
  85.     PWMA_CCMR2 = 0x68;
  86.     PWMA_CCMR3 = 0x68;
  87.     PWMA_CCMR4 = 0x68;
  88.     PWMA_CCER1 = 0x55; //配置通道输出使能和极性
  89.     PWMA_CCER2 = 0x55;

  90.     PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间
  91.     PWMA_ARRL = (u8)PWM_PERIOD;

  92.     PWMA_ENO = 0x00;
  93.     PWMA_ENO |= ENO1P; //使能输出
  94.     PWMA_ENO |= ENO1N; //使能输出
  95.     PWMA_ENO |= ENO2P; //使能输出
  96.     PWMA_ENO |= ENO2N; //使能输出
  97.     PWMA_ENO |= ENO3P; //使能输出
  98.     PWMA_ENO |= ENO3N; //使能输出
  99.     PWMA_ENO |= ENO4P; //使能输出
  100.     PWMA_ENO |= ENO4N; //使能输出

  101.     PWMA_PS = 0x00;  //高级 PWM 通道输出脚选择位
  102.     PWMA_PS |= PWM1_3; //选择 PWM1_3 通道
  103.     PWMA_PS |= PWM2_3; //选择 PWM2_3 通道
  104.     PWMA_PS |= PWM3_3; //选择 PWM3_3 通道
  105.     PWMA_PS |= PWM4_3; //选择 PWM4_3 通道

  106.     PWMA_BKR = 0x80; //使能主输出
  107.     PWMA_CR1 |= 0x01; //开始计时

  108.     P40 = 0;                //给LED供电
  109.     EA = 1;     //打开总中断

  110.     while (1)
  111.     {
  112.     }
  113. }


  114. /********************** Timer0 1ms中断函数 ************************/
  115. void timer0(void) interrupt 1
  116. {
  117.     if(!PWM1_Flag)
  118.     {
  119.         PWM1_Duty++;
  120.         if(PWM1_Duty > PWM_PERIOD) PWM1_Flag = 1;
  121.     }
  122.     else
  123.     {
  124.         PWM1_Duty--;
  125.         if(PWM1_Duty <= 0) PWM1_Flag = 0;
  126.     }

  127.     if(!PWM2_Flag)
  128.     {
  129.         PWM2_Duty++;
  130.         if(PWM2_Duty > PWM_PERIOD) PWM2_Flag = 1;
  131.     }
  132.     else
  133.     {
  134.         PWM2_Duty--;
  135.         if(PWM2_Duty <= 0) PWM2_Flag = 0;
  136.     }

  137.     if(!PWM3_Flag)
  138.     {
  139.         PWM3_Duty++;
  140.         if(PWM3_Duty > PWM_PERIOD) PWM3_Flag = 1;
  141.     }
  142.     else
  143.     {
  144.         PWM3_Duty--;
  145.         if(PWM3_Duty <= 0) PWM3_Flag = 0;
  146.     }

  147.     if(!PWM4_Flag)
  148.     {
  149.         PWM4_Duty++;
  150.         if(PWM4_Duty > PWM_PERIOD) PWM4_Flag = 1;
  151.     }
  152.     else
  153.     {
  154.         PWM4_Duty--;
  155.         if(PWM4_Duty <= 0) PWM4_Flag = 0;
  156.     }
  157.    
  158.     UpdatePwm();
  159. }


  160. //========================================================================
  161. // 函数: UpdatePwm(void)
  162. // 描述: 更新PWM占空比.
  163. // 参数: none.
  164. // 返回: none.
  165. // 版本: V1.0, 2012-11-22
  166. //========================================================================
  167. void UpdatePwm(void)
  168. {
  169.     PWMA_CCR1H = (u8)(PWM1_Duty >> 8); //设置占空比时间
  170.     PWMA_CCR1L = (u8)(PWM1_Duty);
  171.     PWMA_CCR2H = (u8)(PWM2_Duty >> 8); //设置占空比时间
  172.     PWMA_CCR2L = (u8)(PWM2_Duty);
  173.     PWMA_CCR3H = (u8)(PWM3_Duty >> 8); //设置占空比时间
  174.     PWMA_CCR3L = (u8)(PWM3_Duty);
  175.     PWMA_CCR4H = (u8)(PWM4_Duty >> 8); //设置占空比时间
  176.     PWMA_CCR4L = (u8)(PWM4_Duty);
  177. }
复制代码


回复

使用道具 举报

ID:433219 发表于 2024-3-20 14:45 | 显示全部楼层
呼吸,调整起来方便顺畅么?
回复

使用道具 举报

ID:961114 发表于 2024-3-27 09:11 | 显示全部楼层
STC 系列-输出任意周期和任意占空比的波形
#include "reg51.h"
#include "intrins.h"

sfr     P_SW2       =   0xba;

sfr     PWMSET      =   0xF1;
sfr     PWMCFG01    =   0xF6;
sfr     PWMCFG23    =   0xF7;
sfr     PWMCFG45    =   0xFE;

#define PWM0C       (*(unsigned int  volatile xdata *)0xFF00)
#define PWM0CH      (*(unsigned char volatile xdata *)0xFF00)
#define PWM0CL      (*(unsigned char volatile xdata *)0xFF01)
#define PWM0CKS     (*(unsigned char volatile xdata *)0xFF02)
#define PWM0TADC    (*(unsigned int  volatile xdata *)0xFF03)
#define PWM0TADCH   (*(unsigned char volatile xdata *)0xFF03)
#define PWM0TADCL   (*(unsigned char volatile xdata *)0xFF04)
#define PWM0IF      (*(unsigned char volatile xdata *)0xFF05)
#define PWM0FDCR    (*(unsigned char volatile xdata *)0xFF06)
#define PWM00T1     (*(unsigned int  volatile xdata *)0xFF10)
#define PWM00T1H    (*(unsigned char volatile xdata *)0xFF10)
#define PWM00T1L    (*(unsigned char volatile xdata *)0xFF11)
#define PWM00T2H    (*(unsigned char volatile xdata *)0xFF12)
#define PWM00T2     (*(unsigned int  volatile xdata *)0xFF12)
#define PWM00T2L    (*(unsigned char volatile xdata *)0xFF13)
#define PWM00CR     (*(unsigned char volatile xdata *)0xFF14)
#define PWM00HLD    (*(unsigned char volatile xdata *)0xFF15)

sfr     P0M1    =   0x93;
sfr     P0M0    =   0x94;
sfr     P1M1    =   0x91;
sfr     P1M0    =   0x92;
sfr     P2M1    =   0x95;
sfr     P2M0    =   0x96;
sfr     P3M1    =   0xb1;
sfr     P3M0    =   0xb2;
sfr     P4M1    =   0xb3;
sfr     P4M0    =   0xb4;
sfr     P5M1    =   0xc9;
sfr     P5M0    =   0xca;

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    PWMSET = 0x01;                              //使能PWM0模块(必须先使能模块后面的设置才有效)

    P_SW2 = 0x80;
    PWM0CKS = 0x00;                             //PWM0时钟为系统时钟
    PWM0C = 0x1000;                             //设置PWM0周期为1000H个PWM时钟
    PWM00T1= 0x0100;                            //在计数值为100H地方PWM00通道输出低电平
    PWM00T2= 0x0500;                            //在计数值为500H地方PWM00通道输出高电平
    PWM00CR= 0x80;                              //使能PWM00输出
    P_SW2 = 0x00;

    PWMCFG01 = 0x01;                            //启动PWM0模块

    while (1);
}


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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