本帖最后由 千年老姚 于 2023-2-2 19:39 编辑
感谢大家最近以来对本帖子的支持!
因为个人原因 拖更了太久
但是最近又要准备期末考 所以我可能没办法更新很频繁 大概三四天一更。
谢谢各位关注 以下为今日复习:
第十二章:计数器的使用
一.计数器的用途例:直流有刷电机 对光电码盘的扫描 编码器——咖啡机 只要输出信号带着高低电平变化,想要计算个数的就可以使用计数器的功能 二.计数器的配置T1C/T位写1 T1_GATE = 0 TR1 = 1 例如 TH1,TL1写入数值500 假设不分频 脉冲+1+1至65535,超过65535直接溢出重装载,又到了65536之后重新计数 例:定时器1:外部计数——扩展T1为外部下降沿中断 /*****省略部分代码*****/ void main() { TMOD = 0X40; //设置计数器模式 TL1 = 0XFF; //设置计数器初始值 TH1 = 0XFF; //设置定时器初始值 TF0 = 0; //清除TF0标志 TH0 = 0; //定时器0开始计时 ET0 = 0; //使能定时器0中断 P3PU = 0X20; //手册建议 打开4.1k上拉电阻 可使用stcisp进行配置 } void Timer0_Inr(void) interrupt3 { P60 = !P60; //检测到一个外部脉冲 }
手册建议 打开4k上拉电阻 可使用stcisp进行配置 三.计数器的应用例:2017.全国大学生电子设计竞赛O题 任务: 在不检测电动机转轴旋转运动的前提下,按照下列要求设计并制作相应的直流电动机测速装置。 要求: 1.基本要求 以电动机电枢供电回路申接采样电阻的方式实现对小型直流有刷电动机的转速测量。 (1)测量范围: 600 ~ 5000rpm (2)显示格式:四位十进制 (3)测量误差:不大于0.5% (4)测量周期: 2秒. (5)采样电阻对转速的影响:不大于0.5% 思路: n=1/(tg*c)=F0/(M1*C) M法测速:又叫做频率测量法。这种方法是在一个固定的定时时间内(以秒为单位),统计这段时间的编码器脉冲数,计算速度值。设编码器单圈总脉冲数为C, 时间T0内,统计到的编码器脉冲数为M0,则转速n的计算公式为:n = M0 /(C*T0) 代码如下: /*省略部分头文件*/ void sys_init(); //函数声明 void delay_ms(u16 ms); //unsigned int void SEG_Fre( void ) { //位码选择第一位,段码选择0 P7 = COM_Tab[num]; //位码的选择 P6 = SEG_Tab[Show_Tab[num]];//需要显示的数字的内码 赋给 P6 NUM =0 -> Show_Tab[num]] = 1 -> p6 = oxF9 //delay_ms(SEG_Delay); num++; if( num >7 ) num = 0; }
void Timer0_Init(void) //1毫秒@24.000MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x30; //设置定时初始值 TH0 = 0xF8; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; //使能定时器0中断 } void main() //程序开始运行的入口 { sys_init(); //USB功能+IO口初始化 usb_init(); //usb库初始化 TMOD = 0x50; //设置计数器模式 TL1 = 0x00; //设置计数初始值 TH1 = 0x00; //设置计数初始值 TF1 = 0; //清除TF1标志 TR1 = 1; //定时器1开始计时 ET1 = 1; //使能定时器1中断 P3PU = 0x20; //打开内部上拉4.1K Timer0_Init(); EA = 1; //CPU开放中断,打开总中断。 while(1) //死循环 { if( DeviceState != DEVSTATE_CONFIGURED ) // continue; if( bUsbOutReady ) { usb_OUT_done(); } } } void Timer0_Isr(void) interrupt 1 { TimCount++; //每隔1ms+1 // 计数到2000 = 2s if( TimCount>=2000 ) //2秒定时时间到了 { TimCount = 0; Count_T1 = (TH1 *256 )+ TL1; // 转/2s 转/min TH1 = 0; TL1 = 0; Show_Tab[4] = Count_T1/1000%10; Show_Tab[5] = Count_T1/100%10; Show_Tab[6] = Count_T1/10%10; Show_Tab[7] = Count_T1/1%10; //取10位 } SEG_Fre(); //数码管刷新的 } void Timer1_Isr(void) interrupt 3 { } /* 11111110 0XFE 11111101 0XFD 11111011 0XFB 11110111 0XF7 11101111 0XEF 11011111 0XDF 10111111 0XBF 01111111 0X7F */ void sys_init() //函数定义 { WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快 EAXFR = 1; //扩展寄存器(XFR)访问使能 CKCON = 0; //提高访问XRAM速度 P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口 P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口 P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口 P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口 P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口 P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口 P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口 P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口 P3M0 = 0x00; P3M1 = 0x00; P3M0 &= ~0x03; P3M1 |= 0x03; //设置USB使用的时钟源 IRC48MCR = 0x80; //使能内部48M高速IRC while (!(IRC48MCR & 0x01)); //等待时钟稳定 USBCLK = 0x00; //使用CDC功能需要使用这两行,HID功能禁用这两行。 USBCON = 0x90; } void delay_ms(u16 ms) //unsigned int { u16 i; do { i = MAIN_Fosc/6000; while(--i); }while(--ms); }
|