库函数调用:BYTE cod;//定义一个数组
cod = 0x3f;
cod = 0x06;
cod = 0x5b;
cod = 0x4f;
cod = 0x66;
cod = 0x6d;
cod = 0x7d;
cod = 0x27;
SEG7_ShowCode(cod);//调用发送函数
3. 虚拟键盘。虚拟一个多功能键盘,向单片机发送指令和数据,接收处理并回传到USB调试接口,用虚拟的8位数码管显示出来。一切都是虚拟,所以需要将这个函数规定的键值按照规律翻译,才能正确显示出来,视频教学里面采用“-48”,巧妙的同步的一致的显示在虚拟的数码管上。冲哥非常厉害! 虚拟键盘直接以串行的方式发送出来,需要在“UsbOutBuffer”提取。if (bUsbOutReady) //如果接收到了数据
{
REC_NUM = UsbOutBuffer; //验证“UsbOutBuffer”只有PC发送了数据才会更新,无新数据不会变。
//放在了缓存里。
//USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done(); //
}
4. 课后练习:8位密码锁-1.没有输入时,显示“- - - - - - - -”-2.有输入时,按下一个按键,开始按顺序写入 例如,第一个按下1,显示“1 - - - - - - -” 例如,第二个按下3,显示“1 3 - - - - - -”-3.当按下的密码为“ 1 2 3 4 5 6 7 8”时,数码管显示open的字符,否则,还是显示“- - - - - - - -” /* 课后任务8位密码锁 -1.没有输入时,显示“- - - - - -- -” -2.有输入时,按下一个按键,开始按顺序写入 例如,第一个按下1,显示“1 - - - - - - -” 例如,第二个按下3,显示“1 3 - - - - - -” -3.当按下的密码为“ 1 2 3 4 5 67 8”时,数码管显示open的字符,否则,还是显示“- -- - - - - -”*/下面是实现该功能的部分程序,数码管段码数组用软件生成,放在SEG_NUM数组里。模拟当中出现的问题是,第8位显示不出来,直接跳转到“open”。里面还需要加延时语句。暂时不加。还有就是开机显示“--------”部分,模拟的时候来不及显示,只有按出错了就显示了。哈哈,这单片机运行速度太快了!PC反应不过来。u8 Step =0;u8REC_NUM = 0xff;u8 stop =0;voidTASK_5( void )//任务五{ u8 i ; u8 cod; //新的函数(数组)里面需包含关键字“cod” if(stop == 0) //开机显示“--------”,只运行一次。如果要一直显示可以直接取消stop标志判断。持续发送。 { for(i=0;i<8;i++) { cod = SEG_NUM; } SEG7_ShowCode(cod); // stop = 1; } if(REC_NUM != 0xff) //有新数据 { switch(Step) { case 0:cod=SEG_NUM;break; //装入第1位的段码 case 1:cod=SEG_NUM;break; //装入第2位的段码 case 2:cod=SEG_NUM;break; //装入第3位的段码 case 3:cod=SEG_NUM;break; //装入第4位的段码 case 4:cod=SEG_NUM;break; //装入第5位的段码 case 5:cod=SEG_NUM;break; //装入第6位的段码 case 6:cod=SEG_NUM;break; //装入第7位的段码 case 7:cod=SEG_NUM;break; //装入第8位的段码 default:break; } REC_NUM = 0xff;//清空缓存 SEG7_ShowCode(cod); Step++; if(Step ==8) { if((cod==SEG_NUM)&&(cod==SEG_NUM)&&(cod==SEG_NUM)&&(cod==SEG_NUM)&& (cod==SEG_NUM)&&(cod==SEG_NUM)&&(cod==SEG_NUM)&&(cod==SEG_NUM)) { cod = SEG_NUM; //第1位显示的段码 cod = SEG_NUM; //第2位显示的段码 cod = SEG_NUM; //第3位显示的段码 cod = SEG_NUM; //第4位显示的段码 cod = SEG_NUM; //第5位显示的段码 cod = SEG_NUM; //第6位显示的段码 cod = SEG_NUM; //第7位显示的段码 cod = SEG_NUM; //第8位显示的段码 } else//输入错误 { for(i=0;i<8;i++) { cod =SEG_NUM; } Step = 0; } } SEG7_ShowCode(cod); //函数里必须包含调用的发送函数 }}
今天是2025年的1月1号。记录我的学习历程。跟着冲哥学,学到了好多知识!感谢冲哥!感谢国芯!2025,新的一年,祝愿大家新年快乐!收获满满!
dongge 发表于 2025-1-1 13:57
优秀课代表
夸奖了,就学习的时候认真了点,分享+记录!一起加油哦! 第十一集 矩阵按键 的学习记录1. 矩阵按键的原理:(IO口设置为准双向口,2行4列用6个IO可得到8个按键,4行4列可得到16个按键)a. 首先让列都输出低电平,如4列;让行输出高电平,如2行b. 判断行是否有低电平出现,若有表示有按键按下。c. 让每行赋值低电平,每列赋值高电平(翻转)。再检测那列出现低电平,就可以判断是这个低电平对应列的按键按下了。2. 矩阵按键的程序实现:由矩阵按键得到键值,同时依然需要按键消抖处理后,才用于程序实施!保证触发精确。3. 用按键密码锁任务验证矩阵按键,这次是用了试验箱上面的数码管,就需要略作修改,调用的595驱动函数,就实现了。4. 课后任务:简易洗衣机面板a按下开机键后,数码管显示1,表示默认为清洗模式1;b用矩阵按键模拟洗衣机的操作面板,前五个按键模拟1-5的清洗模式按键,选择几的时候数码管显示数字几,表示以当前为第几个功能;c按下启动后,按照选择的模式对应的时间开始倒计时,倒计时结束后,数码管熄灭,表示清洗完成。 d.下面是逻辑处理和显示部分,按键扫描和任务调度依然采用冲哥的多任务处理框架。显示部分非常耗费存储空间,代码还需要优化。voidTime_Count_Decrement(void) //秒计数,减计数,{ if(Run_Pause == 1) //1.启动,2.暂停,0.模式切换 { Run_Time--;// if(Run_Time == 0) { Run_ON = 0 ; Run_Pause = 0; } }} voidSeg_Task(void) //显示函数{ static u8i=0; if(Run_ON == 1) { if(Run_Pause == 1) //1.启动,2.暂停,0.模式切换 { switch(i) { case 0 : { Display_Seg(SEG_NUM , T_NUM); } break; case 1 : { Display_Seg(SEG_NUM , T_NUM); } break; } i++; if(i>1) { i=0; } } else if(Run_Pause == 0) //0.仅开机时的模式切换,1.启动,2.暂停 { switch(Display_data) { case 0 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示1 } break; case 1 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示1 } break; case 2 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示2 } break; case 3 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示3 } break; case 4 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示4 } break; case 5 : { Display_Seg(SEG_NUM , T_NUM);//仅仅在数码管1显示5 } break; } } } else { for(i=0;i<8;i++) { Display_Seg( SEG_NUM ,T_NUM);//关机状态,清空。 } }} voidLaundry_Task(void)//洗衣机程序{ switch(Key_Sec)//调用键值进行处理 { case 1 : { Run_ON = !Run_ON ;//开关机 if(Run_ON == 0) { Run_Pause = 0;//关机状态下,所有模式清空 Display_data= 1 ; } } break; case 2 : { if(Run_ON == 1) { Run_Pause +=1 ;//启动暂停键模式切换 if(Run_Pause>2) { Run_Pause= 1; } } } break; case 3 : { Display_data = 1;//显示数据1内容 Run_Time =Time_mode;//装入设定值1 } break; case 4 : { Display_data = 2;//显示数据2内容 Run_Time =Time_mode;//装入设定值2 } break; case 5 : { Display_data = 3;//显示数据3内容 Run_Time =Time_mode;//装入设定值3 } break; case 6 : { Display_data = 4;//显示数据4内容 Run_Time =Time_mode;//装入设定值4 } break; case 7 : { Display_data = 5;//显示数据5内容 Run_Time =Time_mode;//装入设定值5 } break; } Key_Sec = 0;}
第十二集复位系统 的 学习记录1. 复位系统:系统上电复位都是开始工作的第一步。上电复位,使整个系统处于或回到默认的初始硬件状态下,复位也就是强制单片机进行初始化,作用是使CPU和系统中的其他部件都处于一个确定的初始状态,并从这个状态开始工作。2. 复位在Ai8051U中 包含了上电复位、低压复位、复位脚复位和看门狗复位。也可统称为硬件复位或者软件复位两大类。3. 硬件复位:a.上电复位,通过引脚上的接入的一个按钮和阻容元件达到复位效果。复位电压达到(1.7~1.9V)可正常复位b.注意,Ai8051U的复位引脚可以通过程序初始化得到想要的复位效果。默认它的复位引脚没有开启,需要在“AIapp-ISP”的“硬件选项”中开启复位功能。该引脚为“P47”。C.“AIapp-ISP”中与复位相关的设置,“上电复位使用较长延时”:内核决定,可以让各个硬件都完成初始化,但有开机时间要求的可以不开启这个功能。“允许低压复位”:指VCC电压低于设定值时产生复位。“下次冷启动时,P32/P33为0时才可下载程序”“复位脚用作IO口”等设置,让IO口具有更多的功能。d.看门狗复位:这是需要对看门狗控制寄存器进行相应的设置才能正常使用。寄存器“WDT_CONTR”开启后,达到设定值后,将会使单片机复位。所以就必须让单片机定期的去清空计数单元,防止复位。如果单片机异常,不能有效清除计数单元的值,则看门狗认为系统死机,复位动作。WDT_CONTR=0x2n即可开启(n为8级分频系数),WDT_CONTR=0x3n清空定时器,防止复位,同时赋值n。4. 软件复位:对寄存器“IAP-CONTR”赋值达到复位效果。(IAP控制寄存器)IAP-CONTR=0x60(复位到系统ISP区,进入下载模式IAP-CONTR=0x28(复位到用户系统区)IAP-CONTR=0x20复位到用户程序区)5. 课后任务:密码锁a.没有输入时,显示“-- - - - - - -”b.有输入时,按下一个按键,开始按顺序写入 例如,第一个按下1,显示“1 - - - - - - -” 例如,第二个按下3,显示“1 3 - - - - - -”c.当按下的密码为“ 12 3 4 5 6 7 0”时,数码管显示open的字符,否则,还是显示“- - - - - - - -”新增:e.看门狗,超时1秒自动复位f.增加开机版本号,开机显示三秒的U 1.00 版本号g.增加手动复位,P33按钮按下时重启(方便查看版本号和清除密码) 新增代码:主函数中:void main(void) WDT_CONTR= 0X25; //开启看门狗定时器@24M≈1秒定时时长 主循环中:while(1) WDT_CONTR= 0X35; //清除看门狗定时器,且赋值@24M≈1秒定时时长 按键任务中:KEY_Task IAP_CONTR = 0X20; //按下后,复位到用户程序区 调度任务中: Task_Display_Control();//1000毫秒执行一次{ if(!System_control) //该函数执行完就失效。 { Key_Vol= 0; //清空按键计数器 Key_Vol3= 0;//清空按键计数器 if(++Display_Control==3) { passward= 19; //装入正常数据 “--------” passward= 19; //该数组在初始化时的数据为“U1.00” passward= 19; passward= 19; passward= 19; passward= 19; passward= 19; passward= 19; System_control= 1; } }}虽然用另外的一个定时器也能达到效果,且可以关闭,但消耗容量比新增几个变量来运算还多。这个还是比较好的。
第十三集外部中断 的 学习记录1. 关于中断,是专为CPU处理紧急事件而设置的实时处理功能。2. CPU总是会响应优先级别最高的中断请求处理;3. CPU能暂停处理中断源的服务程序,转而处理优先级更高的中断请求,执行完后,再回到原低级的中断服务程序;4. 部分中断的优先级可以用软件设置,高优先级的中断请求可以打断低优先级的中断;5. 每个中断源可以用软件独立的控制开中断或者关闭中断。6. 从上往下,中断优先级越来越低7. 外部中断,就是单片机的引脚引入的一个信号,如高低电平的变化,就会让内部程序暂时打断,转而去执行相应的处理程序,处理完后又回到原来中断的地方继续执行原来的程序。8. 外部中断引脚,须包含INTx标识的才具有该功能,同时还需注意他们支持什么电平变化的触发,如(上升沿触发、下降沿触发等),具体可以查看手册。9. 结构示意途中,可以看出,如:要使用外部中断0,需要设置相关控制寄存器-> IT0(上升\下降沿选择)、IE0(触发标志)、EX0(开启外部中断0)、EA(开启总中断) 10. 中断函数的编写。一般分为初始化,即配置相关寄存器,如设置触发信号的来源(什么类型),设置触发信号的形式(高低电平),设置开启命令(打开相关通道);然后确认相关的中断端口号,编写进入中断后需要执行的程序。初始化配置只需要令相关寄存器到对应状态的指令即可;中断服务程序的编写需要确认正确的端口号(用关键字“interrupt+数字编号”的形式来表达)后,为该服务程序取个好听好记的名字+中断服务号的格式,像编写正常函数一样来编写需要执行的程序。 11.课后练习。用矩阵键盘打开LED,用外部中断1控制LED关闭。
第十四集 IO中断 的 学习记录1. Ai8051u支持普通IO口中断,优先级为4,每一个IO口都可以单独拎出来设置,非常强大!2. 普通IO口的配置:
3. 用作中断的IO口配置:
4. 配置中断IO的同时,还需要配置其相关的控制寄存器:
配置完,才能使用“普通IO口的中断功能”。5. 课程重点讲解如何配置中断优先级,以实现不同的功能,虽然最后一个实验,冲哥将P4设置为最高优先级,同时又将定时器T0也改为最高优先级,我感觉最高优先级始终偏向于P4,他们似乎都是同时在执行,但效果确也实现了。看来还需要加强学习!6. 课后小练:多路抢答器。上电后一位数码管显示0,3个按钮任意一个按下就显示该按钮序号。 第十五集 定时器做计数器 的 学习记录
1. 单片机的定时器可以配置做为计数器使用,一般引脚标识上包含字符T、INT等。
2. 配置定时器工作模式的相关寄存器有TMOD,中断请求寄存器TCON。
配置为外部计数TI_CT=1;配置计数模式;配置控制寄存器GATE和TR;配置计数值;配置输入脚位打开上拉电阻。
3. 配置为计数器初始化时,可以用位寻址的方式配置(TMOD支持位寻址,利用软件查找功能,可以定位到有关“TMOD”的相关头文件),如配置TMOD寄存器中的TI_CT=1,则表示配置TI定时器为外部计数模式;同时需要配置其中的 T1_MO、T1_M1寄存器,从4种组合模式中选择一种来设定其数据计数方式。用位寻址的方式配置简洁明了,当然也可以用直接配置寄存器的方式,用整体赋值,不需要记,但需要查手册算。如“TMOD &= 0x08”。
4. 课程中验证了对引脚低电平出现次数的记录并打印出来,和引脚出现低电平持续时间的累计计数并打印出来。非常的引人入胜。需要反复观看,才能体会老师讲解的精髓!
5. 关于计数器应用的课后小练:计算两次按键按下的时间间隔,同时累计按键按下的次数,数码管左边显示次数,右边显示前后间隔时间。
做好笔记学习深刻
页:
1
[2]