找回密码
 立即注册
查看: 1716|回复: 5

STC8G1K08A学习方法

[复制链接]

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 2023-9-7 11:15:28 | 显示全部楼层 |阅读模式
各位大佬,有没有什么方法可以看懂单片机的数据手册,里面的内容太抽象了,看前面忘后面。
想实现具体功能,却无从下手,不知道各个寄存器之间的联系。
比如ADC的电压采集,也找不到具体的例子。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:527
  • 最近打卡:2025-05-07 00:40:41

10

主题

1162

回帖

5197

积分

论坛元老

积分
5197
发表于 2023-9-7 12:18:18 | 显示全部楼层
就是要看数据手册啊,从这里看起。
你要学 ADC 就看 ADC的章节吧。
STC8G_ADC001.png

点进去就可以看那个章节,然后跟着他的案例程序运行就可以了。
STC8G_ADC002.png



  1. <font size="3">/*
  2. 16.6 范例程序
  3. 16.6.1 ADC 基本操作(查询方式)
  4. C 语言代码
  5. */
  6. //测试工作频率为11.0592MHz
  7. #include "reg51.h"
  8. #include "intrins.h"
  9. sfr ADC_CONTR = 0xbc;
  10. sfr ADC_RES = 0xbd;
  11. sfr ADC_RESL = 0xbe;
  12. sfr ADCCFG = 0xde;
  13. sfr P_SW2 = 0xba;
  14. #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
  15. sfr P0M1 = 0x93;
  16. sfr P0M0 = 0x94;
  17. sfr P1M1 = 0x91;
  18. sfr P1M0 = 0x92;
  19. sfr P2M1 = 0x95;
  20. sfr P2M0 = 0x96;
  21. sfr P3M1 = 0xb1;
  22. sfr P3M0 = 0xb2;
  23. sfr P4M1 = 0xb3;
  24. sfr P4M0 = 0xb4;
  25. sfr P5M1 = 0xc9;
  26. sfr P5M0 = 0xca;
  27. void main()
  28. {
  29.         P0M0 = 0x00;
  30.         P0M1 = 0x00;
  31.         P1M0 = 0x00;
  32.         P1M1 = 0x00;
  33.         P2M0 = 0x00;
  34.         P2M1 = 0x00;
  35.         P3M0 = 0x00;
  36.         P3M1 = 0x00;
  37.         P4M0 = 0x00;
  38.         P4M1 = 0x00;
  39.         P5M0 = 0x00;
  40.         P5M1 = 0x00;
  41.         P1M0 = 0x00; //设置P1.0 为ADC 口
  42.         P1M1 = 0x01;
  43.         P_SW2 |= 0x80;
  44.         ADCTIM = 0x3f; //设置ADC 内部时序
  45.         P_SW2 &= 0x7f;
  46.         ADCCFG = 0x0f; //设置ADC 时钟为系统时钟/2/16
  47.         ADC_CONTR = 0x80; //使能ADC 模块
  48.         while (1)
  49.         {
  50.                 ADC_CONTR |= 0x40; //启动AD 转换
  51.                 _nop_();
  52.                 _nop_();
  53.                 while (!(ADC_CONTR & 0x20)); //查询ADC 完成标志
  54.                 ADC_CONTR &= ~0x20; //清完成标志
  55.                 P2 = ADC_RES; //读取ADC 结果
  56.                 ADCCFG = 0x00; //设置结果左对齐
  57.                 ACC = ADC_RES; //A 存储ADC 的10 位结果的高8 位
  58.                 B = ADC_RESL; //B[7:6]存储ADC 的10 位结果的低2 位,B[5:0]为0
  59.                 // ADCCFG = 0x20; //设置结果右对齐
  60.                 // ACC = ADC_RES; //A[1:0]存储ADC 的10 位结果的高2 位,A[7:2]为0
  61.                 // B = ADC_RESL; //B 存储ADC 的10 位结果的低8 位
  62.         }
  63. }
  64. </font>
复制代码


  1. <font size="3">
  2. /*
  3. 16.6.4 利用ADC 第15 通道测量外部电压或电池电压
  4. STC8G 系列ADC 的第15 通道用于测量内部参考信号源,由于内部参考信号源很稳定,约为1.19V,
  5. 且不会随芯片的工作电压的改变而变化,所以可以通过测量内部1.19V 参考信号源,然后通过ADC 的
  6. 值便可反推出外部电压或外部电池电压。
  7. 下图为参考线路图:
  8. C 语言代码
  9. */
  10. //测试工作频率为11.0592MHz
  11. #include "reg51.h"
  12. #include "intrins.h"
  13. #define FOSC 11059200UL
  14. #define BRT (65536 - FOSC / 115200 / 4)
  15. sfr AUXR = 0x8e;
  16. sfr ADC_CONTR = 0xbc;
  17. sfr ADC_RES = 0xbd;
  18. sfr ADC_RESL = 0xbe;
  19. sfr ADCCFG = 0xde;
  20. sfr P_SW2 = 0xba;
  21. #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
  22. sfr P0M1 = 0x93;
  23. sfr P0M0 = 0x94;
  24. sfr P1M1 = 0x91;
  25. sfr P1M0 = 0x92;
  26. sfr P2M1 = 0x95;
  27. sfr P2M0 = 0x96;
  28. sfr P3M1 = 0xb1;
  29. sfr P3M0 = 0xb2;
  30. sfr P4M1 = 0xb3;
  31. sfr P4M0 = 0xb4;
  32. sfr P5M1 = 0xc9;
  33. sfr P5M0 = 0xca;
  34. int *BGV;         //内部1.19V 参考信号源值存放在idata 中
  35.                         //idata 的EFH 地址存放高字节
  36.                         //idata 的F0H 地址存放低字节
  37.                         //电压单位为毫伏(mV)
  38. bit busy;
  39. void UartIsr() interrupt 4
  40. {
  41.         if (TI)
  42.         {
  43.                 TI = 0;
  44.                 busy = 0;
  45.         }
  46.         if (RI)
  47.         {
  48.                 RI = 0;
  49.         }
  50. }
  51. void UartInit()
  52. {
  53.         SCON = 0x50;
  54.         TMOD = 0x00;
  55.         TL1 = BRT;
  56.         TH1 = BRT >> 8;
  57.         TR1 = 1;
  58.         AUXR = 0x40;
  59.         busy = 0;
  60. }
  61. void UartSend(char dat)
  62. {
  63.         while (busy);
  64.         busy = 1;
  65.         SBUF = dat;
  66. }
  67. void ADCInit()
  68. {
  69.         P_SW2 |= 0x80;
  70.         ADCTIM = 0x3f; //设置ADC 内部时序
  71.         P_SW2 &= 0x7f;
  72.         ADCCFG = 0x2f; //设置ADC 时钟为系统时钟/2/16
  73.         ADC_CONTR = 0x8f; //使能ADC 模块,并选择第15 通道
  74. }
  75. int ADCRead()
  76. {
  77.         int res;
  78.         ADC_CONTR |= 0x40; //启动AD 转换
  79.         _nop_();
  80.         _nop_();
  81.         while (!(ADC_CONTR & 0x20)); //查询ADC 完成标志
  82.         ADC_CONTR &= ~0x20; //清完成标志
  83.         res = (ADC_RES << 8) | ADC_RESL; //读取ADC 结果
  84.         return res;
  85. }
  86. void main()
  87. {
  88.         int res;
  89.         int vcc;
  90.         int i;
  91.         P0M0 = 0x00;
  92.         P0M1 = 0x00;
  93.         P1M0 = 0x00;
  94.         P1M1 = 0x00;
  95.         P2M0 = 0x00;
  96.         P2M1 = 0x00;
  97.         P3M0 = 0x00;
  98.         P3M1 = 0x00;
  99.         P4M0 = 0x00;
  100.         P4M1 = 0x00;
  101.         P5M0 = 0x00;
  102.         P5M1 = 0x00;
  103.         BGV = (int idata *)0xef; //内部1.19V 参考信号源值存放在idata 中
  104.         ADCInit(); //ADC 初始化
  105.         UartInit(); //串口初始化
  106.         ES = 1;
  107.         EA = 1;
  108.         // ADCRead();
  109.         // ADCRead(); //前两个数据建议丢弃
  110.         res = 0;
  111.         for (i=0; i<8; i++)
  112.         {
  113.                 res += ADCRead(); //读取8 次数据
  114.         }
  115.         res >>= 3; //取平均值
  116.         vcc = (int)(1024L * *BGV / res);    //(10 位ADC 算法)计算VREF 管脚电压,即电池电压
  117.         // vcc = (int)(4096L * *BGV / res); //(12 位ADC 算法)计算VREF 管脚电压,即电池电压
  118.         //注意,此电压的单位为毫伏(mV)
  119.         UartSend(vcc >> 8); //输出电压值到串口
  120.         UartSend(vcc);
  121.         while (1);
  122. }
  123. /*
  124. 上面的方法是使用ADC 的第15 通道反推外部电池电压的。在ADC 测量范围内,ADC 的外部测量
  125. 电压与ADC 的测量值是成正比例的,所以也可以使用ADC 的第15 通道反推外部通道输入电压,假设
  126. 当前已获取了内部参考信号源电压为BGV,内部参考信号源的ADC 测量值为resbg,外部通道输入电压
  127. 的ADC 测量值为resx,则外部通道输入电压Vx=BGV / resbg * resx;
  128. */
  129. </font>
复制代码









回复 支持 反对

使用道具 举报 送花

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 2023-9-7 13:19:35 | 显示全部楼层
angm*** 发表于 2023-9-7 12:18
就是要看数据手册啊,从这里看起。
你要学 ADC 就看 ADC的章节吧。

谢谢,你发的程序有注释说明,所以理解起来要好一点。
回复 支持 反对

使用道具 举报 送花

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 2023-9-7 13:20:55 | 显示全部楼层
市面上不知道有没有类似像大话数据结构这样的书籍,可以通俗易懂的讲解单片机。
回复 支持 反对

使用道具 举报 送花

0

主题

1

回帖

20

积分

新手上路

积分
20
发表于 2024-3-10 17:46:47 | 显示全部楼层
你好,我使用一枚3s电池,参考上面的代码写出来之后,返回的电压值是5816(mv),而正常电压应该为12000(mv)左右,请问这个程序检测的电压值是有上限的吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:59
  • 最近打卡:2025-05-06 09:22:11

718

主题

1万

回帖

1万

积分

管理员

积分
15676
发表于 2024-3-10 18:05:05 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-7 02:26 , Processed in 0.252614 second(s), 88 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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