㈠ 傾角感測器測出的角度怎麼用單片機去控制步進電機轉幾步使平台平衡
您做的貌似是一個電子科技大賽的題目。就像瞄準器一樣。你可以引進反饋控制,當傾角感測器有信號時,誤差就來了,這時候馬上控制電機轉,全速轉,同時繼續看傾角感測器傳來的信號和參考值之間的誤差,只要還有誤差就繼續轉。當誤差為零的時候,馬上停下來。你也可以設計一個程序當誤差很小時就先停下來,讓電機的慣性把系統平衡下來。這就是比例調節和積分調節相結合起來用。但不要輕易用微分,會使系統飄搖。
㈡ 傾角感測器與單片機連接有必要用A/D轉換器嗎
根據你的精度要求進行選擇,你如果需要平台保持水平,可以採用SAT100T。該感測器具有x,y雙軸傾角感測器。內部具有AD轉換,然後SPI串列輸出;同時內部還具有溫度感測器,可以進行溫度補償。如果需要高精度,可以採用外部高精度AD轉換。
我現在就是用這個感測器做的高精度垂直轉動平台。
㈢ 急求!用單片機測傾角的程序(最好用匯編語言,C語言也可以)
你的問題問得太粗了,沒一點實際設計目的,只有拿我做的實例給你參考了。下面程序是我完成07年電子設計競賽中小車走蹺蹺板平衡問題的實例,正是用的水銀開關解決傾角判斷測量問題,其中包含有一段水銀開關測傾角的子程序(標有注釋自己讀吧),供你參考。
因為程序涉及我的版權,只好刪掉一些無關緊要的地方,所以不能讓你編譯成功,僅供你閱讀,請諒解!
更多電子問題請關注我!_ceo竭誠為您解答!
NOWSTEP EQU 28H
BEGINSPEED EQU 29H
DFSPD EQU 2AH
NOWANGLE EQU 2BH
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INTR_0
ORG 0013H
LJMP INTR_1
ORG 。。。。。
MAIN: DJNZ R0,$
MOV SP,#70H
MOV P1,#0FFH
MOV P3,#0FFH
MOV BEGINSPEED,#80D ;起始速度
STEP_TABLE:MOV 20H,#11111011B ;1
MOV 21H,#11111001B ; 2
MOV 22H,#11111101B ; 3
MOV 23H,#11110101B ; 4
MOV 24H,#11110111B ; 5
MOV 25H,#11110110B ; 6
MOV 26H,#。。。。。。 ; 7
MOV 27H,#11111010B ; 8
MOV R0,#20H
MOV NOWSTEP,R0
;yyf07year
NOP
SPEED_UP1:
;步數=256*(B-1)+A
MOV A,#70D
SPU1: MOV B,#32D
SPU2: LCALL RUNZ
LCALL DELAY_UP
DJNZ B,SPU2
DJNZ ACC,SPU1
NEAR_CENTRE:
MOV A,#70
NR1: MOV B,#12
NR2: MOV DFSPD,#7
LCALL RUNZ
LCALL DELAY_DF
DJNZ B,NR2
DJNZ ACC,NR1
MOV A,#40
NR3: MOV B,#6
NR4: MOV DFSPD,#20
LCALL RUNZ
LCALL DELAY_DF
;yyf07year
DJNZ B,NR4
DJNZ ACC,NR3
MOV A,#30
NR5: MOV B,#3
NR6: MOV DFSPD,#50
LCALL RUNZ
LCALL DELAY_DF
DJNZ B,NR6
DJNZ ACC,NR5
CHECK_BALANCE: ;水銀開關檢測角度
MOV P1,#0FFH
MOV A,P1
JNB ACC.0,FAST_BACK ;傾斜角度1
JNB ACC.1,FAST_BACK ;傾斜角度2
JB ACC.2,FAST_BACK ;傾斜角度3
JB ACC.3,FAST_BACK ;傾斜角度4
MOV DFSPD,#165
LCALL RUNZ
LCALL DELAY_DF
JMP CHECK_BALANCE
FAST_BACK:
MOV DFSPD,#80
MOV A,#6
FB1:LCALL RUNF
LCALL DELAY_DF
DJNZ ACC,FB1
MOV DFSPD,#18
MOV A,#12
FB2:LCALL RUNF
LCALL DELAY_DF
DJNZ ACC,FB2
MOV DFSPD,#7
MOV A,#75
FB3:LCALL RUNF
LCALL DELAY_DF
DJNZ ACC,FB3
MOV DFSPD,#90
;yyf07year
MOV A,#13
FB4:LCALL RUNF
LCALL DELAY_DF
DJNZ ACC,FB4
;..............
JMP KEEP_BALANCE
KEEP_BALANCE:
LCALL DELAY_SEC
LCALL DELAY_SEC
MOV A,P1
JB ACC.0,CHECK_BALANCE
JB ACC.3,GOBACK
JMP ALARM
MOV DFSPD,#160
LCALL DELAY_DF
GOBACK:MOV A,#255
MOV DFSPD,#20
LCALL RUNF
DJNZ ACC,GOBACK
JMP CHECK_BALANCE
ALARM: CLR P3.0
CLR P3.7
CLR P3.1
NOP
。。。。。
NOP
NOP
SETB P3.1
SETB P3.7
DELAY_10SEC:
MOV R0,#100
DLS51: MOV R1,#200
DLS52: MOV R2,#250
DJNZ R2,$
DJNZ R1,DLS52
DJNZ R0,DLS51
SETB P3.0
CLR P3.1
NOP
SETB P3.1
TOPOINTB: MOV A,#70
TB1: MOV B,。。。。。。。。
TB2: MOV DFSPD,。。。
LCALL RUNZ
LCALL DELAY_DF
DJNZ B,TB2
DJNZ ACC,TB1
LCALL DELAY_SEC
LCALL DELAY_SEC
LCALL DELAY_SEC
LCALL DELAY_SEC
LCALL DELAY_SEC
TOPOINTA: MOV A,#70
TA1: MOV B,。。。。。。。。。
TA2: MOV DFSPD,#8
LCALL RUNF
LCALL DELAY_DF
DJNZ B,TA2
DJNZ ACC,TA1
CLR P3.1
NOP
SETB P3.1
KSTAY: NOP
JMP KSTAY
TOCHECK_BALANCE:
LJMP CHECK_BALANCE
RUNZ: PUSH 00H
MOV R0,NOWSTEP ;正向轉動;NOWSTEP為上次步進後,當前步位
INC R0
CJNE R0,#28H,RTOZ
MOV R0,。。。。
RTOZ: MOV P2,@R0
MOV NOWSTEP,R0
POP 00H
RET
RUNF: PUSH 00H
MOV R0,NOWSTEP ;反向轉動;NOWSTEP為上次步進後,當前步位
DEC R0
CJNE R0,#1FH,RTOF
MOV R0,#27H
RTOF: MOV P2,@R0
MOV NOWSTEP,R0
POP 00H
RET
;yyf07year
DELAY_UP: PUSH ACC
PUSH B
PUSH 00H ;BEGINSPPED為起始速率寄存器
PUSH 01H
PUSH 02H
MOV R0,BEGINSPEED
CJNE R0,#3,TOU1
JMP TOU2
TOU1: DEC R0
MOV BEGINSPEED,R0
TOU2: MOV R1,BEGINSPEED
DLU2: MOV R2,#100
DLU3: DJNZ R2,DLU3
DJNZ R1,DLU2
POP 02H
POP 01H
POP 00H
POP B
POP ACC
RET
DELAY_DF: ;自定義速度
PUSH 00H ;DFSPD為自定義速率寄存器
PUSH 01H
PUSH 02H
MOV R1,DFSPD
DLD2: MOV R2,#100D
DLD3: DJNZ R2,DLD3
DJNZ R1,DLD2
POP 02H
POP 01H
。。。。
RET
DELAY_SEC: PUSH 00H
PUSH 01H
PUSH 02H
MOV R0,#250
DLS1: MOV R1,#200
DLS2: MOV R2,#10
DJNZ R2,$
DJNZ R1,DLS2
DJNZ R0,DLS1
POP 02H
POP 01H
POP 00H
RET
INTR_0: NOP
;yyf07year
INTR_1: NOP
toend: nop
END
更多電子問題請關注我!_ceo竭誠為您解答!
㈣ 想用單片機和傾角感測器,實現橫傾角度和縱傾角度在LCD上顯示,求大神教教
SX-QXJ2型數顯傾角儀OLED顯示屏,內嵌微處理器DSP程序化處理,既可以直接顯示角度數字又可以連接控制系統輸出RS485數字信號。
㈤ 求用51單片機控制 MMA7361 傾角感測器 的C 語言代碼。最好有注釋
7361程序~
㈥ ADXL345傾角感測器和STC89C52單片機如何接線(有原理圖和管腳定義說明)
需要幫你做嗎
我做單片機的
㈦ 求51單片機控制 傾角感測器SCA60的匯編語言,用來做蹺蹺板小車的。相近能提供參考也行!!
附件一:
總程序源程序
;**************說明***************************************************
;** P1.1為左邊感測器輸入; P1.0為右邊感測器輸入 **
;** P1.6檢測車身前傾; P1.7檢測車身後傾 **
;** 秒錶埠定義: **
;** A(P2.1):啟動/停止計時; B(P2.3):各段記錄時間回放; **
;** C(P2.3):分段計時標志/清零(停止狀態下) **
;*********************************************************************
ORG 0000H
;************主程序***************************************************
JBGN:
LCALL TC ;停車
LCALL CSZT ;設置初始狀態
;*************車身平衡檢查******************
CGQ:
LCALL QJ ;前進3S,第一次不檢查A端黑線
LCALL QL ;秒錶置零
LCALL QDJS ;啟動秒錶
LCALL DELAY1S
LCALL DELAY1S
LCALL DELAY1S
LCALL TC ;停車
LCALL DELAY30 ;消除擺動
JXPD:JNB P1.6,MBXS ;如果前傾(到達C點附近),轉秒錶顯示AC段行車時間
LCALL QJ ;前進
LCALL DELAY
LCALL TC
LCALL DELAY30 ;消除擺動
LJMP JXPD ;繼續判斷是否到達C點附近
MBXS:
LCALL QDJS
LCALL CDSL5 ;停車5S,讀取AC段行車時間
LCALL QL ;秒錶清零
LCALL QDJS ;啟動計時,記錄平衡調整時間
CGQJC:
JNB P1.6,JBZHT ;如果前傾,轉慢速後退
JNB P1.7, JBWW ;如果後仰,轉慢速前進
LCALL DELAY1S ;延時判斷是否真正平衡
LCALL DELAY1S
LCALL DELAY1S
JNB P1.6,CGQJC ;如果前傾,轉繼續調整平衡
JNB P1.7,CGQJC ;如果後仰,轉繼續調整平衡
LCALL TC ;停車
LCALL QDJS ;停止計時,顯示平衡調整所用時間
CLR P2.5 ;蜂鳴器鳴叫
CLR P2.4 ;七彩燈亮
LCALL CDSL5 ;轉到車燈閃亮5次,表示5S時間
LCALL CSZT
LJMP CDB ;轉C到B程序前進
;***********轉長跳***********
JBZHT:
LJMP JBTPH
JBWW:
LJMP JBWWW
;***********調整平衡*********
JBTPH:
LCALL DELAY30 ;消除感測器擺動
JBTP: LCALL HT
lcall delay
LCALL TC
LCALL DELAYTC ;消除感測器擺動
JNB P1.6,JBTP
LJMP CGQJC
JBWWW:
LCALL DELAY30
JBWG:LCALL QJ
LCALL DELAY
LCALL TC
LCALL DELAYTC ;消除感測器擺動
JNB P1.7,JBWG
LJMP CGQJC
;*********從C點到B端程序**********
CDB:
LCALL QL ;秒錶置零
LCALL QDJS
LCALL QJ
DT: JB P1.0, DT ;如果右邊遇到黑線,則檢查左邊(順序執行),否則繼續檢查左邊
JB P1.1, DT
LCALL TC
LCALL QDJS ;停止計時,顯示從C到B的時間
LCALL CDSL5 ;延時5S
LCALL HT ;停車5S時間到,轉後退返回
LCALL QL
LCALL QDJS
LCALL DELAY1S
LCALL DELAY1S
LCALL DELAY1S
DDTT:JB P1.0, DDTT ;如果右邊遇到黑線,則檢查左邊(順序執行),否則繼續檢查左邊
JB P1.1, DDTT
; INC A
; CJNE A,#2H,DDTT ;從B端返回A端時,不用檢測B端黑線
LCALL TC ;已經返回A端,停車
LCALL QDJS ;停止計時,顯示從B返回A所用時間
;************************基本功能與發揮部分的程序介面*************************************
LCALL CDSL5 ;延時5S,等待進入發揮部分程序
LCALL CSZT
CLR P2.4 ;狀態燈亮5S
LCALL DELAY1S
LCALL DELAY1S
CLR P2.5 ;蜂鳴器叫3S
LCALL DELAY1S
LCALL DELAY1S
LCALL DELAY1S
LCALL CSZT ;關狀態燈,進入發揮部分程序
;**********************發揮部分主程序*********************************************
FHBF:
LCALL QJ
QJXHX:
JNB P1.1,JX1 ;若P1.1為0(黑線),則繼續查詢P1.0 (左邊遇到黑線,則檢查右邊的狀態)
JNB P1.0,JX2 ;若P1.0為0(黑線),則繼續查詢P1.1 (右邊遇到黑線,則檢查左邊的狀態)
LJMP QJXHX
JX1:
JNB P1.0,PHCL
LJMP CZZW ;若P1.0也為黑線,則平衡處理,否則左轉彎
JX2:
JNB P1.1,PHCL
LJMP CYZW
CZZW:
LCALL ZZW
LCALL ZWSJ ;轉彎時間
LCALL TC
LCALL DELAY30
LCALL QJ
LJMP QJXHX
CYZW:
LCALL YZW
LCALL ZWSJ ;轉彎時間
LCALL TC
LCALL DELAY30
LCALL QJ
LJMP QJXHX
;*****************平衡調整*******************
PHCL:
LCALL QJ ;前進3S
LCALL DELAY1S
LCALL DELAY1S
LCALL DELAY1S
LCALL TC
LCALL DELAY30 ;消除感測器擺動
FHPHTZ:
JNB P1.6,FHZHT ;如果前傾,轉慢速後退
JNB P1.7,FHZQJ ;如果後仰,轉慢速前進
LCALL DELAY1S ;延時判斷是否真正平衡
LCALL DELAY1S
LCALL DELAY1S
JNB P1.6,FHPHTZ ;如果前傾,轉繼續調整平衡
JNB P1.7,FHPHTZ ;如果後仰,轉繼續調整平衡
LCALL TC ;停車
LCALL QDJS ;停止計時,顯示平衡調整所用時間
CLR P2.5 ;蜂鳴器鳴叫
CLR P2.4 ;七彩燈亮
LCALL CDSL5 ;轉到車燈閃亮5次,表示5S時間
LJMP FHPHTZ ;轉平衡調整
;***********轉長跳***********
FHZQJ:
LCALL CSZT ;初始狀態關報警
LJMP FHWWW
FHZHT:
LCALL CSZT ;初始狀態關報警
LJMP FHTPH
;***********調整平衡*********
FHTPH:
LCALL DELAY30 ;消除感測器擺動
TP: LCALL HT
LCALL DELAY
LCALL TC
LCALL DELAYTC ;消除感測器擺動
JNB P1.6,TP
LJMP FHPHTZ
FHWWW:
LCALL DELAY30 ;消除感測器擺動
DH: LCALL QJ
LCALL DELAY
LCALL TC
LCALL DELAYTC ;消除感測器擺動
JNB P1.7,DH
LJMP FHPHTZ
;******************子程序****************************************************
;*******設置初始狀態*************
CSZT:
SETB P2.6 ;關燈
SETB P2.7
SETB P2.4
SETB P2.5 ;關蜂鳴器
RET
;***********停轉*******************
TC:
CLR P1.2
CLR P1.3
CLR P1.4
CLR P1.5
RET
;***********前進********************
QJ:
CLR P1.2
SETB P1.3
CLR P1.4
SETB P1.5
RET
;**********後退********************
HT:
SETB P1.2
CLR P1.3
SETB P1.4
CLR P1.5
RET
;*********左轉彎******************
ZZW:
CLR P1.2
CLR P1.3
CLR P1.4
SETB P1.5
RET
;*********右轉彎******************
YZW:
CLR P1.2
SETB P1.3
CLR P1.4
CLR P1.5
RET
;**********秒錶控制************************
;*******啟動/停止計時**********
QDJS:
CLR P2.1
LCALL DELAY10
LCALL DELAY10
LCALL DELAY10
LCALL DELAY10
SETB P2.1
RET
;************顯示清零*************
QL:
CLR P2.3
LCALL DELAY10
LCALL DELAY10
LCALL DELAY10
LCALL DELAY10
SETB P2.3
RET
;************延時程序*********************
;*****延時1秒****
DELAY1S:
MOV R3,#02H
DEL1: MOV R2,#0FAH
DEL2: MOV R1,#0FAH
DEL3: DJNZ R1,DEL3
NOP
DJNZ R2,DEL2
DJNZ R3,DEL1
RET
;*****延時10毫秒*****
DELAY10:
MOV R2,#20
DB1:MOV R1,#248
DB2:DJNZ R1,DB2
DJNZ R2,DB1
RET
;*********前進或後退時間**********
DELAY:
MOV R2,#30
DD1:MOV R1,#200
DD2:DJNZ R1,DD2
DJNZ R2,DD1
RET
;***********停車時間****************
DELAYTC:
MOV R2,#100
D11:MOV R1,#200
D22:DJNZ R1,D22
DJNZ R2,D11
RET
;*********延時程序****************
;*********延時0.5秒****
DELAY30:
MOV R2,#250
DL2: MOV R1,#250
DL1: DJNZ R1,DL1
DJNZ R2,DL2
RET
;*********轉彎時間32MS**********
ZWSJ:
MOV R2,#50
D1:MOV R1,#100
D2:DJNZ R1,D2
DJNZ R2,D1
RET
;****延時約250毫秒(12M晶振)****
DELAY250:
MOV R3,#2
L3: MOV R2,#250
L1: MOV R1,#250
L2: DJNZ R1,L2
DJNZ R2,L1
DJNZ R3,L3
RET
;*****用狀態燈顯示終點停車5S時間(亮5次)*****
CDSL5:
MOV R5,#5H
PY: SETB P2.6
SETB P2.7
LCALL DELAY250
LCALL DELAY250
CLR P2.6
CLR P2.7
LCALL DELAY250
LCALL DELAY250
DJNZ R5,PY
RET
END
㈧ 用51單片機怎麼將MUP6050傳回來的數據轉換成角度急求!!!
MPU6050 有角速度和加速度,角速度的話直接積分就角度了(這里算出的是轉動了多少角度),角度的話利用反三角函數求。角度解算的話需要是在加速度已知(包括大小與方向)的情況下,通常可以利用靜止時的重力加速度可以求出傾角。詳細看晶元手冊的量程來計算哈~~
㈨ 求用51單片機控制ADXL345測量角度的程序,通過ADXL345感測器,用51單片機控制,測量傾角的程序!
//***************************************
// GY-29 ADXL345 IIC測試程序
// 使用單片機STC89C51
// 晶振:11.0592M
// 顯示:LCD1602
// 編譯環境 Keil uVision2
// 參考宏晶網站24c04通信程序
// 時間:2011年3月1日
// QQ:531389319
//****************************************
#include <REG51.H>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define DataPort P0 //LCD1602數據埠
sbit SCL=P1^0; //IIC時鍾引腳定義
sbit SDA=P1^1; //IIC數據引腳定義
sbit LCM_RS=P2^0; //LCD1602命令埠
sbit LCM_RW=P2^1; //LCD1602命令埠
sbit LCM_EN=P2^2; //LCD1602命令埠
#define SlaveAddress 0xA6 //定義器件在IIC匯流排中的從地址,根據ALT ADDRESS地址引腳不同修改
//ALT ADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
typedef unsigned char BYTE;
typedef unsigned short WORD;
BYTE BUF[8]; //接收數據緩存區
uchar ge,shi,,qian,wan; //顯示變數
int dis_data; //變數
int data_xyz[3];
void delay(unsigned int k);
void InitLcd(); //初始化lcd1602
void Init_ADXL345(void); //初始化ADXL345
void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
void conversion(uint temp_data);
void Single_Write_ADXL345(uchar REG_Address,uchar REG_data); //單個寫入數據
uchar Single_Read_ADXL345(uchar REG_Address); //單個讀取內部寄存器數據
void Multiple_Read_ADXL345(); //連續的讀取內部寄存器數據
//------------------------------------
void Delay5us();
void Delay5ms();
void ADXL345_Start();
void ADXL345_Stop();
void ADXL345_SendACK(bit ack);
bit ADXL345_RecvACK();
void ADXL345_SendByte(BYTE dat);
BYTE ADXL345_RecvByte();
void ADXL345_ReadPage();
void ADXL345_WritePage();
//-----------------------------------
//*********************************************************
void conversion(uint temp_data)
{
wan=temp_data/10000+0x30 ;
temp_data=temp_data%10000; //取余運算
qian=temp_data/1000+0x30 ;
temp_data=temp_data%1000; //取余運算
=temp_data/100+0x30 ;
temp_data=temp_data%100; //取余運算
shi=temp_data/10+0x30 ;
temp_data=temp_data%10; //取余運算
ge=temp_data+0x30;
}
/*******************************/
void delay(unsigned int k)
{
unsigned int i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}}
}
/*******************************/
void WaitForEnable(void)
{
DataPort=0xff;
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);
LCM_EN=0;
}
/*******************************/
void WriteCommandLCM(uchar CMD,uchar Attribc)
{
if(Attribc)WaitForEnable();
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/*******************************/
void WriteDataLCM(uchar dataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/***********************************/
void InitLcd()
{
WriteCommandLCM(0x38,1);
WriteCommandLCM(0x08,1);
WriteCommandLCM(0x01,1);
WriteCommandLCM(0x06,1);
WriteCommandLCM(0x0c,1);
}
/***********************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40;
X|=0x80;
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
/**************************************
延時5微秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數,注意時鍾過快時需要修改
當改用1T的MCU時,請調整此延時函數
**************************************/
void Delay5us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
/**************************************
延時5毫秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數
當改用1T的MCU時,請調整此延時函數
**************************************/
void Delay5ms()
{
WORD n = 560;
while (n--);
}
/**************************************
起始信號
**************************************/
void ADXL345_Start()
{
SDA = 1; //拉高數據線
SCL = 1; //拉高時鍾線
Delay5us(); //延時
SDA = 0; //產生下降沿
Delay5us(); //延時
SCL = 0; //拉低時鍾線
}
/**************************************
停止信號
**************************************/
void ADXL345_Stop()
{
SDA = 0; //拉低數據線
SCL = 1; //拉高時鍾線
Delay5us(); //延時
SDA = 1; //產生上升沿
Delay5us(); //延時
}
/**************************************
發送應答信號
入口參數:ack (0:ACK 1:NAK)
**************************************/
void ADXL345_SendACK(bit ack)
{
SDA = ack; //寫應答信號
SCL = 1; //拉高時鍾線
Delay5us(); //延時
SCL = 0; //拉低時鍾線
Delay5us(); //延時
}
/**************************************
接收應答信號
**************************************/
bit ADXL345_RecvACK()
{
SCL = 1; //拉高時鍾線
Delay5us(); //延時
CY = SDA; //讀應答信號
SCL = 0; //拉低時鍾線
Delay5us(); //延時
return CY;
}
/**************************************
向IIC匯流排發送一個位元組數據
**************************************/
void ADXL345_SendByte(BYTE dat)
{
BYTE i;
for (i=0; i<8; i++) //8位計數器
{
dat <<= 1; //移出數據的最高位
SDA = CY; //送數據口
SCL = 1; //拉高時鍾線
Delay5us(); //延時
SCL = 0; //拉低時鍾線
Delay5us(); //延時
}
ADXL345_RecvACK();
}
/**************************************
從IIC匯流排接收一個位元組數據
**************************************/
BYTE ADXL345_RecvByte()
{
BYTE i;
BYTE dat = 0;
SDA = 1; //使能內部上拉,准備讀取數據,
for (i=0; i<8; i++) //8位計數器
{
dat <<= 1;
SCL = 1; //拉高時鍾線
Delay5us(); //延時
dat |= SDA; //讀數據
SCL = 0; //拉低時鍾線
Delay5us(); //延時
}
return dat;
}
//******單位元組寫入*******************************************
void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
{
ADXL345_Start(); //起始信號
ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
ADXL345_SendByte(REG_Address); //內部寄存器地址,請參考中文pdf22頁
ADXL345_SendByte(REG_data); //內部寄存器數據,請參考中文pdf22頁
ADXL345_Stop(); //發送停止信號
}
//********單位元組讀取*****************************************
uchar Single_Read_ADXL345(uchar REG_Address)
{ uchar REG_data;
ADXL345_Start(); //起始信號
ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
ADXL345_SendByte(REG_Address); //發送存儲單元地址,從0開始
ADXL345_Start(); //起始信號
ADXL345_SendByte(SlaveAddress+1); //發送設備地址+讀信號
REG_data=ADXL345_RecvByte(); //讀出寄存器數據
ADXL345_SendACK(1);
ADXL345_Stop(); //停止信號
return REG_data;
}
//*********************************************************
//
//連續讀出ADXL345內部加速度數據,地址范圍0x32~0x37
//
//*********************************************************
void Multiple_read_ADXL345(void)
{ uchar i;
ADXL345_Start(); //起始信號
ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
ADXL345_SendByte(0x32); //發送存儲單元地址,從0x32開始
ADXL345_Start(); //起始信號
ADXL345_SendByte(SlaveAddress+1); //發送設備地址+讀信號
for (i=0; i<6; i++) //連續讀取6個地址數據,存儲中BUF
{
BUF[i] = ADXL345_RecvByte(); //BUF[0]存儲0x32地址中的數據
if (i == 5)
{
ADXL345_SendACK(1); //最後一個數據需要回NOACK
}
else
{
ADXL345_SendACK(0); //回應ACK
}
}
ADXL345_Stop(); //停止信號
Delay5ms();
}
//*****************************************************************
//初始化ADXL345,根據需要請參考pdf進行修改************************
void Init_ADXL345()
{
Single_Write_ADXL345(0x31,0x0B); //測量范圍,正負16g,13位模式
Single_Write_ADXL345(0x2C,0x08); //速率設定為12.5 參考pdf13頁
Single_Write_ADXL345(0x2D,0x08); //選擇電源模式 參考pdf24頁
Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中斷
Single_Write_ADXL345(0x1E,0x00); //X 偏移量 根據測試感測器的狀態寫入pdf29頁
Single_Write_ADXL345(0x1F,0x00); //Y 偏移量 根據測試感測器的狀態寫入pdf29頁
Single_Write_ADXL345(0x20,0x05); //Z 偏移量 根據測試感測器的狀態寫入pdf29頁
}
//***********************************************************************
//顯示x軸
void display_x()
{ float temp;
dis_data=(BUF[1]<<8)+BUF[0]; //合成數據
if(dis_data<0){
dis_data=-dis_data;
DisplayOneChar(2,0,'-'); //顯示正負符號位
}
else DisplayOneChar(2,0,' '); //顯示空格
temp=(float)dis_data*3.9; //計算數據和顯示,查考ADXL345快速入門第4頁
conversion(temp); //轉換出顯示需要的數據
DisplayOneChar(0,0,'X'); //第0行,第0列 顯示X
DisplayOneChar(1,0,':');
DisplayOneChar(3,0,qian);
DisplayOneChar(4,0,'.');
DisplayOneChar(5,0,);
DisplayOneChar(6,0,shi);
DisplayOneChar(7,0,'g');
}
//***********************************************************************
//顯示y軸
void display_y()
{ float temp;
dis_data=(BUF[3]<<8)+BUF[2]; //合成數據
if(dis_data<0){
dis_data=-dis_data;
DisplayOneChar(2,1,'-'); //顯示正負符號位
}
else DisplayOneChar(2,1,' '); //顯示空格
temp=(float)dis_data*3.9; //計算數據和顯示,查考ADXL345快速入門第4頁
conversion(temp); //轉換出顯示需要的數據
DisplayOneChar(0,1,'Y'); //第1行,第0列 顯示y
DisplayOneChar(1,1,':');
DisplayOneChar(3,1,qian);
DisplayOneChar(4,1,'.');
DisplayOneChar(5,1,);
DisplayOneChar(6,1,shi);
DisplayOneChar(7,1,'g');
}
//***********************************************************************
//顯示z軸
void display_z()
{ float temp;
dis_data=(BUF[5]<<8)+BUF[4]; //合成數據
if(dis_data<0){
dis_data=-dis_data;
DisplayOneChar(10,1,'-'); //顯示負符號位
}
else DisplayOneChar(10,1,' '); //顯示空格
temp=(float)dis_data*3.9; //計算數據和顯示,查考ADXL345快速入門第4頁
conversion(temp); //轉換出顯示需要的數據
/*
DisplayOneChar(10,0,'Z'); //第0行,第10列 顯示Z
DisplayOneChar(11,0,':');
DisplayOneChar(11,1,qian);
DisplayOneChar(12,1,'.');
DisplayOneChar(13,1,);
DisplayOneChar(14,1,shi);
DisplayOneChar(15,1,'g');
*/
}
//*********************************************************
//******主程序********
//*********************************************************
void main()
{
uchar devid;
float Roll,Pitch,Q,T,K;
delay(500); //上電延時
InitLcd(); //液晶初始化ADXL345
Init_ADXL345(); //初始化ADXL345
devid=Single_Read_ADXL345(0X00);//讀出的數據為0XE5,表示正確
while(1) //循環
{
Init_ADXL345(); //初始化ADXL345
Multiple_Read_ADXL345(); //連續讀出數據,存儲在BUF中
data_xyz[0]=(BUF[1]<<8)+BUF[0]; //合成數據
data_xyz[1]=(BUF[3]<<8)+BUF[2]; //合成數據
data_xyz[2]=(BUF[5]<<8)+BUF[4]; //合成數據
//分別是加速度X,Y,Z的原始數據,10位的
Q=(float)data_xyz[0]*3.9;
T=(float)data_xyz[1]*3.9;
K=(float)data_xyz[2]*3.9;
Q=-Q;
Roll=(float)(((atan2(K,Q)*180)/3.14159265)+180); //X軸角度值
Pitch=(float)(((atan2(K,T)*180)/3.14159265)+180); //Y軸角度值
conversion(Roll); //轉換出顯示需要的數據X軸,或者Y軸
DisplayOneChar(9,1,'A');
DisplayOneChar(10,1,':');
DisplayOneChar(11,1,);
DisplayOneChar(12,1,shi);
DisplayOneChar(13,1,ge);
delay(200); //延時
}
}
㈩ 求用51單片機控制 MMA7361 傾角感測器 的C 語言代碼。最好有注釋,詳盡者 追加30分。
#include "STC12C5410AD.H"
sbit MMA7260sleep=P1^0; //MMA7260休眠與否,0-休眠;1-正常工作
//---------------------------------------
//名稱: 延時約1毫秒函數
//日期:20081111
//-----------------------------------------
void delay1ms()
{
word k;
for(k=0;k<12000;k++);
}
void delayms(word ms)
{
word k,j;
for(j=0;j<ms;j++)
for(k=0;k<12000;k++);
}
//---------------------------------------
//名稱: 串口數據發送函數
//日期:20081111
//-----------------------------------------
void uart_putchar(byte ch)
{
TI=0;
if (ch == '\n')
{
SBUF= 0x0d; //output'CR'
while(!TI);
return;
}
SBUF=ch;
while(!TI);
}
//---------------------------------------
//名稱: 串口數據接收函數
//日期:20081111
//-----------------------------------------
byte uart_getchar(void)
{
if(RI)
{
RI=0;
return SBUF; //有數據接收到,返回1
}
else
{
return 0; //無數據接收到,返回0
}
}
void putstr(char ch[])
{
byte ptr=0;
while(ch[ptr])
{
uart_putchar((byte)ch[ptr++]);
}
}
//---------------------------------------
//名稱: 模數轉換函數(8位)
//日期:20081111
//-----------------------------------------
byte ReadAD(byte ch)
{
ADC_DATA = 0; //清A/D轉換結果寄存器
ADC_CONTR = 0xF8|ch; //0000,1000ADCS = 1,啟動轉換
delay1ms();
do{;}
while((ADC_CONTR&0x10)==0); //0001,0000等待A/D轉換結束
ADC_CONTR = ADC_CONTR&0xE7; //1110,0111清ADC_FLAG位,停止A/D轉換
return ADC_DATA;
}
/***************************************************
把0--255的數值轉化為3位字元串格式
****************************************************/
void Byte2Str3(char zifu[],byte val,byte StartPtr)
{
char characters[11]="0123456789";
byte tv=0;
tv=val/100;
zifu[StartPtr++] = characters[tv];
tv=(val%100)/10;
zifu[StartPtr++] = characters[tv];
tv=val%10;
zifu[StartPtr] = characters[tv];
//zifu[3] = '\0';
return;
}
//---------------------------------------
//名稱: 初始化函數函數
//日期:20081111
//-----------------------------------------
void init_ad(void)
{
P1M0=0x07; //設置P1.012為高阻輸入,以准備AD
P1M1=0x00;
ADC_CONTR = 0xf8; //1000,0000打開A/D轉換電源
delay1ms();
ADC_CONTR = ADC_CONTR&0xe0; //1110,0000 清ADC_FLAG,ADC_START位和低3位
}
void init_uart(void) //P3.0,3.1
{
TMOD=0x20; //TH1=256-INT(22118400/32/12/baud+0.5)
TH1=0xfa; //0xfa,9600
TL1=0xfd; //0xff,57600
PCON=0x00;
TR1=1;
SCON=0xd0;
}
void init_dev(void)
{
init_ad();
init_uart();
}
//---------------------------------------
//名稱: 主函數
//日期:20081111
//-----------------------------------------
void main()
{
char txtbuf[17]="\n ADC Val: ";
byte adbuf;
init_dev();
putstr("\n MMA7260 starts working!\n");
MMA7260sleep=1;//MMA7260開始工作
while(1)
{
//ADC
adbuf=ReadAD(0); //X AXIS
Byte2Str3(txtbuf,adbuf,11);
putstr(txtbuf);
adbuf=ReadAD(1); //Y AXIS
Byte2Str3(txtbuf,adbuf,11);
putstr(txtbuf);
adbuf=ReadAD(2); //Z AXIS
Byte2Str3(txtbuf,adbuf,11);
putstr(txtbuf);
delayms(300);
}
}