找回密码
 立即注册
查看: 333|回复: 2

用8G1K08A的按键和PWM练习

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:62
  • 最近打卡:2025-05-02 02:48:36
已绑定手机

4

主题

16

回帖

285

积分

中级会员

积分
285
发表于 2025-2-15 14:00:33 | 显示全部楼层 |阅读模式
几个月前开始接触STC8G1K08A这8脚单片机,觉得挺有意思的,范例代码要做成实用的功能,还是要很多试验,才能有一些收获。
先实现了上电等待5秒,再接通1秒,然后断开进入掉电模式,仅涉及定时器和IO相关的代码
再实现了桶装水自动抽水器的定时功能,短按开始抽水,再短按,停止抽水,或者自动倒计时 n 秒后停止抽水;长按3秒开始抽水并进入设置模式,直到短按停止抽水,自动保存长按开始到短按结束之间的时间,作为下次自动倒计时时长,即倒计时时长可设置。涉及定时器、IO、按键中断,短按,长按,长长按,EEPROM读写等操作,还有就是掉电模式进入和恢复等。
最近又研究PWM,控制LED高亮、中亮、低亮、熄灭的不同显示效果,用deepseek和kimi提供的代码,由于不是适配STC8G1K08A芯片,所以无法运行,看STC8G.pdf芯片规范文件,还是很多不理解,特别是IO口不同工作模式的切换,希望大佬可以指点指点。

以下是使用STC8G1K08A单片机实现通过按键控制LED开关和亮度的代码示例。代码基于STC单片机的C语言开发环境,使用PWM信号控制LED亮度,并通过按键切换高亮、中亮、低亮和熄灭状态。
硬件连接说明
  • P32:按键输入,连接到单片机的P32引脚。
  • P54:PWM输出,连接到单片机的P54引脚,用于控制LED亮度,默认输出高电平(熄灭)。
  • LED:通过电阻连接到P54引脚,另一端接电源正极,当IO口低电平时点亮。
  • 按键:一端连接到P32引脚,另一端接地。
软件设计思路
  • PWM控制:使用STC单片机的定时器功能生成PWM信号,通过占空比控制LED亮度。
  • 按键检测:检测P32引脚的状态,判断按键是否按下。
  • 状态切换:通过按键切换LED的亮度状态(高亮、中亮、低亮、熄灭)。
  • 上电默认高亮:程序启动时,设置为高亮状态。
  1. #include "STC8G.H"
  2. #define MAIN_Fosc       24000000L   // 定义主时钟
  3. #define MCU_IDLE()          PCON |= 1   /* MCU 进入 IDLE 模式 */
  4. #define MCU_POWER_DOWN()    PCON |= 2   /* MCU 进入 睡眠 模式 */
  5. #define u1 bit
  6. #define u8 unsigned char
  7. #define u16 unsigned int
  8. #define u32 unsigned long
  9. #define IDLE_TIME 3000000L      // 空闲计数器阈值
  10. // 定义按键引脚
  11. #define KEY_PIN P32  // 按键连接P32
  12. // 定义亮度档位
  13. // 定义PWM相关参数
  14. #define PWM_HIGH_DUTY 0xFF   // 高亮占空比(高电平时间长) = 常亮
  15. #define PWM_MEDIUM_DUTY 0x80 // 中亮占空比
  16. #define PWM_LOW_DUTY 0x40    // 低亮占空比
  17. #define PWM_OFF_DUTY 0x00    // 熄灭占空比(低电平)
  18. extern void          _nop_     (void);
  19. // 定义状态变量
  20. u8 led_state = 0;             // LED状态:0-高亮,1-中亮,2-低亮,3-熄灭
  21. u1 wakeup_status = 1;        // 运行标志(0:休眠,1:活跃)
  22. u32 idle_time = 0;            // 空闲计数器
  23. // 延时函数, ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
  24. void delay_ms(unsigned int ms)
  25. {
  26.         unsigned int i;
  27.         do{
  28.                 i = MAIN_Fosc / 10000;
  29.                 while(--i);
  30.         }while(--ms);
  31. }
  32. // 初始化PWM
  33. void PWM_Init() {
  34.     // 配置 PCA
  35.         CCON= 0x00;
  36.         CL = 0x00;
  37.         CH = 0x00;
  38.         CCAPM2 = 0x42;           // PCA 模块2为PWM工作模式
  39.         CR = 1;                  // 启动PCA 计数器
  40.         
  41. }
  42. // 设置PWM占空比,输出8位的PWM
  43. void Set_PWM_Duty(u8 duty) {
  44.     if (duty == 0xFF){ // 固定输出低电平,常亮
  45.                 PCA_PWM2 &= 0x3F;
  46.                 CCAP2H    = 0xFF;
  47.         }else if (duty == 0x00){ // 固定输出高电平,熄灭
  48.                 PCA_PWM2 &= 0xC0;
  49.                 CCAP2H    = 0x00;
  50.         }else{ // 输出8位的PWM
  51.                 PCA_PWM2 &=0x00;
  52.                 CCAP2L = duty;   // 设置占空比(低字节)
  53.                 CCAP2H = duty;   // 设置占空比(高字节)
  54.         }
  55. }
  56. // 按键检测
  57. u8 Key_Scan() {
  58.     if (KEY_PIN == 0) {  // 检测按键是否按下
  59.         delay_ms(20);  // 消抖
  60.         if (KEY_PIN == 0) {
  61.             while (KEY_PIN == 0);  // 等待按键释放
  62.             return 1;  // 返回按键按下标志
  63.         }
  64.     }
  65.     return 0;  // 无按键按下
  66. }
  67. // 初始化I/O端口
  68. void InitPorts()
  69. {
  70.         // 初始化为准双向
  71.     P3M0 = 0x00; P3M1 = 0x00;
  72.     P5M0 = 0x00; P5M1 = 0x00;
  73. }
  74. // 外部中断0初始化
  75. void Int0_Init(void) {
  76.     IT0 = 1;         // 使能INT0下降沿中断
  77.     EX0 = 1;         // 使能INT0中断0
  78.     EA = 1;          // 使能中断总开关
  79. }
  80. // 掉电模式
  81. void PowerDownMode(void) {
  82.     wakeup_status = 0;
  83.     _nop_();
  84.     _nop_();
  85.     MCU_POWER_DOWN();  // MCU进入掉电模式(STC8G系列)
  86.     _nop_();
  87.     _nop_();
  88.     _nop_();
  89.     _nop_();
  90. }
  91. // 从掉电模式唤醒
  92. void WakeUpFromPowerDown(void) {
  93.     PCON &= 0xFD; // 清除掉电标志
  94. }
  95. // 外部中断0服务程序(按键唤醒)
  96. void INT0_ISR(void) interrupt 0 {
  97.     if (!wakeup_status){       // 如果在休眠状态,就执行唤醒操作
  98.         wakeup_status = 1;
  99.         WakeUpFromPowerDown(); // 从掉电模式唤醒
  100.     }
  101. }
  102. // 主函数
  103. void main() {
  104.         InitPorts(); // 初始化端口
  105.         Int0_Init(); // 初始化外部中断0
  106.     PWM_Init();  // 初始化PWM
  107.     // 上电默认高亮
  108.     Set_PWM_Duty(PWM_HIGH_DUTY);
  109.         led_state = 0;
  110.     while (1) {
  111.                 idle_time++;
  112.         if (Key_Scan()) {  // 检测按键
  113.             led_state++;  // 切换LED状态
  114.                         idle_time = 0; //重置空闲计数器
  115.             if (led_state > 3) {
  116.                 led_state = 0;  // 循环回到高亮状态
  117.             }
  118.             // 根据状态设置PWM占空比或普通输出高电平
  119.             switch (led_state) {
  120.                 case 0:  // 高亮
  121.                     Set_PWM_Duty(PWM_HIGH_DUTY);
  122.                     break;
  123.                 case 1:  // 中亮
  124.                     Set_PWM_Duty(PWM_MEDIUM_DUTY);
  125.                     break;
  126.                 case 2:  // 低亮
  127.                     Set_PWM_Duty(PWM_LOW_DUTY);
  128.                     break;
  129.                 case 3:  // 熄灭
  130.                     Set_PWM_Duty(PWM_OFF_DUTY);
  131.                     break;
  132.             }
  133.         }else{
  134.                         if (led_state == 3 && idle_time >= IDLE_TIME){ // 熄灭时,进入掉电省电模式
  135.                                 PowerDownMode();
  136.                         }
  137.                 }
  138.     }
  139. }
复制代码


回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-19 08:35:19

0

主题

22

回帖

126

积分

注册会员

积分
126
发表于 2025-4-18 11:22:58 | 显示全部楼层
CCAPnL
CCAPnH    这两个寄存器是干啥用的,看数据手册写的我没有完全理解,可能是我的理解能力有问题。能否给讲解一下谢谢!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:62
  • 最近打卡:2025-05-02 02:48:36
已绑定手机

4

主题

16

回帖

285

积分

中级会员

积分
285
发表于 2025-4-19 11:05:39 | 显示全部楼层
阿白*** 发表于 2025-4-18 11:22
CCAPnL
CCAPnH    这两个寄存器是干啥用的,看数据手册写的我没有完全理解,可能是我的理解能力有问题。能 ...

理论上这是内部使用的,我们只要设置好CL和CH初始值,然后修改对应PWM,
CCAPnL中的n是指第几个PWM,例如代码中使用模块2,所以后续代码就设置CCAP2L和CCAP2H
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 13:24 , Processed in 0.109633 second(s), 61 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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