proteus和程序一起打包,送給有需要的小伙伴
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (50.16 KB, 下載次數(shù): 63)
下載附件
2020-11-23 16:24 上傳
捕獲.JPG (159.96 KB, 下載次數(shù): 38)
下載附件
2020-11-23 09:20 上傳
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- typedef unsigned long uint32;
- sbit PWM01=P1^4;
- sbit PWM02=P1^5; //電機1
- sbit PWM11=P1^6;
- sbit PWM12=P1^7; //電機2
- sbit PWM21=P2^2;
- sbit PWM22=P2^3; //電機3
- sbit PWM31=P3^6;
- sbit PWM32=P3^7; //電機4
- sbit ADDRC = P1^0;
- sbit ADDRB = P1^1;
- sbit ADDRA = P1^2;//控制138譯碼器的三個引腳
- uint8 AD_value0 = 0;//AD值
- uint8 AD_value1 = 0;//AD值
- uint8 AD_value2 = 0;//AD值
- uint8 AD_value3 = 0;//AD值
- uint8 Top = 255;
- uint8 Low = 0;
- uint8 between0 = 127;
- uint8 between1 = 128;
- sbit I2C_SDA = P2^1;
- sbit I2C_SCL = P2^0;//I2C通信的兩個引腳
- bit flag_300ms = 0;//300ms時間標志位
- uint8 T0RH = 0;//定時器高8位初值
- uint8 T0RL = 0;//定時器低8位初值
- //uint8 AD_value = 0;//AD值
- uint8 code led_char[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//LED段碼
- void config_timer0(uint8 ms);
- uint8 get_ADC_vaule(uint8 chn);
- void motor_deal0();
- void motor_deal1();
- void motor_deal2();
- void motor_deal3();
- void main()
- {
- config_timer0(1);//初始化通用定時器0,定時1ms
- while(1)
- {
- if(flag_300ms == 1) //判斷300ms時間是否到了
- {
- flag_300ms = 0;//清除標志位
- AD_value0 = get_ADC_vaule(0);//讀取通道0的AD值
- AD_value1 = get_ADC_vaule(1);//讀取通道0的AD值
- AD_value2 = get_ADC_vaule(2);//讀取通道0的AD值
- AD_value3 = get_ADC_vaule(3);//讀取通道0的AD值
-
- }
- motor_deal0();
- motor_deal1();
- motor_deal2();
- motor_deal3();
- }
- }
- void motor_deal0()
- {
- if(AD_value0 == between0 || AD_value0 == between1) //stop
- {
- PWM01=1;
- PWM02=1;
- }
- else if(AD_value0>=Low && AD_value0<between0) //正
- {
- PWM01=0;
- PWM02=1;
- }
- else //反
- {
- PWM01=1;
- PWM02=0;
- }
- }
- void motor_deal1()
- {
- if(AD_value1 == between0 || AD_value1 == between1) //stop
- {
- PWM11=1;
- PWM12=1;
- }
- else if(AD_value1>=Low && AD_value1<between0) //正
- {
- PWM11=0;
- PWM12=1;
- }
- else //反
- {
- PWM11=1;
- PWM12=0;
- }
- }
- void motor_deal2()
- {
- if(AD_value2 == between0 || AD_value2 == between1) //stop
- {
- PWM21=1;
- PWM22=1;
- }
- else if(AD_value2>=Low && AD_value2<between0) //正
- {
- PWM21=0;
- PWM22=1;
- }
- else //反
- {
- PWM21=1;
- PWM22=0;
- }
- }
- void motor_deal3()
- {
- if(AD_value3 == between0 || AD_value3 == between1) //stop
- {
- PWM31=1;
- PWM32=1;
- }
- else if(AD_value3>=Low && AD_value3<between0) //正
- {
- PWM31=0;
- PWM32=1;
- }
- else //反
- {
- PWM31=1;
- PWM32=0;
- }
- }
- void I2C_delay()//I2C延時函數(shù)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- void I2C_start()//I2C起始信號
- {
- I2C_SDA = 1;
- I2C_SCL = 1;
- I2C_delay();
- I2C_SDA = 0;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- }
- void I2C_stop()//I2C停止信號
- {
- I2C_SDA = 0;
- I2C_SCL = 0;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SDA = 1;
- I2C_delay();
- }
- bit I2C_write(uint8 dat)//I2C寫一個字節(jié)
- {
- bit ack = 0;
- uint8 mask = 0;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- if((mask&dat) == 0)
- I2C_SDA = 0;
- else
- I2C_SDA = 1;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- }
- I2C_SDA = 1;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- ack = I2C_SDA;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
-
- return (~ack);
- }
- uint8 I2C_read_ACK()//I2C讀一個字節(jié),并發(fā)送應答位
- {
- uint8 dat = 0;
- uint8 mask = 0;
- I2C_SDA = 1;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- if(I2C_SDA == 0)
- dat = dat & (~mask);
- else
- dat = dat | mask;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- }
- I2C_SDA = 0;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- return dat;
- }
- uint8 I2C_read_NACK()//I2C讀一個字節(jié),并發(fā)送非應答位
- {
- uint8 dat = 0;
- uint8 mask = 0;
- I2C_SDA = 1;
- for(mask=0x80;mask!=0;mask>>=1)
- {
- if(I2C_SDA == 0)
- dat = dat & (~mask);
- else
- dat = dat | mask;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- }
- I2C_SDA = 1;
- I2C_delay();
- I2C_SCL = 1;
- I2C_delay();
- I2C_SCL = 0;
- I2C_delay();
- return dat;
- }
- uint8 get_ADC_vaule(uint8 chn)//獲取AD值
- {
- uint8 value = 0;
- I2C_start();//I2C起始信號
- if(!I2C_write(0X90))//寫入PCF8591地址及讀寫選擇位為寫
- {
- I2C_stop();
- return 0;
- }
- // I2C_write(0X40 | chn);//寫入PCF8591通道0
- I2C_write(0x00 | chn);//寫入PCF8591通道0
- I2C_start();//I2C起始信號
- I2C_write(0x48<<1 | 0x01);
- I2C_read_ACK();//提供轉換所需的時鐘信號
- value = I2C_read_NACK();//讀取上一次轉換的結果
- I2C_stop();//I2C結束信號
- return value;
- }
- void config_timer0(uint8 ms)//配置定時器0的通用函數(shù)
- {
- uint32 temp =0 ;
- temp = 11059200/12;
- temp = (temp * ms)/1000;
- temp = 65536 - (temp + 12);
- T0RH = (uint8)(temp >> 8);
- T0RL = (uint8)temp;
- TMOD = TMOD & 0XF0;
- TMOD = TMOD | 0X01;
- TH0 = T0RH;
- TL0 = T0RL;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
電位器控制電機正反轉四通道ok.zip
(130.46 KB, 下載次數(shù): 35)
2020-11-23 09:22 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|