赞
踩
/*-----------------动态显示数码管------------------*/
利用人的视觉暂留的特点;
- P0 = ***;
- w1 = 0;
- delay_ms(1);
- w1 = 1;
-
- P0 = ****;
- w2 = 0;
- delay_ms(1);
- w2 = 0;
练习:
通过动态显示:
让四个数码管 显示自己
生日的 月日
- #include"shumaguan.h"
- #include"delay.h"
- #include<reg52.h>
-
- sbit w1 = P1^0;
- sbit w2 = P1^1;
- sbit w3 = P1^2;
- sbit w4 = P1^3;
-
- void show_0718(){
- w4 = 0;
- P0 = 0xc0;
- delay_ms(1);
- w4 = 1;
-
- w3 = 0;
- P0 = 0xf8;
- delay_ms(1);
- w3 = 1;
-
- w2 = 0;
- P0 = 0xf9;
- delay_ms(1);
- w2 = 1;
-
- w1 = 0;
- P0 = 0x7f;
- delay_ms(1);
- w1 = 1;
- }

1234%10 = 4;
1234%100 = 34;
1234%1000 = 234;
1234/10 = 123
1234/100 = 12
1234/1000 = 1
练习:
动态计数 0~9999
- #include"sum.h"
- #include"delay.h"
- #include<reg52.h>
-
- sbit w1 = P1^0;
- sbit w2 = P1^1;
- sbit w3 = P1^2;
- sbit w4 = P1^3;
-
- int i = 0;
-
- unsigned int array[10]={0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90};
-
- void sum_shumaguan(){
- int j;
- while(1){
- for(j = 0;j <80; j++){
- w4 = 0;
- P0 = array[i/1000];
- delay_ms(1);
- w4 = 1;
-
- w3 = 0;
- P0 = array[i/100%10];
- delay_ms(1);
- w3 = 1;
-
- w2 = 0;
- P0 = array[i/10%10];
- delay_ms(1);
- w2 = 1;
-
- w1 = 0;
- P0 = array[i%10];
- delay_ms(1);
- w1 = 1;
- }
- // i++;
- if(10000 == i)
- {
- i = 0;
- }
- }
-
-
- }

/*---------------------定时器-----------------------*/
定时器的初步认识:
时钟周期:
时钟周期 T 是时序中的最小单位
计算 : 1/时钟源频率
我们的单片机晶振 11.0592M M = 10^6
所以:
T : 1 / 11059200
机器周期:
我们单片机完成一个操作的最短时间 --- 汇编
汇编语言下 一个语句的执行时间 就一个机器周期的整数倍
定时器:
顾名思义 用来定时
定时器的内部有一个寄存器
我们让他进行计数
这个寄存器的值每经过一个机器周期 就会自动 +1
溢出 : 满了 溢出来了
例如 表
定时器的寄存器:
标准的C51单片机 有T0 , T1 两个定时器
T time的缩写
80C51单片机内设有两个可编程的定时器/计数器 T0 T1
是一个 16 位的计数器 , 分别 有一个 高 8 位 , 一个 低 8 位的寄存器组成
TMOD 定时/计数器的工作方式寄存器
作用:
确定工作方式和功能
TCON 控制寄存器
作用: 控制T1 T0的启动和停止等等
定时/计数器实质上是一个加1的计数器, 它随着计数器的输入脉冲进行自动加1 ,
当加到计数器全为1的时候,再输入一个脉冲就使得计数器归零 , 计数器溢出会
使中断标志位置1 , 向CPU发送请求。
M1 M0 工作模式 描述
0 0 0 13位定时 , 高 8 位 ,低 5 位的寄存器组成
0 1 1 16位的定时 ,高8位 , 低8位
1 0 2 8位自动重装载模式
1 1 4 禁用t定时0变成 两个 8 位定时器
TCON定时器:
见图
编写定时器中断程序:
1、设定定时器工作模式
选择定时器 0 , 工作方式设置为 16 位定时/计数模式
//定时器 0 , 工作模式 1;
2、设定初值
以方式1为例:
方式1为16位定时/计数器 , 对定时器T0来说
分为两个寄存器:
TH0 TL0
高8位 低8位
(想象成 两个 容器)
组成了16位定时器 , 当我们TL0计满之后 , 向TH0移动一个数
机器周期 是 1us , 计满TH0或TL0
需要256 - 1个数 , 再来一个数就“溢出”啦 , 产生“中断”
1111 1111 1111 1111
产生中断请求
256 × 256
总共需要65536us
公式:
总值 - 需要定时值(程序员想要的时间) = 预装值(16位定时器一开始的值 , 就是它不是从 0000 0000 0000 0000 的 , 而是从预装值开始)
我们机器从预装值开始 , 就会计时我们想要的时间后溢出 , 产生中断请求
例:
定时 50ms
65536 - 50000 = 15536
如何将预装值分配给 TH0 , TL0 呢
TH0 = (65536 - 50000) / 256
TL0 = (65536 - 50000) % 256
伪代码:
//赋预装值高 8 位 给TH0
//赋预装值的低 8 位给TL0
3、使能定时器 0 中断
4、使能总中断
5、启动定时器 0
定时器的初始化:
所以 共5步
编写中断服务函数:
难啊
练习:
使用定时器中断精准定时1s,成功实现数码管计时器。
伪代码:
数码管动态计数显示代码已经搞定啦
定时器中断初始化:
五步:
void time_IT0_init()
{
//设置定时器工作模式 , 模式1 16定时
//配置预装载值
······
//使能定时器0中断
//使能总中断
//开启定时器0
}
void interrupt_IT0(void) interrupt 1
{
//重新配置 预装载值
······
//后面程序,随程序员自由编写
}
由于我们的定时器中断定时 是 50ms
那么我们的需求是1s
如何去精准定时1s
交给大家去思考 、 编写
- #include "time.h"
- #include <reg52.h>
-
-
- extern int i;
-
- int j = 0;
-
-
-
-
-
- //定时器T0中断初始化函数
- void time_IT0_init()
- {
- TMOD = 0x01;//设置定时器工作模式,模式1 16定时
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;//配置预装载值
-
- ET0 = 1;//使能定时器0中断
- EA = 1;//使能总中断
- TR0 = 1;//开启定时器0
- }
- void interrupt_IT0(void) interrupt 1
- {
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;//配置预装载值
- j++;
- if( 20 == j)
- {
- i++;
- j = 0;
- }
-
-
- }
- //定时器T0中断服务函数
-
-
-
-
-
-
-
-
-
-
-
-
-

/*------------------电机(马达)-------------------*/
马达:
磁铁:
两个接口:
只需接入高低电平
动起来
电平倒过来:
就会反转
/*------------------------------------------------*/
作业:
1、实现小车的前进 、 后退 、 停止 、左转 、 右转
2、让小车自己能够走 8 字 或者 走圆圈 | 口字
(定时器中断)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。