本帖最后由 好学天上 于 2024-4-30 17:19 编辑
实验箱教学视频打卡
第一至三集 评论区打卡
第四集 点灯打卡 2024-04-18
LED点亮原理:两边电压差
GPIO:软件可以读取引脚输入电平或控制引脚输入电平(总算搞明白)
基本的书写规则
查找:ctrl+f
不掉电下载:根据视频加了lib文件和库文件,不知道为啥还是报错,也找了范例程序还是没找出原因。
作业点亮所以LED灯,按照之前学的,可以一个一个点亮P60 =0; P61=0....也可以P6=0x00即0000 0000八个口全置0点亮。
工程基本流程已掌握。
希望有老师可以解决一下我的问题
(os:讲课的老师手真好看嘻嘻)
已解决,没设置memory model,这也是和51不一样的地方;
第五集 C语言运算符打卡 2024-04-19
这节课的内容都比较基础,是在学校学C语言和单片机的时候都讲过
还有一个printf函数的使用,进制转换那些我们以前考试经常考的基础题,以及与或非之类的逻辑运算。还有变量类型以及它的大小。没有特别大的难度
第六集 流水灯打卡 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用法,相当于把需要定义的内容换一个名字 。
哎哟 我已经掌握了图片排列的奥秘!
函数使用三步: 定义→声明→调用
课后练习:SOS灯光
没有一行一行写,但感觉应该有更简便的方法。
第七集 按键 打卡 2024-04-22
1.按键的原理:两个引脚间的通断:按下之后导通(常开);按下之后断开(常闭);
2.注意:机械开关断开闭合时都会有抖动,所以要靠变成消抖,判断按键状态后等待10ms后再次判断开关状态,此为消抖
3.按键应用:按下点亮松开熄灭;按下熄灭松开点亮;按一下取反;按一下led灯左移一位
4.数组的应用:定义→赋值,索引是长度减1,因为是从0开始。
5.课后作业:按下一次,LED右移一位
第八集 蜂鸣器 打卡 2024-04-23
1.蜂鸣器:无源蜂鸣器和有源蜂鸣器,区别是有源蜂鸣器内部有震荡,通电即可打开,而无源直流信号无法令其运行;
2.控制原理:和LED相同
3.电磁炉实战:按键配合LED和蜂鸣器,其实是把前几节课都结合起来了。
ps:老师好像没有在写第二个功能模式按键的时候做开机判断,这样即使在关机模式也可以功能切换吧。
4.课后作业:第三个启动按键,按下对应功能模式闪烁,且功能切换不可用
第九-十集数码管打卡 2024-04-24
1.数码管:多个发光二极管组成
2.控制原理:和LED类似,共阳给0亮,共阴给1亮
3.按键循环0-9:
4.静态显示作业:H 0x89;J 0xF0;L 0xC7;n 0xAD;o 0xA3;P 0x8C;U 0xC1;t 0x87;r 0x8F
按键1自加循环0-9,按键2控制蜂鸣器鸣叫对应数字次数
5.数码管动态显示原理:每一位数码管轮流点亮,但间隔时间只有1ms,是因为人无法分辨50Hz以上的刷新频率二产生视觉残留,看起来好像是一起亮的。
6.10秒免单计数器
7.注意事项:写代码过程中会有很多不注意的小细节,简单的书写错误,格式错误都会在最后要调试很多次,还是写得太少。
8.课后作业:简易时钟 00.00.00,三十秒时闹钟响,蜂鸣器鸣叫3s;
本来想的是把闹钟设置直接放函数中判断,打开之后延时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.作业:用定时器驱动时钟并设置启动暂停按键
主函数
定时器函数;
5.计数器:计数器用途有电机测速等,输出信号带高低电平变化都可以用计数器;
6.计数器的配置:
按键P35每按下一次,led灯P60状态取反一次;
7.例程:电机测速模拟,用按键模拟脉冲
8.作业:2s周期改为每分钟:
9.思考:如果计数器溢出了程序要怎么写? 答:说实话这节课还有点云里雾里。
第十三集 TIM多任务处理打卡 2024-04-26
1.创建程序文件三步;程序定义三步,函数定义三步;这里前面的课程都有提到过。
2.extern:在a文件里要使用b文件的变量时,用extern在b的库文件中定义该变量,再在a.c中包含b的库文件;
3.bdata位寻址变量定义,例如定义一个八位变量使用bdata,可以分别定义八位的每一位,单独赋值。
4.static静态变量,静态变量时的赋值只一次有效;
5.数码管LED的程序文件:
2024-04-28接上文
6.按键的函数文件,不使用while循环,改用状态机的模式,在主函数中定时使用循环读取每个按键状态的函数,再在使用到某个按键时,使用另一个函数直接读取该按键的状态,返回定义好的状态返回值,有未按下,抖动,按下,按下结束,长按,长按结束这些状态,再在主函数当中通过判断该按键状态来书写功能函数:
key.h
key.c
主函数中功能实现
7.蜂鸣器的函数文件,通过设置蜂鸣器鸣叫时间的函数来决定蜂鸣器要不要叫,要叫多久,再在主函数中10ms循环运行蜂鸣器运行函数,当设置的时间等于0,蜂鸣器不鸣叫,大于0,则鸣叫该时间后关闭。
beep.h
beep.c
beep在主函数中调用使用。
8.定时器函数文件,只需要将之前在主函数写的定时器初始化移到定时器c文件中,在主函数里调用函数使用;而中断函数最好仍在主函数中书写,因其需要调用不同的功能函数,所以放在主函数更佳。
9.课后作业:
LED0每200ms取反一次;LED1每400ms取反一次;LED2每800ms取反一次
感觉这个方法不是那么聪明的样子;
改写电磁炉程序:
10.体会:主要是将程序都结构化,让看代码的人也能清晰易懂,修改优化程序时更方便。
第十四集 矩阵按键打卡 2024-04-29
1.矩阵按键:每行由一个IO口控制,每列由一个IO口控制,不同于独立按键的一对一IO口,可以大大节省硬件资源;
2.控制原理:通过扫描行和列,判断按键按下位置,类似二维坐标;先将行IO都置低电平,列置高电平,确定哪一列;再将行置高电平,列置低电平,确定哪一行;通过二者确定按键位置;
3.实践程序:电子门锁----矩阵按键输入八位密码,密码正确门开则LED亮,密码错误蜂鸣器鸣叫2s后关闭;每次按键输入蜂鸣器鸣叫20ms。
+课后作业:门锁打开5s后自动关闭,切回锁定状态,设置门内手动开门按钮,使用独立按键,可以一键直接开门;10s内无操作数码管熄灭,有操作即点亮。
复制代码
第十五集 外部中断打卡 2024-04-29
1.中断系统:CPU处理紧急事件的功能部件。优点:a.总是响应优先级最高的中断请求;b.每个中断源都可以独立控制开关;c.低优先级中断处理中可以被高优先级中断打断;d.部分中断源优先级可以通过软件改变。
2.外部中断:单片机的一个引脚上由于外部因素造成的电平变化(如按键按下),引起的中断就是外部中断.单片机原理图标了INTx的就是外部中断口.
3.外部中断使用:
- void INT0_init(void) //外部中断初始化函数
- {
- IT0 = 1; //1为下降沿有效,0为上升沿下降沿均可触发
- EX0 = 1; //中断允许
- IE0 = 0; //清楚中断标志
- }
复制代码
//外部中断0初始化
//中断功能函数
弄清中断使用的寄存器的每个标志位的高低电平分别是什么功能.
4.课后作业:写外部中断1和中断2-4的函数
- void INT1_init(void) //外部中断1
- {
- IT1 = 1; //1为下降沿有效,0为上升沿下降沿均可触发
- EX1 = 1; //中断允许
- IE1 = 0; //清楚中断标志
- }
-
- void INT1_isr(void) interrupt 2
- {
- //功能
- }
-
-
- void INT2_init(void) //外部中断2
- {
- //只能下降沿触发
- EX2 = 1; //中断允许
- }
-
- void INT2_isr(void) interrupt 10
- {
- //功能
- }
-
- void INT3_init(void) //外部中断3
- {
- //只能下降沿触发
- EX3 = 1; //中断允许
- }
-
- void INT3_isr(void) interrupt 11
- {
- //功能
- }
-
- void INT4_init(void) //外部中断4
- {
- //只能下降沿触发
- EX4 = 1; //中断允许
- }
-
- void INT4_isr(void) interrupt 16
- {
- //功能
- }
复制代码
思考:什么时候用外部中断?
之前学的定时器中断使用在周期性中断,一定时间才会处理一次事件,而外部中断,只要有外部触发就可以产生中断,优先处理,且执行完以后会自己继续执行主程序。可以用外部中断来写之前按键的功能函数。
第十六集 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是最高的;
- void P3EXIT_init(void)
- {
- P3IM0 = 0X00;
- P3IM1 = 0XFF; //M1 M0 = 10 低电平中断
- P3INTE = 0X20; //p35中断 0010 0000
- }
复制代码
//IO中断初始化程序
4.实践:八个按键对应八个LED灯,按键按下灯亮门开,灯灭门锁;一个独立按键模拟应急按钮,按下门全开,且不能用按键解锁,再次按下应急按钮则五秒后解锁:
- void main() //程序开始运行的入口
- {
- u8 key_num = 0; //矩阵按键键值
- u8 key_str = 0; //密码输入数量
- bit flag = 0; //门锁是否开启标志
- sys_init(); //USB功能+IO初始化
- usb_init(); //USB CDC 接口配置
-
- Timer0_Init();
- EA = 1; //打开总中断
-
- SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =22; //初始显示--------
- LED = 0xff; //数码管和LED显示
-
- while(1) //死循环
- {
- if(DeviceState != DEVSTATE_CONFIGURED)
- continue;
- if(bUsbOutReady)
- {
- usb_OUT_done(); //接受应答(固定格式)
- }
- if(TIME_10MS == 1)
- {
- TIME_10MS = 0;
- if( Tcount ==0 ) //如果没有按下过应急按钮
- {
- key_num = MatrixKEY_Read(); //当前矩阵按键的键值 1-8
- BEEP_RUN(); //蜂鸣运行
- if( key_num > 0 ) //如果有按键拿下
- {
- BEEP_ON(2);
- flag ^= (1<<(key_num-1)); //获取当前是第几个按钮按下,{1-8}-》
- }
- LED = flag; //初始状态熄灭所有LED
- SEG0 = 21; //熄灭数码管
- }
- else //按下了应急按钮
- {
- Tcount--;
- SEG0 = (Tcount/100+1); //500/100 499
- }
- }
-
- }
- }
复制代码
//主程序
- void P3EXIT_isr(void) interrupt 40
- {
- u8 intf;
- intf = P3INTF ; //中断标志寄存器
- if (intf)
- {
- P3INTF = 0x00; //清零标志位
- if(intf & 0x20)
- {
- LED = 0x00; //打开所有门锁
- SEG0 = 5; //数码管持续显示5
- Tcount = 500;//5秒倒计时的一个变化
- }
- }
- }
复制代码
//中断功能函数
5.课后作业:
按下P35四位秒表50s倒计时,最小单位10ms;P54中断,低电平触发,按下SEG1从0-9计数;设置P54优先级高于P35,可以中断秒表计时
- void P3EXIT_init(void)
- {
- P3IM0 = 0X00;
- P3IM1 = 0XFF; //M1 M0 = 10 低电平中断
- P3INTE = 0X20; //p35中断 0010 0000
- }
-
- //void P3EXIT_init(void) interrupt 31 写在主函数
-
- void P5EXIT_init(void)
- {
- P5IM0 = 0X00;
- P5IM1 = 0XFF; //M1 M0 = 10 低电平中断
- IPH = 0;
- IP = 1; //优先级设为1,这样就高于P3
- P5INTE = 0X20; //p54中断 0001 0000
- }
复制代码
//初始化中断函数
- void main() //程序开始运行的入口
- {
- u8 key_num = 0; //矩阵按键键值
- u8 key_str = 0; //密码输入数量
-
- sys_init(); //USB功能+IO初始化
- usb_init(); //USB CDC 接口配置
-
- Timer0_Init();
- EA = 1; //打开总中断
-
- SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 =21; //初始显示--------
- LED = 0xff; //数码管和LED显示
-
- while(1) //死循环
- {
- if(DeviceState != DEVSTATE_CONFIGURED)
- continue;
- if(bUsbOutReady)
- {
- usb_OUT_done(); //接受应答(固定格式)
- }
- if(TIME_10MS == 1)
- {
- TIME_10MS = 0; if(flag != 1)
- {
- if(Tcount > 0)
- {
- Tcount--;
- SEG4 = 0; //ms
- SEG5 = Tcount/10; //10ms
- SEG6 = Tcount/100; //1s
- SEG7 = Tcount/1000; //10s
- }
- }
- else
- {
- SEG1 += 1; //数码管1数字加一
- }
- }
-
- }
- }void P3EXIT_isr(void) interrupt 31
- {
- u8 intf;
- intf = P3INTF ; //中断标志寄存器
- if (intf)
- {
- P3INTF = 0x00; //清零标志位
- if(intf & 0x20)
- {
- // LED = 0x00; //打开所有门锁
- // SEG0 = 5; //数码管持续显示5
- // Tcount = 500;//5秒倒计时的一个变化
- Tcount = 5000; //50s
- SEG4 = 0; //ms
- SEG5 = 0; //10ms
- SEG6 = 0; //1s
- SEG7 = 5; //10s
-
- }
- }
- }
-
- void P5EXIT_isr(void) interrupt 42
- {
- u8 intf;
- intf = P5INTF ; //中断标志寄存器
- if (intf)
- {
- P5INTF = 0x00; //清零标志位
- if(intf & 0x10) //P54
- {
- flag = 1;
- SEG1 = 0; //数码管1循环显示0-9
- }
- }
- }
复制代码
//主函数和中断功能函数
感觉我这个代码还是有很大问题的,没关系等我实验箱到了我就可以根据一一调试了,我实验箱后天就要到了哈哈哈哈哈哈哈哈哈哈
|