找回密码
 立即注册
楼主: noonezero

冲哥STC32G单片机学习笔记

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-7 11:43:00 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-10 07:54 编辑

第九课:数码管的静态使用


1.显示一个数字

截图202309062152422169.jpg 截图202309070911104166.jpg

截图202309070911311267.jpg



数码管显示
截图202309071114425013.jpg




代码 我增加了sizeof函数,这样想显示什么,直接在数组上加,不用修改后面的代码


  1. #include <STC32G.H>
  2. #include "../COMM/stc32_stc8_usb.h"
  3. #define KEY1 P32  // 功能按键一
  4. #define KEY2 P33  // 功能按键二
  5. #define BEEP P54   // 蜂鸣器引脚,低电平响
  6. void sys_init();
  7. //USB调试及复位所需定义
  8. char *USER_DEVICEDESC = NULL;
  9. char *USER_PRODUCTDESC = NULL;
  10. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  11. void Delay_ms(int x)        //@24.000MHz
  12. {
  13.         unsigned long edata i;
  14.         for(; x > 0; x--)
  15.         {
  16.         _nop_();
  17.         _nop_();
  18.         _nop_();
  19.         i = 5998UL;
  20.                 while (i) i--;
  21.         }
  22. }
  23. void main()
  24. {
  25.        
  26.         u8 SEG_Tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x89, 0xC7, 0xA3, 0x8C, 0xC1};  // 这里不写多少也行,会算出来
  27.         u8 num = 0;  // 显示数组中第几个字符
  28.        
  29.         sys_init();
  30.         usb_init();  //USB初始化
  31.         EA = 1;
  32.        
  33.         P70 = 0;  // 开启数码管
  34.     while(1)
  35.     {
  36.         P6 = SEG_Tab[num];  // 显示第几个
  37.         
  38.         if(KEY1 == 0)
  39.         {
  40.             Delay_ms(10);  // 软件消抖
  41.             if(KEY1 == 0)
  42.             {
  43.                 BEEP = 0;      // 打开蜂鸣器
  44.                 Delay_ms(10);  // 延时
  45.                 BEEP = 1;      // 关闭蜂鸣器
  46.                 while(KEY1 == 0);  // 死循环 等待抬起
  47.                 if(num < sizeof(SEG_Tab) / sizeof(SEG_Tab[0]))  // 算出数组长度
  48.                 {
  49.                     num ++;
  50.                 }
  51.             }
  52.         }
  53.         if(KEY2 == 0)
  54.         {
  55.             Delay_ms(10);  // 软件消抖
  56.             if(KEY2 == 0)
  57.             {
  58.                 BEEP = 0;      // 打开蜂鸣器
  59.                 Delay_ms(10);  // 延时
  60.                 BEEP = 1;      // 关闭蜂鸣器
  61.                 while(KEY2 == 0);  // 死循环 等待抬起
  62.                 if(num > 0)
  63.                 {
  64.                     num --;
  65.                 }
  66.             }
  67.         }
  68.     }
  69. }
  70. void sys_init()
  71. {
  72.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  73.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  74.     CKCON = 0; //提高访问XRAM速度
  75.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  76.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  77.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  78.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  79.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  80.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  81.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  82.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  83. }
复制代码






截图202309070908437810.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-8 10:18:27 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-10 09:17 编辑

第十课:数码管的动态显示

动态点亮八个数码管控制原理

截图202309080749121722.jpg


P7 开关显示对应数码管对应的值
截图202309080815334774.jpg


作业代码


  1. #include <STC32G.H>
  2. #include <intrins.h>
  3. #include "../COMM/stc32_stc8_usb.h"
  4. #define KEY1 P32  // 功能按键一
  5. #define KEY2 P33  // 功能按键二
  6. #define BEEP P54  // 蜂鸣器引脚,低电平响
  7. u8 SEG_Tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF
  8. };  // 这里不写多少也行,会算出来
  9. bit onoroff = 0;  // 开机还是关机
  10. u32 count = 18456000;
  11. //USB调试及复位所需定义
  12. char *USER_DEVICEDESC = NULL;
  13. char *USER_PRODUCTDESC = NULL;
  14. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  15. void sys_init();
  16. void Delay_ms(int x)        //@24.000MHz
  17. {
  18.         unsigned long edata i;
  19.         for(; x > 0; x--)
  20.         {
  21.         _nop_();
  22.         _nop_();
  23.         _nop_();
  24.         i = 5998UL;
  25.                 while (i) i--;
  26.         }
  27. }
  28. void show(u8 P7index, u8 showtabindex)  // P7index 从1开始
  29. {
  30.     u8 indexnum = 0x01;
  31.         P6 = 0xFF;
  32.     P7 = ~(indexnum << (8 - P7index));
  33.     P6 = SEG_Tab[showtabindex];
  34.     Delay_ms(1);
  35. }
  36. void showinit()
  37. {
  38.     show(1, 0);
  39.     show(2, 0);
  40.     show(3, 10);
  41.     show(4, 0);
  42.     show(5, 0);
  43.     show(6, 10);
  44.     show(7, 0);
  45.     show(8, 0);
  46. }
  47. void countshow()  // count计数显示
  48. {
  49.     u32 a = count / 100;  // 显示延时了好多,这里如果按1000算 太慢了,100差不多
  50.         int mouth =a/(60 * 60);  // 求小时
  51.         int min =(a - mouth * (60 * 60)) / 60;  // 求分
  52.         int s = a - mouth * (60 * 60) - min * 60;  // 求秒
  53.     show(1, (u8)mouth/10);
  54.     show(2, (u8)mouth%10);
  55.     show(3, 10);
  56.    
  57.     show(4, (u8)min/10);
  58.     show(5, (u8)min%10);
  59.     show(6, 10);
  60.    
  61.     show(7, (u8)s/10);
  62.     show(8, (u8)s%10);
  63. }
  64. void main()
  65. {
  66.         sys_init();
  67.         usb_init();  //USB初始化
  68.         EA = 1;
  69.         
  70.         while(1)
  71.     {
  72.                 if(onoroff)
  73.         {
  74.             count++;
  75.             countshow();
  76.         }
  77.                 else
  78.                 {
  79.                         showinit();
  80.                 }
  81.                 Delay_ms(1);  // 延时
  82.    
  83.         if(KEY1 == 0)
  84.         {
  85.             Delay_ms(10);  // 软件消抖
  86.             if(KEY1 == 0)
  87.             {
  88.                 BEEP = 0;      // 打开蜂鸣器
  89.                 Delay_ms(10);  // 延时
  90.                 BEEP = 1;      // 关闭蜂鸣器
  91.                 while(KEY1 == 0)  // 死循环 等待抬起
  92.                 {
  93.                     showinit();
  94.                 }
  95.                 onoroff = !onoroff;
  96.                 count = 0;
  97.             }
  98.         }
  99.     }
  100. }
  101. void sys_init()
  102. {
  103.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  104.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  105.     CKCON = 0; //提高访问XRAM速度
  106.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  107.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  108.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  109.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  110.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  111.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  112.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  113.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  114. }
复制代码



截图202309100917014862.jpg








回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-11 08:53:18 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-13 13:48 编辑

第十一课:定时器的使用


定时器使用比前十节的视频难度蹭的就上来了

之前的就是简单的I/O操作,配置好模式就只剩下设置高低电平了
定时器这节,刷了几个视频才对定时器,中断有些了解了


简单说,定时器就是按系统时钟,分频下 然后计数脉冲。脉冲计数达到65536 时溢出,产生中断。
计数初始值可以通过 TH0 和 TL0 配置


截图202309131347555905.jpg 截图202309110851428100.jpg


以下代码通过定时器改了上节课的代码


  1. #include <STC32G.H>
  2. #include <intrins.h>
  3. #include "../COMM/stc32_stc8_usb.h"
  4. #define KEY1 P32  // 功能按键一
  5. #define KEY2 P33  // 功能按键二
  6. #define BEEP P54  // 蜂鸣器引脚,低电平响
  7. u8 SEG_Tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0xBF
  8. };  // 这里不写多少也行,会算出来
  9. bit onoroff = 0;  // 开机还是关机
  10. u32 count = 18456000;
  11. //USB调试及复位所需定义
  12. char *USER_DEVICEDESC = NULL;
  13. char *USER_PRODUCTDESC = NULL;
  14. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  15. void sys_init();
  16. void Delay_ms(int x)        //@24.000MHz
  17. {
  18.         unsigned long edata i;
  19.         for(; x > 0; x--)
  20.         {
  21.         _nop_();
  22.         _nop_();
  23.         _nop_();
  24.         i = 5998UL;
  25.                 while (i) i--;
  26.         }
  27. }
  28. void show(u8 P7index, u8 showtabindex)  // P7index 从1开始
  29. {
  30.     u8 indexnum = 0x01;
  31.         P6 = 0xFF;
  32.     P7 = ~(indexnum << (8 - P7index));
  33.     P6 = SEG_Tab[showtabindex];
  34.     Delay_ms(1);
  35. }
  36. void showinit()
  37. {
  38.     show(1, 0);
  39.     show(2, 0);
  40.     show(3, 10);
  41.     show(4, 0);
  42.     show(5, 0);
  43.     show(6, 10);
  44.     show(7, 0);
  45.     show(8, 0);
  46. }
  47. void countshow()  // count计数显示
  48. {
  49.     u32 a = count / 1000;  // 显示延时了好多,这里如果按1000算 太慢了,100差不多
  50.         int mouth =a/(60 * 60);  // 求小时
  51.         int min =(a - mouth * (60 * 60)) / 60;  // 求分
  52.         int s = a - mouth * (60 * 60) - min * 60;  // 求秒
  53.     show(1, (u8)mouth/10);
  54.     show(2, (u8)mouth%10);
  55.     show(3, 10);
  56.    
  57.     show(4, (u8)min/10);
  58.     show(5, (u8)min%10);
  59.     show(6, 10);
  60.    
  61.     show(7, (u8)s/10);
  62.     show(8, (u8)s%10);
  63. }
  64. void main()
  65. {
  66.         sys_init();
  67.         usb_init();  //USB初始化
  68.         EA = 1;
  69.         
  70.         /**定时器配置**/
  71.         AUXR &= 0x7F;  //定时器时钟12T模式
  72.         TMOD &= 0xF0;  //设置定时器模式
  73.         TH0 = 0xF8;  // 计算出24M时钟下1ms定时时间初始值
  74.         TL0 = 0x30;
  75.         TR0 = 1;  // 启动定时器
  76.         EA = 1;  // 打开总中断
  77.         ET0 = 1;  // 使能定时器中断
  78.         
  79.         while(1)
  80.     {
  81.                 if(onoroff)
  82.         {
  83.             countshow();
  84.         }
  85.                 else
  86.                 {
  87.                         showinit();
  88.                 }
  89.    
  90.         if(KEY1 == 0)
  91.         {
  92.             Delay_ms(10);  // 软件消抖
  93.             if(KEY1 == 0)
  94.             {
  95.                 BEEP = 0;      // 打开蜂鸣器
  96.                 Delay_ms(10);  // 延时
  97.                 BEEP = 1;      // 关闭蜂鸣器
  98.                 while(KEY1 == 0)  // 死循环 等待抬起
  99.                 {
  100.                     showinit();
  101.                 }
  102.                 onoroff = !onoroff;
  103.                 count = 0;
  104.             }
  105.         }
  106.     }
  107. }
  108. void Timer0_Isr(void) interrupt 1
  109. {
  110.         count++;
  111. }
  112. void sys_init()
  113. {
  114.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  115.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  116.     CKCON = 0; //提高访问XRAM速度
  117.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  118.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  119.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  120.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  121.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  122.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  123.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  124.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  125. }
复制代码




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-14 12:07:49 | 显示全部楼层
第十二课:计数器的使用


1.开启内部上拉电阻

截图202309140751479881.jpg 截图202309140752326718.jpg


2.补充中断号

截图202309140753306161.jpg




代码

冲哥代码中 TF1 位不用清零,默认就是0,响应中断后会硬件清零
  1. #include <STC32G.H>
  2. #include <intrins.h>
  3. #include "../COMM/stc32_stc8_usb.h"
  4. //USB调试及复位所需定义
  5. char *USER_DEVICEDESC = NULL;
  6. char *USER_PRODUCTDESC = NULL;
  7. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  8. void sys_init();
  9. void Delay_ms(int x)        //@24.000MHz
  10. {
  11.         unsigned long edata i;
  12.         for(; x > 0; x--)
  13.         {
  14.         _nop_();
  15.         _nop_();
  16.         _nop_();
  17.         i = 5998UL;
  18.                 while (i) i--;
  19.         }
  20. }
  21. void main()
  22. {
  23.         sys_init();
  24.         usb_init();  //USB初始化
  25.        
  26.         P40 = 0;
  27.         P3PU = 0x20;  // 启动P35上拉电阻
  28.        
  29.         /**定时器配置**/
  30.         TMOD |= 0x40;  //设置定时器0计数模式
  31.         TH1 = 0xFF;  // 计算出24M时钟下1ms定时时间初始值
  32.         TL1 = 0xFF;
  33.         TR1 = 1;  // 启动计数器
  34.         EA = 1;  // 打开总中断
  35.         ET1 = 1;  // 使能定时器中断
  36.        
  37.        
  38.         while(1)
  39.     {
  40.                 ;
  41.     }
  42. }
  43. void Timer1_Isr(void) interrupt 3
  44. {
  45.         P6 = ~P6;
  46. }
  47. void sys_init()
  48. {
  49.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  50.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  51.     CKCON = 0; //提高访问XRAM速度
  52.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  53.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  54.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  55.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  56.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  57.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  58.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  59.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  60. }
复制代码



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-14 21:56:46 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-24 15:13 编辑

第十三课:简单多任务处理


1.创建程序文件
  • 新建文件并添加到工程
  • 添加引用路径



引脚定义在.h文件中
sbit 名称 = P10;
#define 名称 P10


2.修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”
extern修饰的变量不能赋初值


3.bdata位寻址变量的使用
截图202309142156202928.jpg



4.代码待填

07简单多任务.zip (91.78 KB, 下载次数: 201)

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-24 18:43:38 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-25 14:22 编辑

第十四课:什么是矩阵按键


1.原理图


截图202309241709568194.jpg

2.实现原理
端口默认高电平,实时读取引脚为低电平表示按下


1. 将P00-P03输出低电平,P06-P07输出高电平,如果有按键按下,按下的那一列IO就会变成低电平,可以判断哪一列按下了


2. 将P00-P03输出高电平,P06-P07输出低电平,如果有按键按下,按下的那一列IO就会变成低电平,可以判断哪一列按下了


3. 行列组合就能知道是哪个按键按下了



3.实现代码:


  1. #include <STC32G.H>
  2. #include "../COMM/stc32_stc8_usb.h"
  3. void sys_init();
  4. //USB调试及复位所需定义
  5. char *USER_DEVICEDESC = NULL;
  6. char *USER_PRODUCTDESC = NULL;
  7. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  8. /*
  9. 函数功能:定时器0定时初始化
  10. 入口参数:@
  11. 函数返回:
  12. 其他备注:
  13. */
  14. void Timer0init()
  15. {
  16.         AUXR &= 0x7F;  //定时器时钟12T模式 默认就是
  17.         TMOD &= 0xF0;  //设置定时器模式
  18.         TH0 = 0xF8;  // 计算出24M时钟下1ms定时时间初始值
  19.         TL0 = 0x30;
  20.         ET0 = 1;  // 使能定时器中断
  21.         TR0 = 1;   // 开始定时
  22. }
  23. void Delay_ms(int x)        //@24.000MHz
  24. {
  25.         unsigned long edata i;
  26.         for(; x > 0; x--)
  27.         {
  28.                 _nop_();
  29.                 _nop_();
  30.                 _nop_();
  31.                 i = 5998UL;
  32.                 while (i) i--;
  33.         }
  34. }
  35. // 矩阵按键
  36. u8 MateixKEY_Read()
  37. {
  38.         u8 keystate; u8 key_val;
  39.         // 端口默认高电平,实时读取引脚为低电平表示按下
  40.         // 1. 将P00-P03输出低电平,P06-P07输出高电平,如果有按键按下,按下的那一列IO就会变成低电平,可以判断哪一列按下了
  41.         P0 = 0xC0;                        // 1100 0000
  42.         Delay_ms(10);
  43.         keystate = (P0 ^ 0xC0);        // 0100 0000 ^ 1100 0000 = 1000 0000 假设第7位按下
  44.        
  45.         // 2. 将P00-P03输出高电平,P06-P07输出低电平,如果有按键按下,按下的那一列IO就会变成低电平,可以判断哪一列按下了
  46.         P0 = 0x0F;                        // 1100 0000
  47.         Delay_ms(10);
  48.         keystate |= (P0 ^ 0x0F);
  49.         switch (keystate)
  50.     {
  51.             case 0x41: key_val = 1;
  52.                     break;
  53.             case 0x42: key_val = 2;
  54.                     break;
  55.                 case 0x44: key_val = 3;
  56.                     break;
  57.             case 0x48: key_val = 4;
  58.                     break;
  59.                 case 0x81: key_val = 5;
  60.                     break;
  61.             case 0x82: key_val = 6;
  62.                     break;
  63.                 case 0x84: key_val = 7;
  64.                     break;
  65.             case 0x88: key_val = 8;
  66.                     break;
  67.             default: key_val = 0;
  68.                     break;
  69.     }
  70.         return key_val;
  71.        
  72. }
  73. u8 SEG_Tab[20] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x89, 0xC7, 0xA3, 0x8C, 0xC1};  // 这里不写多少也行,会算出来
  74. void main()
  75. {
  76.         //
  77.         u8 num = 0;  // 显示数组中第几个字符
  78.        
  79.         sys_init();
  80.         usb_init();  //USB初始化
  81.        
  82.         //Timer0init();
  83.         EA = 1;
  84.        
  85.        
  86.        
  87.         P40 = 0;
  88.         P70 = 0;
  89.         P6 = 0;
  90.        
  91.         while(1)
  92.         {
  93.                 num = MateixKEY_Read();
  94.                 P6 = SEG_Tab[num];
  95.         }
  96. }
  97. /*
  98. 函数功能:定时器0中断执行函数
  99. 入口参数:@
  100. 函数返回:
  101. 其他备注:
  102. */
  103. void Timer0_Isr(void) interrupt 1
  104. {
  105.        
  106. }
  107. void sys_init()
  108. {
  109.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  110.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  111.     CKCON = 0; //提高访问XRAM速度
  112.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  113.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  114.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  115.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  116.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  117.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  118.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  119.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  120. }
复制代码





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-26 18:43:24 | 显示全部楼层
本帖最后由 noonezero 于 2023-9-27 07:46 编辑

第十五课:外部中断


1.什么是中断




中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。
当CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后再回到原来被中断的地方,继续原来的工作,这样的过程就叫中断。


2.中断的嵌套
正在执行中断的时候发生优先级更高的中断,会先去执行优先级高的


3.中断结构图
截图202309261740337221.jpg 截图202309261843044548.jpg



4.什么是外部中断
在单片机引脚上,由于外部因素导致一个电平的变化,跳变。而通过捕获这个变化,单片机内部自主运行的程序就会被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续原来的程序


5.程序代码
  1. #include <STC32G.H>
  2. #include "../COMM/stc32_stc8_usb.h"
  3. void sys_init();
  4. //USB调试及复位所需定义
  5. char *USER_DEVICEDESC = NULL;
  6. char *USER_PRODUCTDESC = NULL;
  7. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  8. void Delay_ms(int x)        //@24.000MHz
  9. {
  10.         unsigned long edata i;
  11.         for(; x > 0; x--)
  12.         {
  13.                 _nop_();
  14.                 _nop_();
  15.                 _nop_();
  16.                 i = 5998UL;
  17.                 while (i) i--;
  18.         }
  19. }
  20. void main()
  21. {
  22.         //
  23.         u8 num = 0;  // 显示数组中第几个字符
  24.         
  25.         sys_init();
  26.         usb_init();  //USB初始化
  27.         EA = 1;
  28.         
  29.         IT1 = 1;                        // 使能INT1下降沿中断
  30.         EX1 = 1;                        // 使能INT1中断
  31.         
  32.         P40 = 0;
  33.         P70 = 0;
  34.         P6 = 0;
  35.         
  36.         while(1)
  37.         {
  38.         }
  39. }
  40. void Timer1_Isr(void) interrupt 2   // 外部中断1中断函数
  41. {
  42.         P6 = ~P6;
  43. }
  44. void sys_init()
  45. {
  46.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  47.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  48.     CKCON = 0; //提高访问XRAM速度
  49.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  50.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  51.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  52.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  53.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  54.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  55.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  56.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  57. }
复制代码


问题,我用外部中断0,上下沿和下降沿都可以正常亮灭灯,但是用定时器1就不行,即使配置的是下降沿,上升沿的时候灯依旧会取反一次,我看原理图中有上拉电阻,不清楚原因,先略过,以后解答



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-9-27 09:54:44 | 显示全部楼层
本帖最后由 noonezero 于 2023-10-1 14:47 编辑

第十六课:IO中断


1.什么是IO中断
STC32G系列支持所有的I/O中断,且支持4种中断模式,下降沿中断,上升沿中断,低电平中断,高电平中断。每组IO口均有独立的中断入口地址,且每个IO可独立设置中断模式

2.寄存器相关配置

01使能寄存器配置

截图202309280741558457.jpg


02中断标志寄存器
截图202309280742283575.jpg
截图202309280742517407.jpg


03中断模式配置寄存器
截图202309280743152230.jpg
截图202309280743223854.jpg


04优先级控制寄存器



2.IO中断的用法

由于中断号大于31,keil不能直接编译,需要下载软件拓展中断号,下载地址深圳国芯人工智能有限公司-工具软件 (stcai.com)


3.中断优先级设置

截图202310011446366321.jpg

4.中断代码

  1. #include <STC32G.H>
  2. #include "../COMM/stc32_stc8_usb.h"
  3. void sys_init();
  4. //USB调试及复位所需定义
  5. char *USER_DEVICEDESC = NULL;
  6. char *USER_PRODUCTDESC = NULL;
  7. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  8. void Delay_ms(int x)        //@24.000MHz
  9. {
  10.         unsigned long edata i;
  11.         for(; x > 0; x--)
  12.         {
  13.                 _nop_();
  14.                 _nop_();
  15.                 _nop_();
  16.                 i = 5998UL;
  17.                 while (i) i--;
  18.         }
  19. }
  20. void main()
  21. {
  22.         sys_init();
  23.         usb_init();  //USB初始化
  24.         EA = 1;
  25.        
  26.         // P3IO中断配置 下降沿中断
  27.         P3IM0 = 0x00;
  28.         P3IM1 = 0x00;
  29.         P3INTE = 0x20;  // 使能P35中断 0010 0000
  30.         //P35INTE = 0;  // 这种方式不能用
  31.        
  32.         P40 = 0;
  33.         P70 = 0;
  34.         P6 = 0;
  35.        
  36.         while(1)
  37.         {
  38.         }
  39. }
  40. void P3Exit_Isr(void) interrupt 40   // 外部中断1中断函数
  41. {
  42.         u8 intf;
  43.        
  44.         intf = P3INTF;
  45.         if(intf)
  46.         {
  47.                 P3INTF = 0x00;
  48.                 if(intf & 0x20)
  49.                 {
  50.                         P6 = ~P6;
  51.                 }
  52.         }
  53. }
  54. void sys_init()
  55. {
  56.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  57.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  58.     CKCON = 0; //提高访问XRAM速度
  59.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  60.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  61.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  62.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  63.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  64.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  65.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  66.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  67. }
复制代码








截图202310011445399257.jpg
截图202310011446001206.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-10-2 12:43:48 | 显示全部楼层
本帖最后由 noonezero 于 2023-10-4 17:33 编辑

第十七课:模数转换器ADC


1.模数转换器是什么


模数转换器即A/D转换器,简称ADC,通常是指一个将模拟信号转变为数字信号的电子元器件


  模拟信号 -> 电压
  数字信号 -> 0/1组成的二进制数


如果芯片有ADC的外部参考电源管脚 ADC_VRef+, 则一定不能浮空,必须接外部参考电源或者直接连到VCC。


2.需要配置的寄存器
截图202310021515069831.jpg


ADC_POWER:ADC电源控制位,0关闭ADC,1打开。建议进入空闲模式和掉电模式前将ADC电源关闭,以降低功耗;
                      1. 给MCU的内部ADC模块电源打开后,需等待约1ms,等MCU内部的ADC电源稳定后再让ADC工作。
                      2.适当加长对外部信号的采样时间,就是对ADC内部采样保持电容的充电放电时间,时间够,内部才能和外部电势相等。



ADC_START:开始转换,转换后自动清0,手动输0不会停止转换
ADC_FLAG:转换结束标志位,转换完成会置1,需要软件清零
ADC_EPWMP:暂空,需要PWM
ADC_CHS:通道选择位,选择好通道需要把对应IO口设置为高阻输入


RESFMT:0转换结果左对齐,1右对齐
SPEED:设置ADC时钟


ADC_RES:转换结果高位
ADC_RESL:转换结果低位



3.ADC速度计算公式
截图202310021532458916.jpg


4.ADC转换结果公式
截图202310021533254877.jpg


5.反推ADC输入电压计算公式
截图202310021537555957.jpg


5.反推工作电压计算公式
截图202310021538308912.jpg


6.代码-查询方式

  1. #include "config.h"
  2. #include <STC32G.H>
  3. #include "../COMM/stc32_stc8_usb.h"
  4. #include "stdio.h"
  5. void sys_init();
  6. //USB调试及复位所需定义
  7. char *USER_DEVICEDESC = NULL;
  8. char *USER_PRODUCTDESC = NULL;
  9. char *USER_STCISPCMD = "@STCISP#";
  10. // ADC初始化
  11. void ADC_init()
  12. {
  13.         //P10高祖输入
  14.         P0M1 &= 0xFE;
  15.         P0M1 |= 0x01;
  16.        
  17.         ADCTIM = 0x3F;        // 设置ADC内部时序
  18.         ADCCFG = 0x2F;        // 数据右对齐,方便合二为一。时钟选择为最慢
  19.         ADC_POWER = 1;        // 打开ADC电源
  20. }
  21. // ADC读取
  22. u16 ADC_Read(u8 num)
  23. {
  24.         u16 adcval;                                // ADC数值保存变量
  25.         ADC_CONTR &= 0xF0;                // 清空通道
  26.         ADC_CONTR |= num;                // 选择通道
  27.         ADC_START = 1;                        // 开启ADC转化
  28.         _nop_();                                // 空操作指令
  29.         _nop_();
  30.         while(!ADC_FLAG);                // 等待ADC转换结束
  31.         ADC_FLAG = 0;                        // 手动清零
  32.         adcval = (ADC_RES << 8) + ADC_RESL;        // 计算ADC数值
  33.        
  34.         return adcval;
  35.        
  36. }
  37. void main()
  38. {
  39.         u16 ADC_VAL;
  40.         sys_init();
  41.         usb_init();  //USB初始化
  42.         EA = 1;
  43.        
  44.         ADC_init();
  45.        
  46.         while(1)
  47.         {
  48.                 if (bUsbOutReady)
  49.         {
  50.             USB_SendData(UsbOutBuffer, 64);
  51.             usb_OUT_done();
  52.                 }
  53.                 ADC_VAL = ADC_Read(0);
  54.                 printf("adcvalue\t%d\r\n",(int)ADC_VAL);
  55. //                printf("wenjun\r\n");
  56.         }
  57. }
  58. void sys_init()
  59. {
  60.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  61.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  62.     CKCON = 0; //提高访问XRAM速度
  63.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  64.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  65.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  66.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  67.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  68.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  69.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  70.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  71. }
复制代码



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:407
  • 最近打卡:2025-06-29 09:45:45

2

主题

87

回帖

1110

积分

金牌会员

积分
1110
发表于 2023-10-5 15:24:12 | 显示全部楼层
第十八课:ADC采集电源电压和ADC按键


1.ADC采集电源电压

内部1.19V电源有+-1%误差,可以利用ADC的第15通道反推ADC_VRef+脚外接参考电源电压


截图202310051439598625.jpg



  1. #include "config.h"
  2. #include <STC32G.H>
  3. #include "../COMM/stc32_stc8_usb.h"
  4. #include "stdio.h"
  5. #define                VREFH_ADDR                CHIPID7
  6. #define                VREFL_ADDR                CHIPID8
  7. int BGV;
  8. void sys_init();
  9. //USB调试及复位所需定义
  10. char *USER_DEVICEDESC = NULL;
  11. char *USER_PRODUCTDESC = NULL;
  12. char *USER_STCISPCMD = "@STCISP#";
  13. // ADC初始化
  14. void ADC_init()
  15. {
  16.         ADCTIM = 0x3F;        // 设置ADC内部时序
  17.         ADCCFG = 0x2F;        // 数据右对齐,方便合二为一。时钟选择为最慢
  18.         ADC_CONTR = 0x8F;                // 选择通道15
  19. }
  20. // ADC读取
  21. int ADC_Read()
  22. {
  23.         int res;                                // ADC数值保存变量
  24.        
  25.         ADC_START = 1;                        // 开启ADC转化
  26.         _nop_();                                // 空操作指令
  27.         _nop_();
  28.         while(!ADC_FLAG);                // 等待ADC转换结束
  29.         ADC_FLAG = 0;                        // 手动清零
  30.         res = (ADC_RES << 8) | ADC_RESL;        // 计算ADC数值
  31.        
  32.         return res;
  33. }
  34. void main()
  35. {
  36.         int res;
  37.         int vcc;
  38.         int i;
  39.         sys_init();
  40.         usb_init();  //USB初始化
  41.         EA = 1;
  42.        
  43.         BGV = (VREFH_ADDR << 8) + VREFL_ADDR;                // 从CHIPID中读取内部参考电压值
  44.        
  45.         ADC_init();
  46.         ADC_Read();
  47.         ADC_Read();
  48.         ADC_Read();
  49.         ADC_Read();                // 舍弃四个值
  50.        
  51.         res = 0;
  52.         for(i=0; i<8; i++)
  53.         {
  54.                 res += ADC_Read();
  55.         }
  56.         res >>= 3;  // res / 8 算平均值
  57.         vcc = (int)(4096L * BGV / res);
  58.        
  59.         while(1)
  60.         {
  61.                 if (bUsbOutReady)
  62.         {
  63.             USB_SendData(UsbOutBuffer, 64);
  64.             usb_OUT_done();
  65.                 }
  66.                 printf("power \t%d\r\n", vcc);
  67.         }
  68. }
  69. void sys_init()
  70. {
  71.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  72.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  73.     CKCON = 0; //提高访问XRAM速度
  74.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  75.     P1M1 = 0x32;   P1M0 = 0x32;   //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
  76.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
  77.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  78.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  79.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  80.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  81.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  82. }
复制代码






ADC按键,后面补,我的实验箱有点BUG,按键1-5可以用,其他都不行。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-7-2 21:24 , Processed in 0.162938 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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