找回密码
 立即注册
查看: 2835|回复: 8

PWM学习之单路PWM输出(STC8G)

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-04-14 10:08:33

14

主题

61

回帖

481

积分

中级会员

积分
481
发表于 2024-1-1 12:09:47 | 显示全部楼层 |阅读模式
硬件:STC8G1K08-38I-TSSOP20

这次用pin20 cpp0 进行输出,电路图

pwm1.png

P35设置为推挽输出,高电平为LED供电。
P11设置为开漏输出,低电平点亮,高电平熄灭。
先测试一下管脚是否正常。
配置io
io1.png
io3.png

代码:
  1. /*********************************************************/
  2. #define MAIN_Fosc        11059200L        //定义主时钟
  3. #include        "STC8Gxxx.h"
  4. /*************        功能说明        *************
  5. 整体布局
  6. 功能        管脚        用途                 输入输出     类型      PXM1  PXM0
  7. P11         PIN20       seg_a           输出         开漏输出  1     1
  8. P0M1 = 00000010B 0x02
  9. P0M0 = 00000010B 0x02
  10. 功能        管脚        用途                 输入输出     类型      PXM1  PXM0
  11. P35         PIN16       数码管共阳G1    输出         推挽输出  0     1
  12. P3M1 = 0000 0000B 0x00
  13. P3M0 = 0010 0000B 0x20
  14.       
  15. ******************************************/
  16. /*************        本地常量声明        **************/
  17. #define G1_ON    (P35 = 1)
  18. #define G1_OFF   (P35 = 0)
  19. #define LED_OFF   (P11 = 1)
  20. #define LED_ON    (P11 = 0)
  21. /*************        本地变量声明        **************/
  22. /*************        本地函数声明        **************/
  23. /****************  外部函数声明和外部变量声明 *****************/
  24. /**********************************************/
  25. void Delay100ms(void)        //@11.0592MHz
  26. {
  27.         unsigned char data i, j, k;
  28.         _nop_();
  29.         _nop_();
  30.         i = 5;
  31.         j = 52;
  32.         k = 195;
  33.         do
  34.         {
  35.                 do
  36.                 {
  37.                         while (--k);
  38.                 } while (--j);
  39.         } while (--i);
  40. }
  41. void main(void)
  42. {
  43.     int time100ms = 0;
  44.     P_SW2 |= 0x80;        //允许访问XSFR(扩展特殊功能寄存器)
  45.     //设置管脚模式
  46.     P1M1 = 0x02;
  47.     P1M0 = 0x02;
  48.     P3M1 = 0x00;
  49.     P3M0 = 0x20;
  50.         //打开LED供电
  51.     G1_ON;
  52.     while (1)
  53.     {
  54.             //点亮led            
  55.         LED_ON;
  56.                 //延时0.5s
  57.                 for(time100ms = 5; time100ms > 0; time100ms--)
  58.         {
  59.              Delay100ms();   
  60.         }
  61.                 //熄灭led            
  62.         LED_OFF;
  63.                 //延时0.5s
  64.                 for(time100ms = 5; time100ms > 0; time100ms--)
  65.         {
  66.              Delay100ms();   
  67.         }                                 
  68.     }
  69. }
复制代码


回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-04-14 10:08:33

14

主题

61

回帖

481

积分

中级会员

积分
481
发表于 2024-1-1 14:52:44 | 显示全部楼层
本帖最后由 hl1200aa 于 2024-1-1 14:56 编辑

PWM的设置包括
1. 输出管脚 (已经配置)
2. 模式配置
3. pwm频率设置
4. pwm占空比设置

这次根据手册里面的例程,配置一个频率为1hz,占空比特定的pwm。
pca的计数器结构图如下
微信图片_20240101145556.png
PWM_CLK = CLK_in / 64
PWM_CLK = 1
CLK_in 则是64hz

系统时钟11059200, 12分配后也远超这个频率
所以选择用T0溢出。
配置T0输出64hz,则是每15625us溢出一次
pwm_clk.png

CLK_in = 64hz
最简单的6位pwm模式,
PWM_CLK = CLK_IN/64

计算得到PWM_CLK = 1

看下手册里面的例程
  1. CCON = 0x00;
复制代码
ccon.png


  1. CMOD = 0x08; //PCA 时钟为系统时钟
复制代码
CMOD.png


  1. CL = 0x00;CH = 0x00;  //清零计数寄存器
复制代码

  1. CCAPM0 = 0x42;  //PCA 模块 0 为 PWM 工作模式
复制代码
capm0.png



  1. PCA_PWM0 = 0x80;  //PCA 模块 0 输出 6 位 PWM
复制代码
pca_pwm0.png

6bitpwm.png

结合这张图可以看到,设置为0x80时,pwm工作在6bit模式
CH永远为0, EPC0L如果为0则可以比对,为1时,则永远为1。
在CL发生溢出时,EPC0H的值重载到EPC0L,CCAP0H的值重载到CCAP0L。

  1. CCAP0L = 0x20; //PWM 占空比为 50%[(40H-20H)/40H]
复制代码
占空比一般是计算高电平的时间,对于我们这个,刚好相反,低电平为亮,那就是CCAP0L/64。
如果我们设置为8,则8/64*100%=12.5%,亮的时间短灭的时间长
  1. CCAP0H = 0x20; //重载值
复制代码
最后记得打开计数开关
  1. CR = 1; //开始计数
复制代码







T0set.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-04-14 10:08:33

14

主题

61

回帖

481

积分

中级会员

积分
481
发表于 2024-1-1 14:58:53 | 显示全部楼层
  1. /*********************************************************/
  2. #define MAIN_Fosc        11059200L        //定义主时钟
  3. #include        "STC8Gxxx.h"
  4. /*************        功能说明        *************
  5. 整体布局
  6. 功能        管脚        用途                 输入输出     类型      PXM1  PXM0
  7. P11         PIN20       seg_a           输出         开漏输出  1     1
  8. P0M1 = 00000010B 0x02
  9. P0M0 = 00000010B 0x02
  10. 功能        管脚        用途                 输入输出     类型      PXM1  PXM0
  11. P35         PIN16       数码管共阳G1    输出         推挽输出  0     1
  12. P3M1 = 0000 0000B 0x00
  13. P3M0 = 0010 0000B 0x20
  14.       
  15. ******************************************/
  16. /*************        本地常量声明        **************/
  17. #define G1_ON    (P35 = 1)
  18. #define G1_OFF   (P35 = 0)
  19. #define LED_OFF   (P11 = 1)
  20. #define LED_ON    (P11 = 0)
  21. /*************        本地变量声明        **************/
  22. /*************        本地函数声明        **************/
  23. /****************  外部函数声明和外部变量声明 *****************/
  24. /**********************************************/
  25. void Delay100ms(void)        //@11.0592MHz
  26. {
  27.         unsigned char data i, j, k;
  28.         _nop_();
  29.         _nop_();
  30.         i = 5;
  31.         j = 52;
  32.         k = 195;
  33.         do
  34.         {
  35.                 do
  36.                 {
  37.                         while (--k);
  38.                 } while (--j);
  39.         } while (--i);
  40. }
  41. //初始化T0
  42. void Timer0_Init(void)                //15625微秒@11.0592MHz
  43. {
  44.         AUXR &= 0x7F;                        //定时器时钟12T模式
  45.         TMOD &= 0xF0;                        //设置定时器模式
  46.         TL0 = 0xC0;                                //设置定时初始值
  47.         TH0 = 0xC7;                                //设置定时初始值
  48.         TF0 = 0;                                //清除TF0标志
  49.         TR0 = 1;                                //定时器0开始计时
  50. }
  51. /*
  52. //定时器0中断函数
  53. void T0_ISR(void) interrupt 1
  54. {
  55.     TF0  =  0;     //清除TF位
  56. }
  57. */
  58. void main(void)
  59. {
  60.     int time100ms = 0;
  61.     P_SW2 |= 0x80;        //允许访问XSFR(扩展特殊功能寄存器)
  62.     //设置管脚模式
  63.     P1M1 = 0x02;
  64.     P1M0 = 0x02;
  65.     P3M1 = 0x00;
  66.     P3M0 = 0x20;
  67.         //初始化T0
  68.         Timer0_Init();
  69.         //打开LED供电
  70.     G1_ON;
  71.         CCON = 0x00;
  72.         CMOD = 0x04; //PCA 时钟为T0溢出
  73.         CL = 0x00;
  74.         CH = 0x00;  //清零计数寄存器
  75.         CCAPM0 = 0x42;  //PCA 模块 0 为 PWM 工作模式
  76.         PCA_PWM0 = 0x80;  //PCA 模块 0 输出 6 位 PWM
  77.         CCAP0L = 0x8; //PWM 占空比为 CCAP0L/64*100%
  78.         CCAP0H = 0x8; //重载值
  79.         //ET0  =  1;     //允许T0中断
  80.         //打开全局中断
  81.         //EA = 1;
  82.         CR = 1; //开始计数
  83.     while (1)
  84.     {
  85.             /*
  86.                 //点亮led            
  87.         LED_ON;
  88.                 //延时0.5s
  89.                 for(time100ms = 5; time100ms > 0; time100ms--)
  90.         {
  91.              Delay100ms();   
  92.         }
  93.                 //熄灭led            
  94.         LED_OFF;
  95.                 //延时0.5s
  96.                 for(time100ms = 5; time100ms > 0; time100ms--)
  97.         {
  98.              Delay100ms();   
  99.         }
  100.                 */                                 
  101.     }
  102. }
  103. /**********************************************/
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-05-03 10:05:34

718

主题

1万

回帖

1万

积分

管理员

积分
15646
发表于 2024-1-1 15:33:02 | 显示全部楼层
截图202401011532035236.jpg

截图202401011532287707.jpg

截图202401011532545751.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:56
  • 最近打卡:2025-05-03 10:05:34

718

主题

1万

回帖

1万

积分

管理员

积分
15646
发表于 2024-1-1 15:34:34 | 显示全部楼层

浪费 1个 I/O 的目的 ?
截图202401011534029173.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-04-14 10:08:33

14

主题

61

回帖

481

积分

中级会员

积分
481
发表于 2024-1-1 15:58:13 来自手机 | 显示全部楼层
这个板是机器上的主板,控制两位数码管的,这只是个等效电路。当时这主板的stc8g坏了,换掉后自己编程序修好了,顺便拿来学习用,反正hex在手,要用时刷进去就行了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-04-14 10:08:33

14

主题

61

回帖

481

积分

中级会员

积分
481
发表于 2024-1-1 17:09:58 | 显示全部楼层
神*** 发表于 2024-1-1 15:34
浪费 1个 I/O 的目的 ?

这个板是机器上的主板,控制两位数码管的,这只是个等效电路。当时这主板的stc8g坏了,换掉后自己编程序修好了,顺便拿来学习用,反正hex在手,要用时刷进去就行了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:513
  • 最近打卡:2025-05-02 07:32:37

21

主题

564

回帖

2678

积分

金牌会员

积分
2678
发表于 2024-1-2 15:19:04 | 显示全部楼层
楼主会玩,是个高手
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:457
  • 最近打卡:2025-05-03 00:00:33

6

主题

81

回帖

2126

积分

金牌会员

积分
2126
发表于 2024-10-8 17:19:11 | 显示全部楼层

弄个38K的红外发射接收电路和程序来学习一下
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 15:07 , Processed in 0.241300 second(s), 104 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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