欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
用51單片機實現紅外遙控風扇程序 舵機搖頭
[打印本頁]
作者:
是鯨落不是鯊掉
時間:
2019-5-20 21:35
標題:
用51單片機實現紅外遙控風扇程序 舵機搖頭
舵機信號線連接 P3.5
電機連接 uln2003 A腳
ch- 停止舵機轉動
ch 開始舵機轉動
prev 停止風扇轉動
next 開始風扇轉動
- 風扇減速
+ 風扇加速
具體代碼見附件
一、元件清單
1、9G舵機 1個
2、直流電機 1個
3、電機支架 1組
4、51主板 1個
5、杜邦線 若干
6、螺絲、螺帽 若干
二、軟件
1、Keil4軟件
2、程序燒錄軟件
三、硬件安裝
1、舵機
2、直流電機
四、硬件接線
1.舵機接線說明
舵機
51開發板
紅色
VCC
棕色
GND
橙色
P35
2.直流電機接線說明
一個腳接步進電機模塊的+,另一個腳接步進電機模塊的A 。
3.實物接線圖
3.1602直插即可。
五、實驗操作說明
用紅外遙控器對準紅外接收頭,操作即可。
單片機源程序如下:
/*******************************************************************************
* 實驗名 : 1602顯示紅外線值實驗
* 使用的IO : 電機用P1口,鍵盤使用P3.0、P3.1、P3.2、P3.3
* 實驗效果 : LCD1602顯示出讀取到的紅外線的值
* 注意 :
*******************************************************************************/
#include<reg51.h>
#include"lcd.h"
#include <stdio.h>
//#include "delay.h"
sfr T2CON = 0xC8; //timer2 control register
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2 = 0xCC;
sfr TH2 = 0xCD;
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 12000000L //System frequency
#define BAUD 9600 //UART baudrate
/*Define UART parity mode*/
#define NONE_PARITY 0 //None parity
#define ODD_PARITY 1 //Odd parity
#define EVEN_PARITY 2 //Even parity
#define MARK_PARITY 3 //Mark parity
#define SPACE_PARITY 4 //Space parity
#define PARITYBIT NONE_PARITY //Testing even parity
sbit bit9 = P2^2; //P2.2 show UART data bit9
bit busy;
sbit Sevro_moto_pwm = P3^5; //接舵機信號端輸入PWM信號調節速度
sbit FanPin=P1^0;
unsigned int pwm_val_left = 0;//變量定義
unsigned char push_val_left =14;//舵機歸中,產生約,1.5MS 信號
unsigned int timer=0; //延時基準變量
unsigned int Servo_Ctr=0;
unsigned int pwm_val_Fan=0;
unsigned char Fan_speed=199;
int flag=0;
sbit IRIN=P3^2;
unsigned char code CDIS1[13]={" Red Control "};
unsigned char code CDIS2[13]={" IR-CODE:--H "};
unsigned char code Test_OK[2]={"OK"};
unsigned char IrValue[6];
unsigned char Time;
unsigned char IrOK=0;
/*--------------------------------------------------------------
函數聲明
--------------------------------------------------------------*/
void InitUART(void);
char putchar(char c);
void IrInit();
void DelayMs(unsigned int );
void SendString(char *s);
void SendData(BYTE dat);
void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time);
void pwm_Servomoto(void);
void test_servo(void);
void Motor_Ctr(void);
void Pwm_Motor(void);
/*******************************************************************************
* 函數名 : main
* 函數功能 : 主函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void main()
{
unsigned char i;
//串口初始化
// printf("\r\n\n\r\n");
TMOD=0X11;
TH1=(65536-100)/256; //100US定時
TL1=(65536-100)%256;
TH0=0;
TL0=0;
TR1= 1;
ET1= 1;
ET0= 1;
EA = 1;
IrInit();
LcdInit();
InitUART();
LcdWriteCom(0x80);
for(i=0;i<13;i++)
{
LcdWriteData(CDIS1[i]);
}
LcdWriteCom(0x80+0x40);
for(i=0;i<13;i++)
{
LcdWriteData(CDIS2[i]);
}
while(1)
{
test_servo();
IrValue[4]=IrValue[2]>>4; //高位
IrValue[5]=IrValue[2]&0x0f; //低位
if(IrValue[4]>9)
{
LcdWriteCom(0xc0+0x09); //設置顯示位置
LcdWriteData(0x37+IrValue[4]); //將數值轉換為該顯示的ASCII碼
}
else
{
LcdWriteCom(0xc0+0x09);
LcdWriteData(IrValue[4]+0x30); //將數值轉換為該顯示的ASCII碼
}
if(IrValue[5]>9)
{
LcdWriteCom(0xc0+0x0a);
LcdWriteData(IrValue[5]+0x37); //將數值轉換為該顯示的ASCII碼
}
else
{
LcdWriteCom(0xc0+0x0a);
LcdWriteData(IrValue[5]+0x30); //將數值轉換為該顯示的ASCII碼
}
DelayMs(50);
// printf("\r\n SZ-51 UART printftest OK if you see these words! c%c%", IrValue[2], IrValue[3]);
if(IrOK==1) //如果處理好后進行紅外處理
{
// printf("\r\n SZ-51 UART printftest OK if you see these words!");
SendString(Test_OK);
if(IrValue[4]>9)
{
LcdWriteCom(0x80+0x0d); //設置顯示位置
LcdWriteData(0x37+IrValue[4]); //將數值轉換為該顯示的ASCII碼
}
else
{
LcdWriteCom(0x80+0x0d);
LcdWriteData(IrValue[4]+0x30); //將數值轉換為該顯示的ASCII碼
}
if(IrValue[5]>9)
{
LcdWriteCom(0x80+0x0e);
LcdWriteData(IrValue[5]+0x37); //將數值轉換為該顯示的ASCII碼
}
else
{
LcdWriteCom(0x80+0x0e);
LcdWriteData(IrValue[5]+0x30); //將數值轉換為該顯示的ASCII碼
}
switch(IrValue[2])
{
case 0x18:
LcdWriteCom(0x80+0x0f);
LcdWriteData(CDIS1[3]); //將數值轉換為該顯示的ASCII碼
break;
case 0x52:
LcdWriteCom(0x80+0x0f);
LcdWriteData(CDIS1[2]); //將數值轉換為該顯示的ASCII碼
break;
default:break;
}
IrOK=0;
}
else
{
// printf("\r\n SZ-51 UART printftest OK if you see these words!");
}
DelayMs(50);
}
}
/*******************************************************************************
* 函數名 : DelayMs()
* 函數功能 : 延時
* 輸入 : x
* 輸出 : 無
*******************************************************************************/
void DelayMs(unsigned int x) //0.14ms誤差 0us
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++)
{}
}
}
/*******************************************************************************
* 函數名 : IrInit()
* 函數功能 : 初始化紅外線接收
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿觸發
EX0=1;//打開中斷0允許
EA=1; //打開總中斷
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函數名 : ReadIr()
* 函數功能 : 讀取紅外數值的中斷函數
* 輸入 : 無
* 輸出 : 無
*******************************************************************************/
void ReadIr() interrupt 0
{
unsigned char j,k;
unsigned int err;
Time=0;
DelayMs(70);
if(IRIN==0) //確認是否真的接收到正確的信號
{
err=1000; //1000*10us=10ms,超過說明接收到錯誤的信號
/*當兩個條件都為真是循環,如果有一個條件為假的時候跳出循環,免得程序出錯的時
侯,程序死在這里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低電平過去
{
DelayMs(1);
err--;
}
if(IRIN==1) //如果正確等到9ms低電平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高電平過去
{
DelayMs(1);
err--;
}
for(k=0;k<4;k++) //共有4組數據
{
for(j=0;j<8;j++) //接收一組數據
{
err=60;
while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
// while (!IRIN)
{
DelayMs(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //計算高電平的時間長度。
{
DelayMs(1);//0.14ms
Time++;
err--;
if(Time>30)
{
EX0=1;
return;
}
}
IrValue[k]>>=1; //k表示第幾組數據
if(Time>=8) //如果高電平出現大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完時間要重新賦值
}
}
}
if(IrValue[2]==~IrValue[3])
{
IrOK=1;
DelayMs(5);
return;
}
else
{
IrOK=0;
}
}
}
/*--------------------------------------------------------------
串口初始化
--------------------------------------------------------------*/
void InitUART(void)
{
#if (PARITYBIT == NONE_PARITY)
SCON = 0x50; //8-bit variable UART
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
SCON = 0xda; //9-bit variable UART, parity bit initial to 1
#elif (PARITYBIT == SPACE_PARITY)
SCON = 0xd2; //9-bit variable UART, parity bit initial to 0
#endif
TL2 = RCAP2L = (65536-(FOSC/32/BAUD)); //Set auto-reload vaule
TH2 = RCAP2H = (65536-(FOSC/32/BAUD)) >> 8;
T2CON = 0x34; //Timer2 start run
ES = 1; //Enable UART interrupt
EA = 1;
}
/*--------------------------------------------------------------
printf調用的底層發送一個字節函數
--------------------------------------------------------------*/
char putchar(char c)
{
SBUF = c;
while(!TI);
TI = 0;
return c;
}
/*----------------------------
UART interrupt service routine
----------------------------*/
void Uart_Isr() interrupt 4 using 1
{
if (RI)
{
RI = 0; //Clear receive interrupt flag
P0 = SBUF; //P0 show UART data
bit9 = RB8; //P2.2 show parity bit
}
if (TI)
{
TI = 0; //Clear transmit interrupt flag
busy = 0; //Clear transmit busy flag
}
}
/*----------------------------
Send a byte data to UART
Input: dat (data to be sent)
Output:None
----------------------------*/
void SendData(BYTE dat)
{
while (busy); //Wait for the completion of the previous data is sent
ACC = dat; //Calculate the even parity bit P (PSW.0)
if (P) //Set the parity bit according to P
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 0; //Set parity bit to 0
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 1; //Set parity bit to 1
#endif
}
else
{
#if (PARITYBIT == ODD_PARITY)
TB8 = 1; //Set parity bit to 1
#elif (PARITYBIT == EVEN_PARITY)
TB8 = 0; //Set parity bit to 0
#endif
}
busy = 1;
SBUF = ACC; //Send data to UART buffer
}
/*----------------------------
Send a string to UART
Input: s (address of string)
Output:None
----------------------------*/
void SendString(char *s)
{
while (*s) //Check the end of the string
{
SendData(*s++); //Send current char and increment string ptr
}
}
/************************************************************************/
/* PWM調制舵機電機轉速 */
/************************************************************************/
/* 舵機電機調速 */
/*調節push_val_left的值改變舵機電機轉速,占空比 */
void pwm_Servomoto(void)
{
if(pwm_val_left<=push_val_left)
Sevro_moto_pwm=1;
else
Sevro_moto_pwm=0;
if(pwm_val_left>=200)
pwm_val_left=0;
}
void Pwm_Motor(void)
{
if(flag==1)
{
FanPin=0;
}
else
{
if(pwm_val_Fan<=Fan_speed)
FanPin=1;
else
FanPin=0;
if(pwm_val_Fan>=200)
pwm_val_Fan=0;
}
}
/***************************************************/
///*TIMER1中斷服務子函數產生PWM信號*/
void time1()interrupt 3 using 2
{
TH1=(65536-100)/256; //100US定時
TL1=(65536-100)%256;
timer++; //定時器100US為準。在這個基礎上延時
pwm_val_left++;
pwm_val_Fan++;
pwm_Servomoto();
Pwm_Motor();
}
void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time)
{
push_val_left=5+angle*20/180; //舵機向左轉90度
timer=0;
while(timer<=Servo_time); //延時400MS讓舵機轉到其位置 4000
}
void test_servo(void)
{
int pos;
for(pos=0;pos<180;pos+=3)
{
Motor_Ctr();
// pwm_Fan_speed();
while(Servo_Ctr==0)
{
Motor_Ctr();
}
pwm_Servomoto_angle(pos,100) ;
DelayMs(10);
}
for(pos = 180; pos>=0; pos-=3) // goes from 180 degrees to 0 degrees
{
Motor_Ctr();
while(Servo_Ctr==0)
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
紅外遙控風扇-lcd1602顯示鍵值.zip
(2.51 MB, 下載次數: 145)
2019-5-20 21:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
iot愛好者
時間:
2020-4-22 12:42
我是一個非本專業的學生,出于好奇心和興趣,也想嘗試這個小設計,在那個寶上買了元器件,雖然仔細查閱了資料,但還是沒能做出來,咨詢那個寶客服,它們的售后服務很差,沒法兒解決我的問題,一方面我不甘心放棄,另一方面實在沒找到突破口,就在山重水復疑無路之時,在網上找到樓主這篇帖子,尤其其中有關鍵思路的備注,還有一些問題的解決辦法,我又重新燃起了希望,最終做了出來,能遇到這樣的平臺,真的太幸運了。
作者:
iot愛好者
時間:
2020-4-22 19:07
請問樓主在軟件上仿真模擬過嗎?
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1