网友投稿 591 2022-05-29
编程实验分别仿真和实验台操作两种方式。
实验1 AD转换--输入
AD转换是所有嵌入式系统或机器人获取外部信息的一种重要方式,将温度、角度和位置等转换为对应的数字量,供处理器处理。
原理图:
程序:
/*************** ex1 ******************/
#include
#define uint unsigned int
#define uchar unsigned char
uchar code LEDData[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
sbit OE = P1^0;
sbit EOC = P1^1;
sbit ST = P1^2;
sbit CLK = P1^3;
void DelayMS(uint ms)
uchar i;
while(ms--)
for(i=0;i<120;i++);
}
void Display_Result(uchar d)
P2 = 0xf7;
P0 = LEDData[d%10];
DelayMS(5);
P2 = 0xfb;
P0 = LEDData[d%100/10];
P2 = 0xfd;
P0 = LEDData[d/100];
void main()
TMOD = 0x02;
TH0 = 0x14;
TL0 = 0x00;
IE = 0x82;
TR0 = 1;
P1 = 0x3f;
while(1)
ST = 0;
ST = 1;
while(EOC == 0);
OE = 1;
Display_Result(P3);
OE = 0;
void Timer0_INT() interrupt 1
CLK = !CLK;
实验台,测量电压值并显示:
代码:
//模数实验
#include "reg52.h"
#define ulong unsigned long
sbit LE1=P3^3;
//定义数值显示
uchar code xianshi[11]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xbE,0xE0,0xFE,0xF6,0x00};
sbit ST=P3^0; //起始
sbit OE=P3^1; //使能
sbit EOC=P3^2; //转换完成标志位
sbit ADD_A=P3^5; //输入端口选择A
sbit ADD_B=P3^6; //输入端口选择B
sbit ADD_C=P3^7; //输入端口选择C
uint getdata,average,n,volt,sum; //变量
void delay1_ms(uint time) //延时
uint i,j;
for(i=0;ifor(j=0;j<123;j++);}void display_num1(uint dat,uchar num1) //显示数值{// P2=0x00;// P0=0x00;P0=xianshi[dat];switch(num1){case 1: P2=0x01;break;case 2: P2=0x02;break;case 3: P2=0x04;break;case 4: P2=0x08;break;case 5: P2=0x10;break;case 6: P2=0x20;break;case 7: P2=0x40;break;case 8: P2=0x80;break;default: break;}delay1_ms(1);//P0=0x00;}//数码管4位显示函数void display_num4(uint num){uint wan;uint qian;uint bai;uint shi;uint ge;P2=0x00;wan=(num/10000)%10;if(wan==0) wan=10;display_num1(wan,5);qian=(num/1000)%10;if(wan==10&&qian==0) qian=10;display_num1(qian,4);bai=(num/100)%10;if(wan==10&&qian==10&&bai==0) bai=10;display_num1(bai,3);shi=(num/10)%10;if(wan==10&&qian==10&&bai==10&&shi==0) shi=10;display_num1(shi,2);ge=num%10;display_num1(ge,1);}void delay(uint N){while(N--);}uint adconvert_date(){ST=0;ST=1;delay(2);ST=0;while(!EOC);OE=1;delay(2);getdata=P1;delay(2);OE=0;return getdata;}void main(){uint i;uint n;uint volt;ulong sum=0;uint average;P2=0x00;ADD_A=0;ADD_B=0;ADD_C=0;delay(1000);while(1){ADD_A=0;ADD_B=0;ADD_C=0;ST=0;P2=0x00;for(n=0;n<10;n++){volt=adconvert_date(); //测量可变电阻电压sum += volt; //累加次数50}average=sum/10; //取平均值average=average*19.4; //换算成电压值 19.4=OKsum=0; //和清零for(i=0;i<400;i++)display_num4(average); //显示平均值}}DA转换将控制器结果转为模拟量控制外部设备。最常用的实验是波形仿真。数字调压:代码:#include #define uint unsigned int#define uchar unsigned charsbit K1 = P3^0;sbit K2 = P3^1;sbit K3 = P3^2;sbit K4 = P3^3;sbit K5 = P3^4;sbit K6 = P3^5;sbit K7 = P3^6;sbit K8 = P3^7;void DelayMS(uint ms){uchar i;while(ms--){for(i=0;i<120;i++);}}void main(){P2 = 0x00;while(1){if(K1 == 0) P2 = 0;if(K2 == 0) P2 = 35;if(K3 == 0) P2 = 70;if(K4 == 0) P2 = 105;if(K5 == 0) P2 = 140;if(K6 == 0) P2 = 175;if(K7 == 0) P2 = 210;if(K8 == 0) P2 = 255;DelayMS(2);}}代码:#include #include #define uint unsigned int#define uchar unsigned char#define DAC0832 XBYTE[0xfffe]char code sin_data[256]={0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,0xda,0xd8,0xd6,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x3,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xc,0xd,0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,0x27,0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c};//正弦码表,可通过SIN()函数获得void DelayMS(uint ms){uchar i;while(ms--){for(i=0;i<120;i++);}}void delay_nus(unsigned int i){unsigned int j;while(i--){for(j=0;j<127;j++);}}/**********************************************/void delay(unsigned char i){unsigned char t;for(t=0;t}/**********************************************输出数据到端口(注意考虑延时)**********************************************/void conversion(unsigned char out_data){DAC0832 =out_data; //输出数据delay(1);//delay_nus(10); //延时等待转换}/************************************************产生正弦波函数************************************************/void sine(void){unsigned char i;for(i=0;i<255;i++){conversion(sin_data[i]);}}/***********************************************产生锯齿波(下降型)***********************************************/void saw(void){unsigned char j;for(j=0;j<255;j++)conversion(j);}/***********************************************产生方波(脉冲)***********************************************/void pulse(void){conversion(0xff);delay_nus(1000);conversion(0x00);delay_nus(1000);}/***********************************************产生三角波***********************************************/void triangle(void){unsigned char k;for(k=0;k<255;k++)conversion(k);for(;k>0;k--)conversion(k);}void main(){while(1){// pulse();// saw();// sine();triangle();}}代码:#include"reg52.h"char code sin_data[256]={0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,0xda,0xd8,0xd6,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x3,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xc,0xd,0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,0x27,0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c};//正弦码表,可通过SIN()函数获得void delay_nus(unsigned int i){unsigned int j;while(i--){for(j=0;j<127;j++);}}/**********************************************/void delay(unsigned char i){unsigned char t;for(t=0;t}/**********************************************输出数据到端口(注意考虑延时)**********************************************/void conversion(unsigned char out_data){P0=out_data; //输出数据delay(5);//delay_nus(10); //延时等待转换}/************************************************产生正弦波函数************************************************/void sine(void){unsigned char i;for(i=0;i<255;i++){conversion(sin_data[i]);}}/***********************************************产生锯齿波(下降型)***********************************************/void saw(void){unsigned char j;for(j=0;j<255;j++)conversion(j);}/***********************************************产生方波(脉冲)***********************************************/void pulse(void){conversion(0xff);delay_nus(1000);conversion(0x00);delay_nus(1000);}/***********************************************产生三角波***********************************************/void triangle(void){unsigned char k;for(k=0;k<255;k++)conversion(k);for(;k>0;k--)conversion(k);}void main(){while(1){pulse();//saw();//sine();//triangle();}}实验台:代码:#include"reg52.h"#include "math.h"#define uchar unsigned char#define uint unsigned intuchar code xianshi[12]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xbE,0xE0,0xFE,0xF6,0x9c,0x00};sbit PWM=P1^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;uint wide=100;//脉宽计数uint t1=0; //低电平脉宽uint t2=0; //一个周期uint time_low=0;uint time_high=100;bit high_flag=0;bit low_flag=0;bit state_flag=0;uint set_count=100;//设定转速值uint run_count=0;//实际频率的读取uint stop_count=0; //电机转速存储变量uint time=0;int en=0,en_1=0,en_2=0; //定义 三个时刻的误差存储变量float a0=1.7,a1=0.30,a2 =0.002,un=0; //定义PID计算参公式的参数void delay1_ms(uint time);void delay(uint time);void display_num1(uint dat,uchar num1);void display_num4(uint num);void time01_initiat(void);void key_precess(void);void pid(void);void main(){time01_initiat(); //初始化定时器0和定时器1while(1){key_precess(); //键盘扫描函数}}//1ms延时函数void delay1_ms(uint time){uint i,j;for(i=0;ifor(j=0;j<123;j++);}//指定的位上显示 指定的一位数据void display_num1(uint dat,uchar num1){P0=xianshi[dat]; //段显switch(num1){case 1: P2=0x01;break;case 2: P2=0x02;break;case 3: P2=0x04;break;case 4: P2=0x08;break;default: break;}delay1_ms(2);}//四位数据显示函数void display_num4(uint num){uint qian;uint bai;uint shi;uint ge;qian=num/1000;if(qian==0)// qian=11;display_num1(11,4);bai=num%1000;bai=bai/100;if(qian==10&&bai==0) bai=10;display_num1(bai,3);shi=num%100;shi=shi/10;if(qian==10&&bai==10&&shi==0) shi=10;display_num1(shi,2);ge=num%10;display_num1(ge,1);}//四位数据显示函数void display_num4_1(uint num){uint qian;uint bai;uint shi;uint ge;display_num1(10,4);bai=num%1000;bai=bai/100;if(qian==10&&bai==0) bai=10;display_num1(bai,3);shi=num%100;shi=shi/10;if(qian==10&&bai==10&&shi==0) shi=10;display_num1(shi,2);ge=num%10;display_num1(ge,1);}void delay(uint time){uint i;for(i=0;idisplay_num4_1(stop_count);}void delay1(uint num){uint i;for(i=0;idisplay_num4(set_count);}void time01_initiat(){TMOD=0X11; //计数器0和定时器1TL0=0X33;TH0=0XFE;//计数器0赋初值 0.5msTH1=0X4C;TL1=0X00;//定时器1赋初值 50msEA=1;PT0=1;ET0=1;ET1=1;TR0=0;TR1=0;IT0=1;EX0=0;}void key_precess(){if(key1==0&&key2==1&&key3==1) //判断系统的运行模式,如果KEY1键 按下//且state_flag为1则系统处于运行模式,如果state__flag为0则为设置模式{while(key1==0);state_flag=~state_flag;if(state_flag==1){EX0=1;TR1=1;TR0=1;en =0;en_1 =0;en_2 =0;un =0;wide=150;//wide = set_count;}}if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2为按键加{//while(key2==0);delay1(20);set_count+=1;if(set_count>300) set_count=100;}if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3为按键减{// while(key3==0);delay1(20);if(set_count>100) set_count-=1;if(set_count==100) set_count=300;}if(state_flag==0) //如果系统处于设置模式,则关闭定时器中断和外部中断,同时初始化部分变量{PWM = 0;EX0=0;TR0=0;TR1=0;run_count=0;stop_count=0;time=0;t1=0;t2=0;display_num4(set_count);}if(state_flag==1) //如果系统处于运行模式则显示电机的实际转速值{display_num4_1(stop_count);}}void pid(void) //PID 计算输出量{en=set_count-stop_count;un=1.7*en-0.03*en_1+0.002*en_2;//计算输出量if(un > 400)un = 400;if(un <-400)un = -400;en_2=en_1; //更新误差en_1=en;wide = wide + un/4; //计算wide,用于调节PWM的占空比,计算周期为100msif(wide>900)wide=900; //防止超限,确保计算饿wide值有效if(wide<10)wide=10;}//外部中断0用于电机转速测量void int0() interrupt 0{EX0=0;run_count++;EX0=1;}//定时器0用于产生PWM ,占空比通过PID计算获得void time0() interrupt 1{TL0=0X9c;TH0=0XFF;//计数器0赋初值 100usTR0=0;if(low_flag==0)t1++;//低电平时间计时t2++;if(t2==1000) //用于确定PWM的周期 ,t2乘以定时器的中断周期即为PWM的周期{PWM=1;t2=0;low_flag=0;}if(t1==wide)//wide的值即为低电平的时间{PWM=0;t1=0;low_flag=1;}TR0=1;}void time1() interrupt 3{TH1=0X3C;TL1=0XBD; //50ms定时TR1=0;time++;if(time==40) //定时2s到,读取到的值run_count即为电机每秒的转速值{stop_count=run_count/2;time=0;run_count=0;pid(); //调用PID算法}TR1=1;} 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
for(j=0;j<123;j++);
void display_num1(uint dat,uchar num1) //显示数值
// P2=0x00;
// P0=0x00;
P0=xianshi[dat];
switch(num1)
case 1: P2=0x01;break;
case 2: P2=0x02;break;
case 3: P2=0x04;break;
case 4: P2=0x08;break;
case 5: P2=0x10;break;
case 6: P2=0x20;break;
case 7: P2=0x40;break;
case 8: P2=0x80;break;
default: break;
delay1_ms(1);
//P0=0x00;
//数码管4位显示函数
void display_num4(uint num)
uint wan;
uint qian;
uint bai;
uint shi;
uint ge;
P2=0x00;
wan=(num/10000)%10;
if(wan==0) wan=10;
display_num1(wan,5);
qian=(num/1000)%10;
if(wan==10&&qian==0) qian=10;
display_num1(qian,4);
bai=(num/100)%10;
if(wan==10&&qian==10&&bai==0) bai=10;
display_num1(bai,3);
shi=(num/10)%10;
if(wan==10&&qian==10&&bai==10&&shi==0) shi=10;
display_num1(shi,2);
ge=num%10;
display_num1(ge,1);
void delay(uint N)
while(N--);
uint adconvert_date()
ST=0;
ST=1;
delay(2);
while(!EOC);
OE=1;
getdata=P1;
OE=0;
return getdata;
uint i;
uint n;
uint volt;
ulong sum=0;
uint average;
ADD_A=0;
ADD_B=0;
ADD_C=0;
delay(1000);
for(n=0;n<10;n++)
volt=adconvert_date(); //测量可变电阻电压
sum += volt; //累加次数50
average=sum/10; //取平均值
average=average*19.4; //换算成电压值 19.4=OK
sum=0; //和清零
for(i=0;i<400;i++)
display_num4(average); //显示平均值
DA转换将控制器结果转为模拟量控制外部设备。最常用的实验是波形仿真。
数字调压:
sbit K1 = P3^0;
sbit K2 = P3^1;
sbit K3 = P3^2;
sbit K4 = P3^3;
sbit K5 = P3^4;
sbit K6 = P3^5;
sbit K7 = P3^6;
sbit K8 = P3^7;
P2 = 0x00;
if(K1 == 0) P2 = 0;
if(K2 == 0) P2 = 35;
if(K3 == 0) P2 = 70;
if(K4 == 0) P2 = 105;
if(K5 == 0) P2 = 140;
if(K6 == 0) P2 = 175;
if(K7 == 0) P2 = 210;
if(K8 == 0) P2 = 255;
DelayMS(2);
#define DAC0832 XBYTE[0xfffe]
char code sin_data[256]={0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,
0xab,0xae,0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,
0xd8,0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf4,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,
0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe3,0xe1,0xde,0xdc,0xda,0xd8,0xd6,
0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb4,0xb1,0xae,0xab,0xa8,
0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x92,0x8f,0x8c,0x89,0x86,0x83,0x80,0x7d,0x79,0x76,0x73,
0x70,0x6d,0x6a,0x67,0x64,0x61,0x5e,0x5b,0x58,0x55,0x52,0x4f,0x4c,0x49,0x46,0x43,0x41,
0x3e,0x3b,0x39,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,
0x17,0x15,0x14,0x12,0x10,0xf,0xd,0xc,0xb,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x3,0x2,0x1,0x1,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x3,0x3,0x4,0x5,0x6,0x7,0x8,
0x9,0xa,0xc,0xd,0xe,0x10,0x12,0x13,0x15,0x17,0x18,0x1a,0x1c,0x1e,0x20,0x23,0x25,0x27,
0x29,0x2c,0x2e,0x30,0x33,0x35,0x38,0x3b,0x3d,0x40,0x43,0x46,0x48,0x4b,0x4e,0x51,0x54,
0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x73,0x76,0x79,0x7c};//正弦码表,可通过SIN()函数获得
void delay_nus(unsigned int i)
unsigned int j;
while(i--)
for(j=0;j<127;j++);
/**********************************************/
void delay(unsigned char i)
unsigned char t;
for(t=0;t
/**********************************************
输出数据到端口(注意考虑延时)
**********************************************/
void conversion(unsigned char out_data)
DAC0832 =out_data; //输出数据
delay(1);
//delay_nus(10); //延时等待转换
/************************************************
产生正弦波函数
************************************************/
void sine(void)
unsigned char i;
for(i=0;i<255;i++)
conversion(sin_data[i]);
/***********************************************
产生锯齿波(下降型)
***********************************************/
void saw(void)
unsigned char j;
for(j=0;j<255;j++)
conversion(j);
产生方波(脉冲)
void pulse(void)
conversion(0xff);
delay_nus(1000);
conversion(0x00);
产生三角波
void triangle(void)
unsigned char k;
for(k=0;k<255;k++)
conversion(k);
for(;k>0;k--)
// pulse();
// saw();
// sine();
triangle();
#include"reg52.h"
P0=out_data; //输出数据
delay(5);
pulse();
//saw();
//sine();
//triangle();
实验台:
#include "math.h"
uchar code xianshi[12]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xbE,0xE0,0xFE,0xF6,0x9c,0x00};
sbit PWM=P1^7;
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
uint wide=100;//脉宽计数
uint t1=0; //低电平脉宽
uint t2=0; //一个周期
uint time_low=0;
uint time_high=100;
bit high_flag=0;
bit low_flag=0;
bit state_flag=0;
uint set_count=100;//设定转速值
uint run_count=0;//实际频率的读取
uint stop_count=0; //电机转速存储变量
uint time=0;
int en=0,en_1=0,en_2=0; //定义 三个时刻的误差存储变量
float a0=1.7,a1=0.30,a2 =0.002,un=0; //定义PID计算参公式的参数
void delay1_ms(uint time);
void delay(uint time);
void display_num1(uint dat,uchar num1);
void display_num4(uint num);
void time01_initiat(void);
void key_precess(void);
void pid(void);
time01_initiat(); //初始化定时器0和定时器1
key_precess(); //键盘扫描函数
//1ms延时函数
void delay1_ms(uint time)
for(i=0;ifor(j=0;j<123;j++);}//指定的位上显示 指定的一位数据void display_num1(uint dat,uchar num1){P0=xianshi[dat]; //段显switch(num1){case 1: P2=0x01;break;case 2: P2=0x02;break;case 3: P2=0x04;break;case 4: P2=0x08;break;default: break;}delay1_ms(2);}//四位数据显示函数void display_num4(uint num){uint qian;uint bai;uint shi;uint ge;qian=num/1000;if(qian==0)// qian=11;display_num1(11,4);bai=num%1000;bai=bai/100;if(qian==10&&bai==0) bai=10;display_num1(bai,3);shi=num%100;shi=shi/10;if(qian==10&&bai==10&&shi==0) shi=10;display_num1(shi,2);ge=num%10;display_num1(ge,1);}//四位数据显示函数void display_num4_1(uint num){uint qian;uint bai;uint shi;uint ge;display_num1(10,4);bai=num%1000;bai=bai/100;if(qian==10&&bai==0) bai=10;display_num1(bai,3);shi=num%100;shi=shi/10;if(qian==10&&bai==10&&shi==0) shi=10;display_num1(shi,2);ge=num%10;display_num1(ge,1);}void delay(uint time){uint i;for(i=0;idisplay_num4_1(stop_count);}void delay1(uint num){uint i;for(i=0;idisplay_num4(set_count);}void time01_initiat(){TMOD=0X11; //计数器0和定时器1TL0=0X33;TH0=0XFE;//计数器0赋初值 0.5msTH1=0X4C;TL1=0X00;//定时器1赋初值 50msEA=1;PT0=1;ET0=1;ET1=1;TR0=0;TR1=0;IT0=1;EX0=0;}void key_precess(){if(key1==0&&key2==1&&key3==1) //判断系统的运行模式,如果KEY1键 按下//且state_flag为1则系统处于运行模式,如果state__flag为0则为设置模式{while(key1==0);state_flag=~state_flag;if(state_flag==1){EX0=1;TR1=1;TR0=1;en =0;en_1 =0;en_2 =0;un =0;wide=150;//wide = set_count;}}if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2为按键加{//while(key2==0);delay1(20);set_count+=1;if(set_count>300) set_count=100;}if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3为按键减{// while(key3==0);delay1(20);if(set_count>100) set_count-=1;if(set_count==100) set_count=300;}if(state_flag==0) //如果系统处于设置模式,则关闭定时器中断和外部中断,同时初始化部分变量{PWM = 0;EX0=0;TR0=0;TR1=0;run_count=0;stop_count=0;time=0;t1=0;t2=0;display_num4(set_count);}if(state_flag==1) //如果系统处于运行模式则显示电机的实际转速值{display_num4_1(stop_count);}}void pid(void) //PID 计算输出量{en=set_count-stop_count;un=1.7*en-0.03*en_1+0.002*en_2;//计算输出量if(un > 400)un = 400;if(un <-400)un = -400;en_2=en_1; //更新误差en_1=en;wide = wide + un/4; //计算wide,用于调节PWM的占空比,计算周期为100msif(wide>900)wide=900; //防止超限,确保计算饿wide值有效if(wide<10)wide=10;}//外部中断0用于电机转速测量void int0() interrupt 0{EX0=0;run_count++;EX0=1;}//定时器0用于产生PWM ,占空比通过PID计算获得void time0() interrupt 1{TL0=0X9c;TH0=0XFF;//计数器0赋初值 100usTR0=0;if(low_flag==0)t1++;//低电平时间计时t2++;if(t2==1000) //用于确定PWM的周期 ,t2乘以定时器的中断周期即为PWM的周期{PWM=1;t2=0;low_flag=0;}if(t1==wide)//wide的值即为低电平的时间{PWM=0;t1=0;low_flag=1;}TR0=1;}void time1() interrupt 3{TH1=0X3C;TL1=0XBD; //50ms定时TR1=0;time++;if(time==40) //定时2s到,读取到的值run_count即为电机每秒的转速值{stop_count=run_count/2;time=0;run_count=0;pid(); //调用PID算法}TR1=1;} 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
//指定的位上显示 指定的一位数据
void display_num1(uint dat,uchar num1)
P0=xianshi[dat]; //段显
delay1_ms(2);
//四位数据显示函数
qian=num/1000;
if(qian==0)// qian=11;
display_num1(11,4);
bai=num%1000;
bai=bai/100;
if(qian==10&&bai==0) bai=10;
shi=num%100;
shi=shi/10;
if(qian==10&&bai==10&&shi==0) shi=10;
void display_num4_1(uint num)
display_num1(10,4);
void delay(uint time)
for(i=0;idisplay_num4_1(stop_count);}void delay1(uint num){uint i;for(i=0;idisplay_num4(set_count);}void time01_initiat(){TMOD=0X11; //计数器0和定时器1TL0=0X33;TH0=0XFE;//计数器0赋初值 0.5msTH1=0X4C;TL1=0X00;//定时器1赋初值 50msEA=1;PT0=1;ET0=1;ET1=1;TR0=0;TR1=0;IT0=1;EX0=0;}void key_precess(){if(key1==0&&key2==1&&key3==1) //判断系统的运行模式,如果KEY1键 按下//且state_flag为1则系统处于运行模式,如果state__flag为0则为设置模式{while(key1==0);state_flag=~state_flag;if(state_flag==1){EX0=1;TR1=1;TR0=1;en =0;en_1 =0;en_2 =0;un =0;wide=150;//wide = set_count;}}if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2为按键加{//while(key2==0);delay1(20);set_count+=1;if(set_count>300) set_count=100;}if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3为按键减{// while(key3==0);delay1(20);if(set_count>100) set_count-=1;if(set_count==100) set_count=300;}if(state_flag==0) //如果系统处于设置模式,则关闭定时器中断和外部中断,同时初始化部分变量{PWM = 0;EX0=0;TR0=0;TR1=0;run_count=0;stop_count=0;time=0;t1=0;t2=0;display_num4(set_count);}if(state_flag==1) //如果系统处于运行模式则显示电机的实际转速值{display_num4_1(stop_count);}}void pid(void) //PID 计算输出量{en=set_count-stop_count;un=1.7*en-0.03*en_1+0.002*en_2;//计算输出量if(un > 400)un = 400;if(un <-400)un = -400;en_2=en_1; //更新误差en_1=en;wide = wide + un/4; //计算wide,用于调节PWM的占空比,计算周期为100msif(wide>900)wide=900; //防止超限,确保计算饿wide值有效if(wide<10)wide=10;}//外部中断0用于电机转速测量void int0() interrupt 0{EX0=0;run_count++;EX0=1;}//定时器0用于产生PWM ,占空比通过PID计算获得void time0() interrupt 1{TL0=0X9c;TH0=0XFF;//计数器0赋初值 100usTR0=0;if(low_flag==0)t1++;//低电平时间计时t2++;if(t2==1000) //用于确定PWM的周期 ,t2乘以定时器的中断周期即为PWM的周期{PWM=1;t2=0;low_flag=0;}if(t1==wide)//wide的值即为低电平的时间{PWM=0;t1=0;low_flag=1;}TR0=1;}void time1() interrupt 3{TH1=0X3C;TL1=0XBD; //50ms定时TR1=0;time++;if(time==40) //定时2s到,读取到的值run_count即为电机每秒的转速值{stop_count=run_count/2;time=0;run_count=0;pid(); //调用PID算法}TR1=1;} 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
display_num4_1(stop_count);
void delay1(uint num)
for(i=0;idisplay_num4(set_count);}void time01_initiat(){TMOD=0X11; //计数器0和定时器1TL0=0X33;TH0=0XFE;//计数器0赋初值 0.5msTH1=0X4C;TL1=0X00;//定时器1赋初值 50msEA=1;PT0=1;ET0=1;ET1=1;TR0=0;TR1=0;IT0=1;EX0=0;}void key_precess(){if(key1==0&&key2==1&&key3==1) //判断系统的运行模式,如果KEY1键 按下//且state_flag为1则系统处于运行模式,如果state__flag为0则为设置模式{while(key1==0);state_flag=~state_flag;if(state_flag==1){EX0=1;TR1=1;TR0=1;en =0;en_1 =0;en_2 =0;un =0;wide=150;//wide = set_count;}}if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2为按键加{//while(key2==0);delay1(20);set_count+=1;if(set_count>300) set_count=100;}if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3为按键减{// while(key3==0);delay1(20);if(set_count>100) set_count-=1;if(set_count==100) set_count=300;}if(state_flag==0) //如果系统处于设置模式,则关闭定时器中断和外部中断,同时初始化部分变量{PWM = 0;EX0=0;TR0=0;TR1=0;run_count=0;stop_count=0;time=0;t1=0;t2=0;display_num4(set_count);}if(state_flag==1) //如果系统处于运行模式则显示电机的实际转速值{display_num4_1(stop_count);}}void pid(void) //PID 计算输出量{en=set_count-stop_count;un=1.7*en-0.03*en_1+0.002*en_2;//计算输出量if(un > 400)un = 400;if(un <-400)un = -400;en_2=en_1; //更新误差en_1=en;wide = wide + un/4; //计算wide,用于调节PWM的占空比,计算周期为100msif(wide>900)wide=900; //防止超限,确保计算饿wide值有效if(wide<10)wide=10;}//外部中断0用于电机转速测量void int0() interrupt 0{EX0=0;run_count++;EX0=1;}//定时器0用于产生PWM ,占空比通过PID计算获得void time0() interrupt 1{TL0=0X9c;TH0=0XFF;//计数器0赋初值 100usTR0=0;if(low_flag==0)t1++;//低电平时间计时t2++;if(t2==1000) //用于确定PWM的周期 ,t2乘以定时器的中断周期即为PWM的周期{PWM=1;t2=0;low_flag=0;}if(t1==wide)//wide的值即为低电平的时间{PWM=0;t1=0;low_flag=1;}TR0=1;}void time1() interrupt 3{TH1=0X3C;TL1=0XBD; //50ms定时TR1=0;time++;if(time==40) //定时2s到,读取到的值run_count即为电机每秒的转速值{stop_count=run_count/2;time=0;run_count=0;pid(); //调用PID算法}TR1=1;} 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
display_num4(set_count);
void time01_initiat()
TMOD=0X11; //计数器0和定时器1
TL0=0X33;
TH0=0XFE;//计数器0赋初值 0.5ms
TH1=0X4C;
TL1=0X00;//定时器1赋初值 50ms
EA=1;
PT0=1;
ET0=1;
ET1=1;
TR0=0;
TR1=0;
IT0=1;
EX0=0;
void key_precess()
if(key1==0&&key2==1&&key3==1) //判断系统的运行模式,如果KEY1键 按下
//且state_flag为1则系统处于运行模式,如果state__flag为0则为设置模式
while(key1==0);
state_flag=~state_flag;
if(state_flag==1)
EX0=1;
TR1=1;
TR0=1;
en =0;
en_1 =0;
en_2 =0;
un =0;
wide=150;
//wide = set_count;
if(key1==1&&key2==0&&key3==1&&state_flag==0) //KEY2为按键加
//while(key2==0);
delay1(20);
set_count+=1;
if(set_count>300) set_count=100;
if(key1==1&&key2==1&&key3==0&&state_flag==0) //KEY3为按键减
// while(key3==0);
if(set_count>100) set_count-=1;
if(set_count==100) set_count=300;
if(state_flag==0) //如果系统处于设置模式,则关闭定时器中断和外部中断,同时初始化部分变量
PWM = 0;
run_count=0;
stop_count=0;
time=0;
t1=0;
t2=0;
if(state_flag==1) //如果系统处于运行模式则显示电机的实际转速值
void pid(void) //PID 计算输出量
en=set_count-stop_count;
un=1.7*en-0.03*en_1+0.002*en_2;//计算输出量
if(un > 400)un = 400;
if(un <-400)un = -400;
en_2=en_1; //更新误差
en_1=en;
wide = wide + un/4; //计算wide,用于调节PWM的占空比,计算周期为100ms
if(wide>900)wide=900; //防止超限,确保计算饿wide值有效
if(wide<10)wide=10;
//外部中断0用于电机转速测量
void int0() interrupt 0
run_count++;
//定时器0用于产生PWM ,占空比通过PID计算获得
void time0() interrupt 1
TL0=0X9c;
TH0=0XFF;//计数器0赋初值 100us
if(low_flag==0)t1++;//低电平时间计时
t2++;
if(t2==1000) //用于确定PWM的周期 ,t2乘以定时器的中断周期即为PWM的周期
PWM=1;
low_flag=0;
if(t1==wide)//wide的值即为低电平的时间
PWM=0;
low_flag=1;
void time1() interrupt 3
TH1=0X3C;
TL1=0XBD; //50ms定时
time++;
if(time==40) //定时2s到,读取到的值run_count即为电机每秒的转速值
stop_count=run_count/2;
pid(); //调用PID算法
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。