📄 实验5.lst
字号:
C51 COMPILER V7.20 实验5 05/27/2008 11:09:34 PAGE 1
C51 COMPILER V7.20, COMPILATION OF MODULE 实验5
OBJECT MODULE PLACED IN 实验5.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE 实验5.c BROWSE DEBUG OBJECTEXTEND
line level source
1
2 //---------------------------------------------------------------------------------------
3 // 步进电机、直流电机控制板程Version1.1。
4 // 编写开始日期:2008年1月27日
5 // 2008.1.30 改进版本1.1,改变测速方法:测霍尔元件若干次触发的时间
6 // 程序中测速、步进电机精确调速、直流电机PWM精确控制等都合用一个T1计时器
7 // ,100us自动重装。
8 //
9 // 测速方法:用T0作计数器,每计4个脉冲(霍尔),就读一下T1中断次数计时器
10 // count_pulse_time,这个值就是转盘旋转一周所花的时间。由于采用100us为最小时间
11 // 单位。速度测量具有一定的误差。
12 //
13 // 步进电机精确控制速度方法:主要是精确控制每步走的时间。同样利用T1的100us
14 // 定时器。根据设定的转速,可求得每步所需要的时间间隔stepping_interval,
15 // 100us计数器采用count_stepping_interval,当count_stepping_interval计到
16 // stepping_interval值时,步进电机走一步。
17 //
18 // 2008.4.5修改:四个磁钢改为一个磁钢,计数只记一次。
19 // 2008.4.7修改:PWM用一个字节,从0-99,周期改为10ms
20 // 2008.4.12修改:测速用INT1中断,计两次中断的时间,不用T0引脚
21 //---------------------------------------------------------------------------------------
22
23 //-------------------------------------变量定义------------------------------------------
24 #include "string.h"
25 #include "stdio.h"
26 #include "reg52.h"
27 sbit _A=0x90; //步进电机4相控制引脚
28 sbit _B=0x91;
29 sbit _C=0x92;
30 sbit _D=0x93;
31 sbit DC_MOTOR=0x96; //直流电机控制引脚
32 sbit clk0=0x97; //硬件环形分配器时钟控制引脚
33 sbit DIR=0xb2; //硬件环形分配器方向控制引脚
34
35 unsigned char cmd;
36 // cmd为PC机通过串口发给控制板的命令值,后续PC可能再发1-2字节数据或控制板返回2字节数据:n1,n2
37 // cmd=0; PC机无命令
38 // cmd=0xc0; PC机要求软件环形分配步进电机,以转速(n1n2)运行,3字节命令。
39 // cmd=0xc1; PC机要求硬件环形分配步进电机,以转速(n1n2)运行,3字节命令。
40 // cmd=0xc2; PC机要求直流电机以PWM=n1运行,n1为占空比百分数1-100.
41 // cmd=0xc3; PC机要求测电机转速,控制板返回转速(n1n2).
42 // cmd=0xc4;
43 // cmd=0xc5; PC机要求步进电机停止。
44
45
46 unsigned char step_index=0; //步进电机软件分配表的索引值:0-7
47 unsigned int speed=0; //一秒内霍尔触发计数次数,除4乘60即为转速
48 unsigned int count_4pulse_time=0; //定时器T1中断次数计时器,计4个T0脉冲(转一圈)花了多少个100us.
49
50 //----步进电机精确调速所需变量-----------
51 unsigned int stepping_interval; //步进电机在用T0中断精确定速时,每步时间间隔(即合计每步有多少个100us)
52 unsigned int count_stepping_time;//定时器T1中断次数计数器,为计到stepping_interval值所设的计数器
53 bit stepping_by_T0=0; //用定时器T1调速步进电机标记:=1确认,=0取消
54
55 //----直流电机PWM精确调速----------------
C51 COMPILER V7.20 实验5 05/27/2008 11:09:34 PAGE 2
56 unsigned int PWM=0; //直流电机脉宽调制系数(1到99)10^-1,精确到1%
57 //例如PWM=21表示21%
58 unsigned int count_DC_MOTOR_time;
59 //定时器T1中断次数计数器,为计到PWM值所设的计数器
60
61 //----三种步进电机工作方式软件分配表-----
62 unsigned char code step_tab0[8]={0x8,0x4,0x2,0x1,0x8,0x4,0x2,0x1};//4相单4拍
63 unsigned char code step_tab1[8]={0xc,0x6,0x3,0x9,0xc,0x6,0x3,0x9};//4相双4拍
64 unsigned char code step_tab2[8]={0x8,0xc,0x4,0x6,0x2,0x3,0x1,0x9};//4相8拍
65
66 //-----LCD16液晶显示控制引脚定义---------
67 sbit E=0xb4;
68 sbit RS=0xb7;
69 sbit RW=0xb6;
70 sfr lcd_dat_port=0x80; //lcd数据口
71 unsigned char lcd_buf[17];
72 unsigned int count_display; //液晶显示刷新计时
73 //------按键端口定义---------------------
74 sfr key_port=0xa0; //P2口接键盘
75 unsigned char code key_index[16]={0xdb,0xee,0xde,0xbe, //0,1,2,3
76 0x7e,0xed,0xdd,0xbd, //4,5,6,7
77 0x7d,0xeb,0xbb,0x7b, //8,9,上,下
78 0xe7,0xd7,0xb7,0x77};//左,右,功能,确认
79 //------菜单变量定义--------------------
80 unsigned char menu_level=0; //菜单级别,0为没选择
81 unsigned char choice=0; //选择项,0为没选择;
82 // 1为测速;
83 // 2为设定步进电机转速;
84 // 3为设定PWM值
85
86 //-----------------------------变量定义结束------------------------------------------------
87
88 /*----------------- 约延时100us --------------------*/
89 delay(unsigned char dy)
90 {
91 1 unsigned char ii;
92 1 while(--dy)
93 1 for(ii=0;ii<24;ii++) ;
94 1 }
95 /*----------------步进电机环形分配驱动程序---------------*/
96 void step(bit direction)
97 {unsigned char state;
98 1 if (direction==1)
99 1 {if (++step_index>7) step_index=0;} //正转
100 1 else
101 1 {if (--step_index<0) step_index=7;} //反转
102 1
103 1 state=step_tab0[step_index];
104 1
105 1
106 1 //根据开关状态决定使用硬件环形分配还是软件环形分配
107 1 clk0=~clk0; //使用硬件环形分配器情况
108 1 _A=state & 0x8; //实用软件环形分配器情况
109 1 _B=state & 0x4;
110 1 _C=state & 0x2;
111 1 _D=state & 0x1;
112 1
113 1 }
114 /*----------------------步进电机软件延时的升速------------------------
115 void accelerating()
116 {
117 unsigned char i;
C51 COMPILER V7.20 实验5 05/27/2008 11:09:34 PAGE 3
118 for(i=0;i<200;i++)
119 {step(1);
120 delay(240-i);
121 }
122 while(1)
123 {step(1);
124 delay(30); //最高速约可到20
125 }
126 }*/
127 /*------------------- 步进电机软件延时调速------------------
128 void stepping(bit direction,unsigned char dy)
129 //direction为方向=0或=1; dy为每步延时时间从0-255
130 {
131 while(1)
132 {step(direction);
133 delay(dy); //最高速约可到20
134 }
135 }*/
136 //----------- T0、T1初始化设置,--------------------------
137 //2008.4.12日,将T0中断改为INT1中断
138 //功能: 设置T1定时100us,T0作计数(计霍尔脉冲数)测转速
139 void set_T0T1() //测步进电机转速时, T1作为定时器计100us时间
140 { //T0计4个霍尔脉冲,察看需要的时间
141 1 TMOD=0x22; //T1:定时方式2,8位自动重装定时器;T0:计数方式1,8自动重装计数器.
142 1 TH1=256-184; //22.1184MHz晶振,184个机器周期约为100微秒(99.83us)
143 1 TL1=256-184;
144 1 TH0=256-56; //T0用来计20us,
145 1 TL0=256-56;
146 1 IT1=1; //INT1为边沿触发上升沿方式
147 1 EA=1;ET1=1;EX1=1;ET0=1; //开定时器T0中断,改为INT1中断
148 1
149 1 TR0=1;
150 1
151 1 TR1=1; //T0开始计数,T1开始计时
152 1 count_4pulse_time=0; //定时器T0累计数清零
153 1 }
154 //--------------步进电机定时器精确调速--------------------
155 //功能: 根据指定速度计算每步以100us为单位的时间间隔
156 void stepping_int(unsigned int stepping_speed_int) //speed_int是转速:r/min
157 {
158 1 float stepping_speed; //为了减少计算带来的误差,先用浮点数进行计算
159 1 stepping_speed=stepping_speed_int;
160 1 stepping_speed=60/(stepping_speed*48);//得到每步秒数
161 1 stepping_speed=stepping_speed*10000; //得到每步百微秒数
162 1 stepping_interval=stepping_speed;
163 1 //set_T0T1(); //设置T1,T0: T1定时器作定时100us并控制步进电机,
164 1 // T0作计数以测定直流电机或步进电机转速
165 1 stepping_by_T0=1;
166 1 }
167 /*--------------------直流电机PWM调速程序1-------------------
168 void pwm(unsigned char percent)//percent为占空比百分比从1到100
169 { unsigned int i,j;
170 j=10*percent;
171 while(1)
172 {
173 DC_MOTOR=1;
174 for(i=0;i<j;i++);
175 DC_MOTOR=0;
176 for(i=0;i<1000-j;i++);
177 }
178 }*/
179 //------定时器T0计20us,用于产生PWM波---------------
C51 COMPILER V7.20 实验5 05/27/2008 11:09:34 PAGE 4
180 void Timer0() interrupt 1 using 2 //每个脉冲进入1次中断
181 {
182 1 count_DC_MOTOR_time++; //直流电机的PWM控制计时
183 1 if (count_DC_MOTOR_time>PWM)
184 1 {
185 2 DC_MOTOR=0;
186 2 if (count_DC_MOTOR_time>500) count_DC_MOTOR_time=0;
187 2 }
188 1 else DC_MOTOR=1;
189 1 }
190 //---------用INT1中断计4个脉冲的中断程序,测量步进电机及测直流电机转速-------
191 void INT1_measurement() interrupt 2 //每个脉冲进入1次中断
192 { unsigned long long_speed; //为减少计算误差,先用浮点数运算
193 1 long_speed=count_4pulse_time;
194 1 count_4pulse_time=0; //重新开始计数
195 1 long_speed=600000L/long_speed; //将计100us数的值转换为每分转的圈数
196 1 speed=long_speed;
197 1 }
198 //-------定时器T1的100us中断程序,控制步进电机转速并为步进/直流电机测速计时----
199 void Timer1() interrupt 3
200 {
201 1 count_4pulse_time++; //为步进电机或直流电机测速计时,4个脉冲一个周期=n个100us
202 1 count_stepping_time++; //为控制步进电机转速计时,计每步是否达到预定速度要求的间隔时
203 1 count_display++;
204 1 if (count_4pulse_time>5000)
205 1 {
206 2 count_4pulse_time=0;
207 2 speed=0;
208 2 }
209 1 if ((stepping_by_T0==1)&&(count_stepping_time>=stepping_interval))
210 1 { //控制步进电机速度
211 2 count_stepping_time=0;
212 2 step(1);
213 2 }
214 1 }
215 //---------------- 初始化串口 ---------------------------
216 void ini_com()
217 {
218 1 SM0=0;SM1=1;REN=1; //串口设定:方式1,即8位可变波特率,接收使能
219 1 T2CON=0x34; //用T2作为波特率发生器
220 1 RCAP2H=0xff;TH2=0xff;
221 1 RCAP2L=0xdc;TL2=0xdc; //0xdc=波特率19200 0xfa=115200
222 1 }
223 //----------------- 串口接收一字节 ----------------------
224 unsigned char receipt_byte()
225 {
226 1 unsigned int i=0;
227 1 while(RI==0 && i<1000) i++;
228 1 RI=0;
229 1 return(SBUF);
230 1 }
231 //----------------- 串口发送一字节 ----------------------
232 void transmit_byte(unsigned char send_byte)
233 {
234 1 ES=0;
235 1 SBUF=send_byte;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -