找回密码
 立即注册
查看: 2403|回复: 9

STC32G128K芯片学习打卡贴

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-17 11:38:59 | 显示全部楼层 |阅读模式
本帖最后由 好学天上 于 2024-5-31 17:46 编辑

实验箱教学视频打卡

第一至三集 评论区打卡
  
截图202404171137485306.jpg
截图202404171138219272.jpg 截图202404171138421549.jpg

第四集 点灯打卡 2024-04-18

LED点亮原理:两边电压差
GPIO:软件可以读取引脚输入电平或控制引脚输入电平(总算搞明白)
基本的书写规则
查找:ctrl+f
不掉电下载:根据视频加了lib文件和库文件,不知道为啥还是报错,也找了范例程序还是没找出原因。
作业点亮所以LED灯,按照之前学的,可以一个一个点亮P60 =0; P61=0....也可以P6=0x00即0000 0000八个口全置0点亮。
工程基本流程已掌握。
希望有老师可以解决一下我的问题
(os:讲课的老师手真好看嘻嘻)
截图202404181042448783.jpg 截图202404181659492597.jpg 已解决,没设置memory model,这也是和51不一样的地方;

第五集 C语言运算符打卡 2024-04-19

这节课的内容都比较基础,是在学校学C语言和单片机的时候都讲过
还有一个printf函数的使用,进制转换那些我们以前考试经常考的基础题,以及与或非之类的逻辑运算。还有变量类型以及它的大小。没有特别大的难度
截图202404191128301563.jpg

第六集 流水灯打卡 2024-04-20

1. u16 → unsigned int
2.while和do while的区别:while一开始就做判断,判断条件为真则进入循环;do while会先执行一遍循环体,再做条件判断是否继续执行循环体;while比do while应用更多
3.--a和a--的区别: 若a=10; →--a=9;a=9;  而a--=9;a=9  a--是先进行取值,后进行自减;--a是先进行自减,后进行取值;
4.编程中常见小错误:忘记写分号;关键词写错;
5.#dedine用法,相当于把需要定义的内容换一个名字 。
截图202404200958568759.jpg 哎哟 我已经掌握了图片排列的奥秘!
函数使用三步: 定义→声明→调用
截图202404201044401606.jpg
截图202404201045205887.jpg
截图202404201046158401.jpg
课后练习:SOS灯光
截图202404201138542114.jpg 没有一行一行写,但感觉应该有更简便的方法。

第七集 按键 打卡 2024-04-22

1.按键的原理:两个引脚间的通断:按下之后导通(常开);按下之后断开(常闭);
2.注意:机械开关断开闭合时都会有抖动,所以要靠变成消抖,判断按键状态后等待10ms后再次判断开关状态,此为消抖
3.按键应用:按下点亮松开熄灭;按下熄灭松开点亮;按一下取反;按一下led灯左移一位
截图202404221046371915.jpg
截图202404221334446109.jpg

4.数组的应用:定义→赋值,索引是长度减1,因为是从0开始。
截图202404221341343178.jpg
5.课后作业:按下一次,LED右移一位
截图202404221347505967.jpg

第八集 蜂鸣器 打卡 2024-04-23

1.蜂鸣器:无源蜂鸣器和有源蜂鸣器,区别是有源蜂鸣器内部有震荡,通电即可打开,而无源直流信号无法令其运行;
2.控制原理:和LED相同
3.电磁炉实战:按键配合LED和蜂鸣器,其实是把前几节课都结合起来了。
截图202404231056028781.jpg
ps:老师好像没有在写第二个功能模式按键的时候做开机判断,这样即使在关机模式也可以功能切换吧。
4.课后作业:第三个启动按键,按下对应功能模式闪烁,且功能切换不可用
截图202404231146165135.jpg

第九-十集数码管打卡 2024-04-24

1.数码管:多个发光二极管组成
2.控制原理:和LED类似,共阳给0亮,共阴给1亮
3.按键循环0-9:
截图202404241047026374.jpg

4.静态显示作业:H 0x89;J 0xF0;L 0xC7;n 0xAD;o 0xA3;P 0x8C;U 0xC1;t 0x87;r 0x8F
按键1自加循环0-9,按键2控制蜂鸣器鸣叫对应数字次数
截图202404241049038500.jpg

5.数码管动态显示原理:每一位数码管轮流点亮,但间隔时间只有1ms,是因为人无法分辨50Hz以上的刷新频率二产生视觉残留,看起来好像是一起亮的。
6.10秒免单计数器
截图202404241513168665.jpg

7.注意事项:写代码过程中会有很多不注意的小细节,简单的书写错误,格式错误都会在最后要调试很多次,还是写得太少。
8.课后作业:简易时钟  00.00.00,三十秒时闹钟响,蜂鸣器鸣叫3s;
截图202404241625047751.jpg

截图202404241626117313.jpg
本来想的是把闹钟设置直接放函数中判断,打开之后延时3s后关闭,但这样会干扰到本身的时钟运转,所以就设置了一个时钟标志位,将三秒的时间放入到时钟计数当中。但其实这种时钟计时方式应该本身就会不那么准确的。

第十一-十二集 定时计数器打卡 2024-04-25

1.定时器是定时/计数器的统称,定时器是硬件计时或每隔一段时间完成一次操作,可以替代长时间延时,提高CPU运行效率和处理速度,能及时响应某个事件;
2.相关的寄存器:TMOD,使用模式0定时器时,值为0x00;AUXR寄存器,设置分频,默认为12分频;定时器工作模式有模式0-16位自动重载,模式1-16位不自动重载,模式2-8位自动重载,模式3-不可屏蔽中断的16位自动重载,其中断优先级最高;
3.定时器初始化步骤:设置模式TMOD→设置分频AUXR→设置时间TH,TL→启动定时器TR0→使能定时器中断ET0→使能总中断EA
4.作业:用定时器驱动时钟并设置启动暂停按键
截图202404251034284463.jpg 主函数
截图202404251035106465.jpg 定时器函数;
5.计数器:计数器用途有电机测速等,输出信号带高低电平变化都可以用计数器;
6.计数器的配置:
截图202404251359251407.jpg 按键P35每按下一次,led灯P60状态取反一次;

7.例程:电机测速模拟,用按键模拟脉冲
截图202404251514164680.jpg

8.作业:2s周期改为每分钟:
截图202404251517283217.jpg

9.思考:如果计数器溢出了程序要怎么写? 答:说实话这节课还有点云里雾里。

第十三集 TIM多任务处理打卡 2024-04-26

1.创建程序文件三步;程序定义三步,函数定义三步;这里前面的课程都有提到过。
2.extern:在a文件里要使用b文件的变量时,用extern在b的库文件中定义该变量,再在a.c中包含b的库文件;
3.bdata位寻址变量定义,例如定义一个八位变量使用bdata,可以分别定义八位的每一位,单独赋值。
4.static静态变量,静态变量时的赋值只一次有效;
5.数码管LED的程序文件:
截图202404261739174852.jpg 截图202404261739421066.jpg
2024-04-28接上文
6.按键的函数文件,不使用while循环,改用状态机的模式,在主函数中定时使用循环读取每个按键状态的函数,再在使用到某个按键时,使用另一个函数直接读取该按键的状态,返回定义好的状态返回值,有未按下,抖动,按下,按下结束,长按,长按结束这些状态,再在主函数当中通过判断该按键状态来书写功能函数:
截图202404281134242435.jpg key.h
截图202404281135035805.jpg 截图202404281135557607.jpg key.c
截图202404281136244842.jpg 主函数中功能实现

7.蜂鸣器的函数文件,通过设置蜂鸣器鸣叫时间的函数来决定蜂鸣器要不要叫,要叫多久,再在主函数中10ms循环运行蜂鸣器运行函数,当设置的时间等于0,蜂鸣器不鸣叫,大于0,则鸣叫该时间后关闭。
截图202404281344558225.jpg beep.h

截图202404281345595472.jpg beep.c

截图202404281346304573.jpg beep在主函数中调用使用。

8.定时器函数文件,只需要将之前在主函数写的定时器初始化移到定时器c文件中,在主函数里调用函数使用;而中断函数最好仍在主函数中书写,因其需要调用不同的功能函数,所以放在主函数更佳。
9.课后作业:
LED0每200ms取反一次;LED1每400ms取反一次;LED2每800ms取反一次
截图202404281450026199.jpg 感觉这个方法不是那么聪明的样子;

改写电磁炉程序:
截图202404281531294289.jpg

10.体会:主要是将程序都结构化,让看代码的人也能清晰易懂,修改优化程序时更方便。

第十四集 矩阵按键打卡 2024-04-29

1.矩阵按键:每行由一个IO口控制,每列由一个IO口控制,不同于独立按键的一对一IO口,可以大大节省硬件资源;
2.控制原理:通过扫描行和列,判断按键按下位置,类似二维坐标;先将行IO都置低电平,列置高电平,确定哪一列;再将行置高电平,列置低电平,确定哪一行;通过二者确定按键位置;
截图202404291131587190.jpg

3.实践程序:电子门锁----矩阵按键输入八位密码,密码正确门开则LED亮,密码错误蜂鸣器鸣叫2s后关闭;每次按键输入蜂鸣器鸣叫20ms。
+课后作业:门锁打开5s后自动关闭,切回锁定状态,设置门内手动开门按钮,使用独立按键,可以一键直接开门;10s内无操作数码管熄灭,有操作即点亮。
  1. #include "COMM/stc.h"
  2. #include "COMM/usb.h"
  3. #include "led_seg.h"
  4. #include "key.h"
  5. #include "beep.h"
  6. #include "time0.h"
  7. char *USER_DEVICEDESC = NULL;
  8. char *USER_PRODUCTDESC = NULL;
  9. char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
  10. bit TIME_10MS = 0; //10ms标志位
  11. void delay_ms(u16 ms);
  12. void sys_init(void);
  13. #define MAIN_Fosc    24000000UL
  14. u16 timi = 0;
  15. void main()  //程序开始运行的入口
  16. {
  17.   u8 key_num = 0; //矩阵按键键值
  18.         u8 key_str = 0; //密码输入数量
  19.         u8 i;
  20.         u32 count = 0;  //计时单位
  21.         bit flag = 0;  //门锁是否开启标志
  22.         sys_init();  //USB功能+IO初始化
  23.         usb_init();  //USB CDC 接口配置
  24.         
  25.         Timer0_Init();
  26.         EA = 1;  //打开总中断
  27.         
  28.         SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =22;  //初始显示--------
  29.         LED = 0xff;  //数码管和LED显示
  30.    
  31.         while(1)      //死循环
  32.         {
  33.                 if(DeviceState != DEVSTATE_CONFIGURED)
  34.                         continue;
  35.                 if(bUsbOutReady)
  36.                 {
  37.                         usb_OUT_done();  //接受应答(固定格式)
  38.                 }
  39.                 if(TIME_10MS == 1) //10ms刷新一次
  40.                 {
  41.                         TIME_10MS =0;
  42.                         count++;
  43.                         BEEP_RUN(); //蜂鸣器运行
  44.                         KEY_Deal(); //读取按键状态
  45.                         key_num = MatrixKEY_Read(); //获取键值
  46.                         if(count == 100) //10s时数码管全都关闭
  47.                         {
  48.                                 count = 0;
  49.                                 SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =21;
  50.                         }
  51.                         if(key_num > 0)  //有按键按下
  52.                         {
  53.                                 count = 0; //有按键按下时,重新计算10s
  54.                                 BEEP_ON(2); //每次按键按下蜂鸣器叫20ms
  55.                                 key_str++; //密码位数++
  56.                                 show_Tab[key_str] = key_num; //数码管显示输入值
  57.                                 if(key_str > 8) //输入密码已达八位
  58.                                 {
  59.                                         key_str = 0; //初始化密码位数
  60.                                         for(i = 0; i < 8; i++)
  61.                                         {
  62.                                                 if(show_Tab[i] == 1) //判断每一位都等于1否
  63.                                                 {
  64.                                                         flag = 1; //密码一致
  65.                                                 }
  66.                                                 else
  67.                                                 {
  68.                                                         flag = 0; //有任何一位不一致,返回门锁未开标志,退出循环
  69.                                                         break;
  70.                                                 }
  71.                                         }
  72.                                         if(flag == 1 )  //门锁已开,灯亮
  73.                                         {
  74.                                                 LED0 = 0;
  75.                                                 delay_ms(5000); //门开后5s,继续上锁,返回门锁上标志
  76.                                                 flag = 0;
  77.                                         }
  78.                                         else if(flag == 0) //门锁关闭,蜂鸣器鸣叫2s,灯灭
  79.                                         {
  80.                                                 BEEP_ON(20);
  81.                                                 LED0 = 1;
  82.                                         }
  83.                                         SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =22;
  84.                                 }
  85.                                 key_num = 0;
  86.                         }
  87.                 }
  88.                 if(KEY_ReadState(KEY1) == KEY_PRESS) //按下按键1,门直接打开
  89.                 {
  90.                         flag = 1;
  91.                 }
  92.         }
  93. }
  94. void Timer0_Isr(void) interrupt 1
  95. {
  96.         static time_count = 0;
  97.         SEG_refresh();                //刷新数码管
  98.         time_count++;
  99.         if(time_count >= 10)
  100.         {
  101.                 TIME_10MS = 1;  //10ms时间到
  102.     time_count = 0;
  103.         }
  104. }
  105. void Timer1_Isr(void) interrupt 3
  106. {
  107.         
  108. }
  109. void sys_init()
  110. {
  111.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  112.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  113.     CKCON = 0; //提高访问XRAM速度
  114.     P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
  115.     P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
  116.     P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
  117.     P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
  118.     P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
  119.     P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
  120.     P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
  121.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  122.     //====== USB 初始化 ======
  123.     P3M0 &= ~0x03;
  124.     P3M1 |= 0x03;
  125.    
  126.     IRC48MCR = 0x80;
  127.     while (!(IRC48MCR & 0x01));
  128.    
  129.     USBCLK = 0x00;
  130.     USBCON = 0x90;
  131.     //========================
  132. }
  133. void delay_ms(u16 ms)
  134. {
  135.         u16 i;
  136.         do
  137.         {
  138.                 i=MAIN_Fosc/6000;
  139.                 while(--i);
  140.         }
  141.         while(--ms);
  142. }
复制代码

第十五集 外部中断打卡 2024-04-29

1.中断系统:CPU处理紧急事件的功能部件。优点:a.总是响应优先级最高的中断请求;b.每个中断源都可以独立控制开关;c.低优先级中断处理中可以被高优先级中断打断;d.部分中断源优先级可以通过软件改变。
2.外部中断:单片机的一个引脚上由于外部因素造成的电平变化(如按键按下),引起的中断就是外部中断.单片机原理图标了INTx的就是外部中断口.
3.外部中断使用:
  1. void INT0_init(void)  //外部中断初始化函数
  2. {
  3.         IT0 = 1;  //1为下降沿有效,0为上升沿下降沿均可触发
  4.         EX0 = 1;  //中断允许
  5.         IE0 = 0;  //清楚中断标志
  6. }
复制代码
//外部中断0初始化
截图202404291649446810.jpg

//中断功能函数
弄清中断使用的寄存器的每个标志位的高低电平分别是什么功能.
4.课后作业:写外部中断1和中断2-4的函数
  1. void INT1_init(void)  //外部中断1
  2. {
  3.   IT1 = 1;  //1为下降沿有效,0为上升沿下降沿均可触发
  4.         EX1 = 1;  //中断允许
  5.         IE1 = 0;  //清楚中断标志
  6. }
  7. void INT1_isr(void) interrupt 2
  8. {
  9.         //功能
  10. }
  11. void INT2_init(void)  //外部中断2
  12. {
  13.   //只能下降沿触发
  14.         EX2 = 1;  //中断允许
  15. }
  16. void INT2_isr(void) interrupt 10
  17. {
  18.         //功能
  19. }
  20. void INT3_init(void)  //外部中断3
  21. {
  22.   //只能下降沿触发
  23.         EX3 = 1;  //中断允许
  24. }
  25. void INT3_isr(void) interrupt 11
  26. {
  27.         //功能
  28. }
  29. void INT4_init(void)  //外部中断4
  30. {
  31.   //只能下降沿触发
  32.         EX4 = 1;  //中断允许
  33. }
  34. void INT4_isr(void) interrupt 16
  35. {
  36.         //功能
  37. }
复制代码
思考:什么时候用外部中断?
之前学的定时器中断使用在周期性中断,一定时间才会处理一次事件,而外部中断,只要有外部触发就可以产生中断,优先处理,且执行完以后会自己继续执行主程序。可以用外部中断来写之前按键的功能函数。


第十六集 IO中断打卡 2024-04-30

1.IO中断:普通IO口均可中断,有四种触发方式,低电平、高电平、上升沿、下降沿;stc32暂时别用上升沿和下降沿触发方式;
2.IO中断和外部中断的区别:外部中断只能单次触发,用下降沿触发;IO口使用高电平,低电平触发,可以持续进入中断,例如按键按住不放,持续低电平,按下有效,松开无效;
3.IO中断相关寄存器: PnIM1 PnIM0 --设置触发方式;INTE -- 中断使能,0关1开;INTF -- 中断标志寄存器 0无中断请求,1有中断请求,若使能中断了,标志位需软件清零;PnIPH PnIP -- 设置中断优先级 00-11,00是最低的11是最高的;
  1. void P3EXIT_init(void)
  2. {
  3.         P3IM0 = 0X00;
  4.         P3IM1 = 0XFF;                                        //M1 M0 = 10 低电平中断
  5.         P3INTE = 0X20;                                        //p35中断  0010 0000  
  6. }
复制代码
//IO中断初始化程序
4.实践:八个按键对应八个LED灯,按键按下灯亮门开,灯灭门锁;一个独立按键模拟应急按钮,按下门全开,且不能用按键解锁,再次按下应急按钮则五秒后解锁:
  1. void main()  //程序开始运行的入口
  2. {
  3.   u8 key_num = 0; //矩阵按键键值
  4.         u8 key_str = 0; //密码输入数量
  5.         bit flag = 0;  //门锁是否开启标志
  6.         sys_init();  //USB功能+IO初始化
  7.         usb_init();  //USB CDC 接口配置
  8.         
  9.         Timer0_Init();
  10.         EA = 1;  //打开总中断
  11.         
  12.         SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =22;  //初始显示--------
  13.         LED = 0xff;  //数码管和LED显示
  14.    
  15.         while(1)      //死循环
  16.         {
  17.                 if(DeviceState != DEVSTATE_CONFIGURED)
  18.                         continue;
  19.                 if(bUsbOutReady)
  20.                 {
  21.                         usb_OUT_done();  //接受应答(固定格式)
  22.                 }
  23.                 if(TIME_10MS == 1)
  24.                 {
  25.                         TIME_10MS = 0;
  26.                         if( Tcount ==0 )                                                                //如果没有按下过应急按钮
  27.                         {
  28.                                 key_num = MatrixKEY_Read();                                                //当前矩阵按键的键值  1-8
  29.                                 BEEP_RUN();                                                                                //蜂鸣运行
  30.                                 if( key_num > 0 )                                                                        //如果有按键拿下
  31.                                 {
  32.                                         BEEP_ON(2);
  33.                                         flag ^=  (1<<(key_num-1));                        //获取当前是第几个按钮按下,{1-8}-》
  34.                                 }
  35.                                 LED = flag;                                                                //初始状态熄灭所有LED
  36.                                 SEG0 = 21;                                                                                //熄灭数码管
  37.                         }
  38.                         else                                                                                                //按下了应急按钮
  39.                         {
  40.                                 Tcount--;
  41.                                 SEG0 = (Tcount/100+1);                                        //500/100 499
  42.                         }
  43.                 }
  44.                         
  45.         }
  46. }
复制代码
//主程序
  1. void P3EXIT_isr(void) interrupt 40
  2. {
  3.         u8 intf;
  4.         intf = P3INTF ;  //中断标志寄存器
  5.         if (intf)
  6.         {
  7.                 P3INTF = 0x00;  //清零标志位
  8.                 if(intf & 0x20)
  9.                 {
  10.                         LED = 0x00;                        //打开所有门锁
  11.                         SEG0 = 5;                        //数码管持续显示5
  12.                         Tcount = 500;//5秒倒计时的一个变化
  13.                 }
  14.         }
  15. }
复制代码
//中断功能函数
5.课后作业:
按下P35四位秒表50s倒计时,最小单位10ms;P54中断,低电平触发,按下SEG1从0-9计数;设置P54优先级高于P35,可以中断秒表计时
  1. void P3EXIT_init(void)
  2. {
  3.         P3IM0 = 0X00;
  4.         P3IM1 = 0XFF;                                        //M1 M0 = 10 低电平中断
  5.         P3INTE = 0X20;                                        //p35中断  0010 0000  
  6. }
  7. //void P3EXIT_init(void) interrupt 31 写在主函数
  8. void P5EXIT_init(void)
  9. {
  10.         P5IM0 = 0X00;
  11.         P5IM1 = 0XFF;                                        //M1 M0 = 10 低电平中断
  12.         IPH = 0;
  13.         IP  = 1;  //优先级设为1,这样就高于P3
  14.         P5INTE = 0X20;                                        //p54中断  0001 0000  
  15. }
复制代码
//初始化中断函数
  1. void main()  //程序开始运行的入口
  2. {
  3.   u8 key_num = 0; //矩阵按键键值
  4.         u8 key_str = 0; //密码输入数量
  5.         sys_init();  //USB功能+IO初始化
  6.         usb_init();  //USB CDC 接口配置
  7.         
  8.         Timer0_Init();
  9.         EA = 1;  //打开总中断
  10.         
  11.         SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =21;  //初始显示--------
  12.         LED = 0xff;  //数码管和LED显示
  13.    
  14.         while(1)      //死循环
  15.         {
  16.                 if(DeviceState != DEVSTATE_CONFIGURED)
  17.                         continue;
  18.                 if(bUsbOutReady)
  19.                 {
  20.                         usb_OUT_done();  //接受应答(固定格式)
  21.                 }
  22.                 if(TIME_10MS == 1)
  23.                 {
  24.                         TIME_10MS = 0;                        if(flag != 1)
  25.                         {
  26.                                 if(Tcount > 0)
  27.                                 {
  28.                                         Tcount--;
  29.                                         SEG4 = 0;  //ms
  30.                                         SEG5 = Tcount/10; //10ms
  31.                                         SEG6 = Tcount/100;  //1s
  32.                                         SEG7 = Tcount/1000;  //10s
  33.                                 }
  34.                         }
  35.                         else
  36.                         {
  37.                                 SEG1 += 1;  //数码管1数字加一
  38.                         }
  39.                 }
  40.                         
  41.         }
  42. }void P3EXIT_isr(void) interrupt 31
  43. {
  44.         u8 intf;
  45.         intf = P3INTF ;  //中断标志寄存器
  46.         if (intf)
  47.         {
  48.                 P3INTF = 0x00;  //清零标志位
  49.                 if(intf & 0x20)
  50.                 {
  51. //                        LED = 0x00;                        //打开所有门锁
  52. //                        SEG0 = 5;                        //数码管持续显示5
  53. //                        Tcount = 500;//5秒倒计时的一个变化
  54.                         Tcount = 5000; //50s
  55.                         SEG4 = 0;  //ms
  56.                         SEG5 = 0; //10ms
  57.                         SEG6 = 0;  //1s
  58.                         SEG7 = 5;  //10s
  59.                         
  60.                 }
  61.         }
  62. }
  63. void P5EXIT_isr(void) interrupt 42
  64. {
  65.         u8 intf;
  66.         intf = P5INTF ;  //中断标志寄存器
  67.         if (intf)
  68.         {
  69.                 P5INTF = 0x00;  //清零标志位
  70.                 if(intf & 0x10)  //P54
  71.                 {
  72.                         flag = 1;
  73.                    SEG1 = 0;  //数码管1循环显示0-9
  74.                 }
  75.         }
  76. }
复制代码
//主函数和中断功能函数
感觉我这个代码还是有很大问题的,没关系等我实验箱到了我就可以根据一一调试了,我实验箱后天就要到了哈哈哈哈哈哈哈哈哈哈

第十七集 ADC采集打卡 2024-05-06

1.ADC:analog to digital converter 模数转换器
2.12位高速A/D转换器:ADC数值占十二位;

3.ADC相关寄存器:ADC控制寄存器(ADC_CONTR)包括ADC电源开关位,ADC转换启动位,ADC转换结束标志位,ADCPWM使能标志位,ADC模拟通道选择位;ADC配置寄存器(ADCCFG);ADC时序控制寄存器(ADCTIM)
4.ADC查询功能初始化
  1. //========================================================================
  2.         // 函数名称: ADC_init()
  3.         // 函数功能: ADC查询初始化
  4.         // 入口参数: 无
  5.         // 函数返回: 无
  6.         // 当前版本: VER1.0
  7.         // 修改日期: 2024-05-06
  8.         // 当前作者:
  9.         // 其他备注:
  10.         //========================================================================
  11.         void ADC_init(void)
  12.         {
  13.                 P1M0 = 0x00;
  14.                 P1M1 = 0x01;   //设置P1.0为ADC口,高阻输入
  15.                 ADCTIM = 0x3F; //设置ADC内部时序
  16.                 ADCCFG = 0x2F; //设置ADC系统时钟为fosc/2/16,右对齐
  17.                 ADC_POWER = 1; //使能ADC模块
  18.         }
  19.         //========================================================================
  20.         // 函数名称: ADC_Read
  21.         // 函数功能: 读取指定通道的adc电压
  22.         // 入口参数: @no:通道0-15
  23.         // 函数返回: 当前的12位adc数值
  24.         // 当前版本: VER1.0
  25.         // 修改日期: 2024-05-07
  26.         // 当前作者:
  27.         // 其他备注:
  28.         //========================================================================
  29.         u16 ADC_Read(u8 no)
  30.         {
  31.                 u16 adcval;     //adc数值保存变量
  32.                 ADC_CONTR &= 0xf0;  //清空通道选择
  33.                 ADC_CONTR |= no;    //选择通道
  34.                 ADC_START = 1;      //开启ADC转化
  35.                 _nop_();       //空操作指令,延时作用
  36.                 _nop_();
  37.                 while(!ADC_FLAG);   //等待ADC转换结束,结束flag会变成1,1取反变成0,0退出循环
  38.                 ADC_FLAG = 0;   //ADC转换结束标志位置0,以便下次转换
  39.                 adcval = (ADC_RES << 8) + ADC_RESL;  //高四位左移八位再与低八位相加得出adc数值
  40.                 adc_val = adcval;  //
  41.                 return adcval;
  42.         }
  43.         //ADC查询相关定义
复制代码
ADC中断功能初始化
  1. #elif ADC_FUNC == ADC_isr
  2.         //========================================================================
  3.         // 函数名称: ADC_init()
  4.         // 函数功能: 中断ADC初始化
  5.         // 入口参数: 无
  6.         // 函数返回: 无
  7.         // 当前版本: VER1.0
  8.         // 修改日期: 2024-05-06
  9.         // 当前作者:
  10.         // 其他备注:
  11.         //========================================================================
  12.         void ADC_init(void)
  13.         {
  14.                 P1M0 = 0x00;
  15.                 P1M1 = 0x01;   //设置P1.0为ADC口,高阻输入
  16.                 ADCTIM = 0x3F; //设置ADC内部时序
  17.                 ADCCFG = 0x2F; //设置ADC系统时钟为fosc/2/16,右对齐
  18.                 ADC_POWER = 1; //使能ADC模块
  19.                
  20.                 EADC = 1;      //打开ADC中断
  21.                 ADC_START = 1; //开启ADC转化
  22.         }
  23.         //========================================================================
  24.         // 函数名称: ADC_isr
  25.         // 函数功能: ADC中断函数
  26.         // 入口参数: 无
  27.         // 函数返回: 无
  28.         // 当前版本: VER1.0
  29.         // 修改日期: 2024-05-09
  30.         // 当前作者:
  31.         // 其他备注:
  32.         //========================================================================
  33.         void ADC_isr() interrupt 5  //ADC中断函数
  34.         {
  35.                 ADC_flag = 0;  //清空读取标志位
  36.                 adc_val  = (ADC_RESL << 8) + ADC_RESL; //读取ADC数值
  37.                 ADC_START = 1; //开启ADC转化
  38.         }
  39.         //ADC中断的相关定义
复制代码
用到if预定义,来选择中断或查询功能。
ADC数值转换成电压值函数:
  1. u16 ADC_CAL_VOLTAGE(u16 num)
  2. {
  3.         return num*2.5*1000 / 4096;  //ADC值*2.5v*0.001V(转成mv)/4096(最大数值)
  4. }
复制代码
5.作业 :前四位显示数值,后四位显示电压,超过2.2V蜂鸣器常响(我改成LED0常亮)
代码
  1. if(TIME_10MS == 1)
  2.                 {
  3.                         TIME_10MS = 0;
  4.                         ADC_Read(0);  //读取ADC0的值,也就是ADC16个按键,0-F分别为256,..,4095,加256一级
  5.                         SEG0 = (int)adc_val/1000;
  6.                         SEG1 = (int)adc_val/100%10;
  7.                         SEG2 = (int)adc_val/10%10;
  8.                         SEG3 = (int)adc_val%10;
  9.                         SEG4 = (int)ADC_CAL_VOLTAGE(adc_val)/1000;
  10.                         SEG5 = (int)ADC_CAL_VOLTAGE(adc_val)/100%10;
  11.                         SEG6 = (int)ADC_CAL_VOLTAGE(adc_val)/10%10;
  12.                         SEG7 = (int)ADC_CAL_VOLTAGE(adc_val)%10;
  13.                         //printf("当前ADC数\xfd值:%d\t%dmv\r\n",(int)adc_val,(int)ADC_CAL_VOLTAGE(adc_val));
  14.                         if((int)ADC_CAL_VOLTAGE(adc_val) > 2200)
  15.                         {
  16.                                 LED0 = 0;
  17.                         }
  18.                         else
  19.                                 LED0 = 1;
  20.                 }
复制代码
效果
截图202405091026139202.jpg

看了两遍终于结束这一课了,

第十八集 ADC应用打卡 2024-05-07~14 拖拖拉拉
1.用ADC15通道反推电源电压:外部通道输入电压=内部参考信号源电压/内部参考信号源ADC测量值*外部通道输入ADC测量值
  1. u16 ADC_VrefCal(void)
  2.         {
  3.                 u8 i;
  4.                 int res;
  5.                 int vcc;
  6.                 BGV = ((VREFH_ADDR << 8) + VREFL_ADDR);  //从CHIPID中读取内部参考电压值
  7.                 ADC_init();    //ADC初始化,ADC15内部参考信号源1.19V,不用设置端口高阻输入,所以可以直接使用初始化函数
  8.                 ADC_Read(15);  //丢弃前几次数据,刚上电读取数值不稳定
  9.                 ADC_Read(15);
  10.                 ADC_Read(15);
  11.                 ADC_Read(15);
  12.                 for(i=0;i<8;i++)  //读取八次数据,保证数据准确
  13.                 {
  14.                         res += ADC_Read(15);  //内部参考信号源ADC数值
  15.                 }
  16.                 res >>=3;  //右移3位,除以8取平均值
  17.                 vcc = (int)(4096L * BGV/res);   //(12位ADC算法)计算VREF管脚电压,即电池电压;4096L是外部通道输入电压ADC测量值
  18.                 return vcc;   //返回电压值
  19.         }
复制代码
2.ADC扫描按键(自动循环):

  1. #define ADC_OFFSET 64  //ADC误差允许
  2. u8 ADC_keyread(u16 adc)
  3. {
  4.         u8 i;
  5.         u16 adc_cmp;   //当前adc数值和每个按键代表adc数值adc_cmp比较
  6.         static u8 key_last = 0;   //按键上一次的状态
  7.         static u16 key_downtime;  //按下时间(长按/短按)
  8.         
  9.         //按钮有无按下,第一个按键按下adc是256
  10.         if(adc < (256 - ADC_OFFSET))   //adc数值小于256-误差允许,没有按键按下,值为0
  11.         {
  12.                 key_downtime = 0;     //没有按键按下,按下时间为0
  13.                 key_last = 0;         //上一次按键状态清零
  14.         }
  15.         adc_cmp = 256;   //有按键按下时,从第一个按键初始值开始比较,依次加256判断是第几个按键
  16.         for(i=1;i<=16;i++)  //循环16次,依次与16个按键比较,键值i从1开始
  17.         {
  18.                 if((adc >= (adc_cmp - ADC_OFFSET)) && (adc <= (adc_cmp + ADC_OFFSET)))  //检测到adc数值跟每个按键数值比较,误差±64
  19.                 {
  20.                         //return i;  //满足本次判断,返回该减值,并退出循环,不执行后面
  21.                         break;
  22.                 }
  23.                 else
  24.                         adc_cmp += 256;  //不满足单次判断,adc_cmp+256,继续比较
  25.         }
  26.         
  27.         if(i>16)  //循环都执行完了,没有键值满足
  28.         {
  29.                 key_downtime = 0;  //即没有按键按下,这个变量清零
  30.                 key_last = 0;      //上一次按键状态清零
  31.         }
  32.         else  //有按键按下,判断按下时间
  33.         {
  34.                 if(key_last == i)  //上一次按键等于这一次按键状态,说明按键是一直按下的
  35.                 {
  36.                         key_downtime ++;  //按下时间加1
  37.                         if(key_downtime == 3)  //主函数每10ms扫描一次,当按下时间等于3时,即30ms
  38.                         {
  39.                                 return i;  //还是返回该键值
  40.                         }
  41.                         else if(key_downtime == 300)  //长按3秒
  42.                         {
  43.                                 key_downtime = 290; //长按3秒后每10ms触发一次长按功能
  44.                                 return i+0x80;
  45.                         }
  46.                         else
  47.                                 return 0;
  48.                 }
  49.                 else
  50.                 {
  51.                         key_downtime = 0;  //刚按下按下时间还未加
  52.                         key_last = i;   //保留按键状态,以便开始按键时间计数
  53.                 }
  54.         }
  55.         return 0; //
复制代码
3.实战小练(简易时钟)+课后作业(闹钟设置):
Demo.uvproj (13.53 KB, 下载次数: 149)

虽然描述很简单,思考的过程很漫长,花了很多的时间去理解老师的代码,又花了很多时间想闹钟设置,一步一步调试代码,再加上自己遇难则退,就拖拖拉拉了一个礼拜了。后面要抓紧了,毕竟还有活要干叻。。


第十九集 NTC温度测温打卡 2024-05-14~05-16

1.NTC原理:Negative Temparature Coefficient,热敏电阻的特性温度越高,电阻的阻值呈指数下降
2.NTC测温程序:单片机的ADC3通道接的NTC电路,通过读取ADC2的adc数值来对照不同等级adc值获取对应温度;
  1. //========================================================================
  2. // 函数名称: temp_cal
  3. // 函数功能: 通过读取的adc数值计算出温度。
  4. // 入口参数: @adc
  5. // 函数返回: 当前的温度值,保留一位小数,-40到150度的温度对应数值-400~1500
  6. // 当前版本: VER1.0
  7. // 修改日期: 2024-05-14
  8. // 当前作者:
  9. // 其他备注: int -32678~32767
  10. //========================================================================
  11. int temp_cal(u16 adc)
  12. {
  13.         u8 i;  //循环比较变量
  14.         float temp;  //温度中间变量
  15.         
  16.         if(adc > adc_table[0])  //比-40温度对应adc值还要大,超出范围
  17.                 return -32678;    //超出返回值
  18.         else if (adc < adc_table[190])   //比150度对应adc值还要小,超出范围
  19.                 return 32767;    //超出返回值
  20.         else  //adc值在NTC范围内
  21.         {
  22.                 for(i=0;i<190;i++)   //遍历ADC值对应温度表,从-40度开始比较
  23.           {
  24.                         if(adc == adc_table[i])  //正好等于该等级adc数值
  25.                         {
  26.                                 return (i-40)*10; //序号减去40,加一位小数乘以10
  27.                         }
  28.                         else if(adc<adc_table[i])  //小于,不处理
  29.                         {
  30.                                 
  31.                         }
  32.                         else   //大于adc_table[i],adc_table[i-1]的值加上算出小数点值
  33.                         {
  34.                                 i = i - 1; //
  35.                                 temp = adc_table[i] - adc; //adc-标准值的余量即为小数部分adc值
  36.                                 temp = temp*10/(adc_table[i] - adc_table[i+1]);  //adc转温度值
  37.                                 temp += (i-40)*10; //小数部分加上整数部分
  38.                                 return temp;
  39.                         }
  40.                 }
  41.         }
  42. }
复制代码
3.实战小练加课后作业:简易温度计,数码管显示温度保留小数点后一位,开关机按键,按一下取反;测量按键,按下读取温度20次后取平均值显示,测量完成LED亮3s;30s不操作自动关机;
Demo.uvproj (13.71 KB, 下载次数: 137)

温度读取老师教的没有花多少时间;功能处理花了很多时间,感觉自己逻辑很差,每次第一次从头顺下来的逻辑都是错的,基本上要从头到尾全部改一遍;再加上粗心导致的问题,有时候系统不会报错就会花很多时间才能发现问题,可能就是变量的名字取得很相似,搞混了,还有一些时间计数变量,太多了导致弄混了,都要花很多时间找出来。

第二十-二十一集 串口通信打卡 2024-05-16~05-18

1.通信:串口通信(每次发送一位数据),并行通信(多位数据一起发)
2.串口通信:外设和计算机之间通过数据信号线、地线、控制线等,按位传输数据;传输双方波特率、校验位、停止位、数据位都要一致;
3.STC32串口通信:全双工(可以同时收发),异步通信()
4.串口通信代码实现:
  1. #define BRT   (65536-(MAIN_FOSC/115200+2)/4)   //加2操作是为了让keil编译器自动实现四舍五入运算
  2. bit busy;   //忙碌标志位
  3. char wptr;  //发送计数
  4. char rptr;  //接收计数
  5. char buffer[16];  //接收缓冲
  6. void usart2_init(void)
  7. {
  8.         P_SW2 = 0x80;   //串口2功能脚切换寄存器
  9.         P_SW2 |= 0x01;  //将串口2的引脚切换到P46 P47,且不改变第一步的设置
  10.         
  11.         S2CFG = 0x01;   //串口2配置寄存器   要用串口2必须设置该寄存器最后一位W1为1,不用可不特别设置
  12.         S2CON = 0x50;   //串口2控制寄存器   选择模式2工作方式,固定波特率9位数据方式
  13.         T2L   = BRT;    //
  14.         T2H   = BRT >> 8;
  15.         T2x12 = 1;
  16.         T2R   = 1;
  17.         wptr  = 0x00;
  18.         rptr  = 0x00;
  19.         busy  = 0;
  20. }
  21. void usart2_isr() interrupt 8
  22. {
  23.         if(S2TI)
  24.         {
  25.                 S2TI = 0;
  26.                 busy = 0;
  27.         }
  28.         if(S2RI)
  29.         {
  30.                 S2RI = 0;
  31.                 buffer[wptr++] = S2BUF;
  32.                 wptr &= 0x0f;
  33.         }
  34. }
  35. void usart2_send(char dat)
  36. {
  37.         while(busy);
  38.         busy = 1;
  39.         S2BUF = dat;
  40. }
  41. void usart2_sendstr(char *p)
  42. {
  43.         while(*p)  //到停止位结束
  44.         {
  45.                 usart2_send(*p++);
  46.         }
  47. }
复制代码
主程序
  1. usart2_sendstr("Uart Test!\r\n");
复制代码
5.串口通信应用:copy实例里的串口设置函数。二十集的作业独立思考完成不了。。
  1. /*
  2. 项目名称:简易串口控制器。
  3. 1.串口发送字符        Ax\r\n,(x表示0-7)板子点亮对应LED
  4. 2.串口发送                Bxxxx\r\n,xxxx表示一个四位数,四位数码管显示这个4位数
  5. 2.串口发送                Z\r\n,板子给电脑发送“Hello STC”;
  6. 3.串口发送字符        Cx\r\n,(x表示0-1)板子打开/关闭蜂鸣
  7. 4.串口发送字符        D\r\n,板子通过串口发送当前温度给电脑。
  8. */temp = temp_cal(ADC_Read(3));
  9.                 if(Rec_Flag == 1)
  10.                 {
  11.                         switch(RX2_Buffer[0])
  12.                         {
  13.                                 case 'A':
  14.                                         if((RX2_Buffer[1] >= 48) && (RX2_Buffer[1] <= 55))  //0-9的ASCII码
  15.                                         {
  16.                                                 LED = ~(1<<(RX2_Buffer[1]-48));
  17.                                         }
  18.                                         break;
  19.                                 case 'B':
  20.                                         SEG0= RX2_Buffer[1]-48;SEG1= RX2_Buffer[2]-48;SEG2= RX2_Buffer[3]-48;SEG3= RX2_Buffer[4]-48;
  21.                                         break;
  22.                                 case 'C':
  23.                                         if(RX2_Buffer[1] == 48)
  24.                                                 BEEP = 0;
  25.                                         else
  26.                                                 BEEP = 1;
  27.                                         break;
  28.                                 case 'D':
  29.                                         sprintf(str,"当前温度:%d\r\n",temp);                                  PrintString2(str);
  30.                                         break;
  31.                                 case 'Z':
  32.                                         PrintString2("Hello STC!");
  33.                                         break;
  34.                                 default:
  35.                                         break;
  36.                         }
  37.                         Rec_Flag = 0;
  38.                 }
复制代码
6.课后作业:串口控制PC(ADC按键配合)
按下按钮0-7,发送“Ax\r\n”,x:0-7;
按下8,发送“B0000\r\n”;
按下9,发送“Z\r\n”;
按下A,发送“C0\r\n”;按下B,发送“C1\r\n”;
按下C,发送“Dx\r\n”;
  1. keynum = ADC_keyread(ADC_Read(0));
  2.                 switch(keynum)
  3.                 {
  4.                         case 1:
  5.                         case 2:
  6.                         case 3:
  7.                         case 4:
  8.                         case 5:
  9.                         case 6:
  10.                         case 7:
  11.                         case 8:
  12.                                 sprintf(str,"A%d\r\n",keynum-1);
  13.                                 PrintString2(str);
  14.                           break;
  15.                         case 9:
  16.                                 PrintString2("B0000\r\n");
  17.                           break;
  18.                         case 10:
  19.                                 PrintString2("Z\r\n");
  20.                           break;
  21.                         case 11:
  22.                                 PrintString2("C0\r\n");
  23.                     break;
  24.                         case 12:
  25.                                 PrintString2("C1\r\n");
  26.                                 break;
  27.                         case 13:
  28.                                 PrintString2("Dx\r\n");
  29.                           break;
  30.                         default:
  31.                                 break;
  32.                 }
复制代码
终于终于学到串口通信,就是因为学习研发卡死在串口通信第一步,才开始重头学单片机哈哈,希望这次不要忘得太快


第二十二集 CDC串口通信打卡 2024-05-20

CDC串口通信和传统串口通信区别:
可以不断电下载;
串口通信波特率随便选也不会出错;
传统打印字符要通过sprintf转化变量为字符,CDC可以直接使用printf;
使用简单可能是可以直接用例程里的代码;
只需要一根线,usb线又供电又通信。
  1. void main()  //程序开始运行的入口
  2. {
  3.         int temp;     //温度
  4.         sys_init();  //USB功能+IO初始化
  5.         usb_init();  //USB CDC 接口配置
  6.         EUSB = 1;
  7.         
  8.         Timer0_Init();
  9.         ADC_init();
  10.         P1M0 = 0x00; P1M1 = 0x08;
  11.         EA = 1;  //打开总中断
  12.         while(DeviceState != DEVSTATE_CONFIGURED);
  13.    
  14.         while(1)      //死循环
  15.         {
  16.                 delay_ms(2);
  17.                 temp = temp_cal(ADC_Read(3));
  18.                 if(bUsbOutReady)
  19.                 {
  20.                         usb_OUT_done();  //接受应答(固定格式)
  21.                         switch(UsbOutBuffer[0])
  22.                         {
  23.                                 case 'A':
  24.                                         if((UsbOutBuffer[1] >= 48) && (UsbOutBuffer[1] <= 55))  //0-9的ASCII码
  25.                                         {
  26.                                                 LED = ~(1<<(UsbOutBuffer[1]-48));
  27.                                         }
  28.                                         break;
  29.                                 case 'B':
  30.                                         SEG0= UsbOutBuffer[1]-48;SEG1= UsbOutBuffer[2]-48;SEG2= UsbOutBuffer[3]-48;SEG3= UsbOutBuffer[4]-48;
  31.                                         break;
  32.                                 case 'C':
  33.                                         if(UsbOutBuffer[1] == 48)
  34.                                                 BEEP = 0;
  35.                                         else
  36.                                                 BEEP = 1;
  37.                                         break;
  38.                                 case 'D':
  39.                                         printf("当前温度:%d\r\n",temp);
  40.                                         break;
  41.                                 case 'Z':
  42.                                         printf("Hello STC!");
  43.                                         break;
  44.                                 default:
  45.                                         break;
  46.                         }
  47.                         Rec_Flag = 0;
  48.                         //USB_SendData(UsbOutBuffer,OutNumber);
  49.                         usb_OUT_done();
  50.                 }
  51.                 if(TIME_10MS == 1)
  52.                 {
  53.                         TIME_10MS = 0;
  54.                 }
  55.         }
  56. }
复制代码
之前也是一直在使用CDC,不过还是云里雾里的,多应用试试看吧。


第二十三集 看门狗打卡 2024-05-20

1.系统复位方式:上电复位;低压复位;复位脚复位(低电平);看门狗复位。
2.看门狗:是一个计数器,其基本功能是在软件问题和程序跑偏后重启系统,看门狗正常工作时会自动计数,程序进程会定时将其归零。如系统在某个地方卡住或者跑了,定时器就会溢出,系统强制复位。使用有看门狗的芯片时要注意清理看门狗。看门口是独立的计数器,普通的计数器不可代替。
3.看门狗控制寄存器WDT_CONTR:WDT_FLAG溢出标志;EN_WDT使能标志;CLR_WDT定时器清零(喂狗);IDL_WDT,空闲时是否计数;WDT_PS[2:0]时钟分频系数;
4.实现代码:
  1. void WDT_init(void)  //初始化WDT设置
  2. {
  3.         WDT_CONTR = 0x24;  //EN_WDT = 1;使能看门狗,WDT_PS[2:0]=100,分频系数32
  4. }
  5. void WDT_feed(void)  //看门狗喂狗
  6. {
  7.         WDT_CONTR = 0x34;  //EN_WDT=1,使能看门狗;CLR_WDT=1,看门狗定时器清零;WDT_PS[2:0]=100,分频系数32
  8. }
复制代码
  1. void main()  //程序开始运行的入口
  2. {
复制代码
注意:等待喂狗的时间要大于代码需要执行的时间,留有余量;

第二十四集 比较器打卡 2024-05-21

1.作用:通过比较两端的电压大小,来及时响应某些动作;
2.原理:比较运放的正端电压和负端电压;若V+>V-,输出1,反之为0;
3.比较器初始化函数:
  1. void CMP_init(void)  //初始化CMP设置
  2. {
  3.         CMPEXCFG = 0x00;
  4.         CMPEXCFG |= 0xc0;                           //比较器DC迟滞输入选择,0:0mV; 0x40:10mV; 0x80:20mV; 0xc0:30mV(一般选最大)
  5. //  CMPEXCFG &= ~0x04;                          //P3.6为CMP-输入脚
  6.         CMPEXCFG |= 0x04;                           //内部1.19V参考电压为CMP-输入脚
  7.         CMPEXCFG &= ~0x03;                          //P3.7为CMP+输入脚
  8. //  CMPEXCFG |= 0x01;                           //P5.0为CMP+输入脚
  9. //  CMPEXCFG |= 0x02;                           //P5.1为CMP+输入脚
  10.         CMPEXCFG |= 0x03;                           //ADC输入脚为CMP+输入脚
  11.         CMPCR2 = 0x00;
  12.         INVCMPO = 0;                                //比较器正向输出
  13. //  INVCMPO = 1;                                //比较器反向输出
  14.         DISFLT = 0;                                 //使能0.1us滤波
  15. //  DISFLT = 1;                                 //禁止0.1us滤波
  16. //  CMPCR2 &= ~0x3f;                            //比较器结果直接输出
  17.         CMPCR2 |= 0x10;                             //比较器结果经过16个去抖时钟后输出
  18.         CMPCR1 = 0x00;
  19. //  PIE = 0;                                    //禁止比较器上升沿中断
  20.         PIE = 1;                                    //使能比较器上升沿中断
  21. //  NIE = 0;                                    //禁止比较器下降沿中断
  22.         NIE = 1;                                    //使能比较器下降沿中断
  23. //  CMPOE = 0;                                  //禁止比较器输出
  24.         CMPOE = 1;                                  //使能比较器输出
  25.         CMPO_S = 0;                                 //选择P3.4作为比较器输出脚
  26. //  CMPO_S = 1;                                 //选择P4.1作为比较器输出脚
  27.         CMPEN = 1;                                  //使能比较器模块
  28. }
复制代码
4.作业:用ADC按键和比较器的方式控制数码管显示当前比较结果,电压大于1.19V显示“On”,否则显示“OFF”;
  1. bit temp = 0;while(1)      //死循环
  2.         {
  3.                 delay_ms(2);
  4.                 if(bUsbOutReady)
  5.                 {
  6.                         //USB_SendData(UsbOutBuffer,OutNumber);
  7.                         usb_OUT_done();
  8.                 }
  9.                 if(TIME_10MS == 1)
  10.                 {
  11.                         TIME_10MS = 0;
  12.                         //ADC_Read(0);
  13.                         if(temp)
  14.                         {
  15.                                 SEG0 = 0;     //O
  16.                                 SEG1 = 22;  //
  17.                                 SEG2 = 20;  //n
  18.                         }
  19.                         else
  20.                         {
  21.                                 SEG0 = 0;     //O
  22.                                 SEG1 = 23;  //F
  23.                                 SEG2 = 23;  //F
  24.                         }
  25.                 }void CMP_isr() interrupt 21
  26. {
  27.         CMPIF = 0;    //清除中断标志
  28.         if(CMPRES)         //为1,正端电压大于负端电压
  29.         {
  30.                                                                   
  31.         }
  32.         else               //为0,正端电压小于负端电压
  33.         {
  34.                
  35.         }
  36.         temp = CMPRES;     //中断方式读取比较器比较结果
  37. }
复制代码
注意变量定义的位置;


第二十五集 flash模拟EEprom ,跌在坑底躺平了 不知道为什么就是没看懂 , 先接着学之后再回过头来,总要继续的吧,不然就一点事也没得做 ,还是入门级

第二十六集 DS18B20温度传感器打卡  2024-05-28~05-30

1.DS18B20简介:数字温度传感器,输出数字信号;单线发送温度信息,三个引脚,正极和负极和DQ脚
2.DS18B20代码过程:


好好学习天天向上
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-06 17:17:05
已绑定手机

90

主题

962

回帖

2326

积分

超级版主

积分
2326
QQ
发表于 2024-4-17 13:25:39 | 显示全部楼层
咋了,前面发的贴 看不到了吗
热线19952583534
www.STCAI.com
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-17 13:38:23 | 显示全部楼层
国学*** 发表于 2024-4-17 13:25
咋了,前面发的贴 看不到了吗

没有啊 只是之前是回复在视频教学帖子下面,工作人员建议我开个新帖记录打卡
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-18 17:00:46 | 显示全部楼层
这图片排列这么混乱的吗
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-25 15:21:37 | 显示全部楼层
怎么又突然冒出bug
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-28 15:47:11 | 显示全部楼层
原来是因为我没有选择那个图片他就跑到最末尾去了
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-4-29 11:49:18 | 显示全部楼层
哟西粘代码比粘截图好多了,又学到了
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:508
  • 最近打卡:2025-05-07 07:34:14
已绑定手机

1

主题

836

回帖

1521

积分

金牌会员

积分
1521
发表于 2024-4-29 13:38:23 | 显示全部楼层
靡不有初,鲜克有终
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:241
  • 最近打卡:2025-05-07 07:54:59
已绑定手机

1

主题

16

回帖

310

积分

中级会员

积分
310
发表于 2024-4-29 15:50:19 | 显示全部楼层
好学*** 发表于 2024-4-17 13:38
没有啊 只是之前是回复在视频教学帖子下面,工作人员建议我开个新帖记录打卡 ...

我也是搞错了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-5-27 09:45:26 | 显示全部楼层
eeprom真的没搞懂,改写CDC也没搞清楚,又要跌在坑里躺下了
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-8 02:11 , Processed in 0.194092 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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