📄 ad7705zh.c
字号:
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#include "cygnal\c8051f340.h"
#define X_MIDDLE 0x7E68
#define Y_MIDDLE 0x7E80
#define X_1G 13008
#define Y_1G 13064
#define MAX_BUF_SIZE 5
// Instruction Set
#define SPI_WRITE 0x01 // Send a byte from the Master to the Slave
#define SPI_READ_16DAT 0x04 // Send a byte from the Slave to the Master
#define CH_X 1
#define CH_Y 2
sfr16 T3 = 0x94;
sfr16 T3RL = 0x92;
sbit LED1 = P2^4;
sbit LED2 = P2^5;
sbit CEX0 = P2^6;
sbit CEX1 = P2^7;
sbit CEX2 = P3^0;
sbit CEX3 = P3^1;
sbit CEX4 = P3^2;
sbit DRDY = P3^3;
sbit SCK = P1^0;
sbit MISO = P1^1;
sbit MOSI = P1^2;
sbit NSS = P1^3;
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
unsigned char SPI_Cmd;
unsigned char SPI_WrData;
unsigned char SPI_RdData[2] = {0};
unsigned int ADBufX[MAX_BUF_SIZE] = {0};
unsigned int ADBufY[MAX_BUF_SIZE] = {0};
unsigned char CHXorY;
unsigned char CHct = 0;
bit b_flag;
unsigned char SPIState = 0;
char xdata PrintBuffer[256];
unsigned char xdata p_PB_end, p_PB_this;
char xdata tempBuffer[30];
char xdata n_tempBuffer;
bit b_pb0;
bit b_pb1;
bit b_pb2;
bit b_pb3;
bit b_pb4;
void Init_Device(void)
{
int i;
PCA0MD &= ~0x40;
PCA0MD = 0x00; //禁用看门狗
P0 &= 0x3F; //晶振引脚写0
P0MDIN = 0x3F; //晶振引脚置于模拟输入方式0
P1MDIN = 0x1F;
P1MDOUT = 0x0D;
P2MDIN = 0xF0;
P0SKIP = 0xCF;
P1SKIP = 0xF0;
P2SKIP = 0x3F;
XBR0 = 0x03;
XBR1 = 0x55;
/* P0MDIN = 0x3F;
P1MDIN = 0x1F;
P2MDIN = 0xF0;
P0SKIP = 0xCF;
P1SKIP = 0xF0;
P2SKIP = 0x3F;
P3SKIP = 0x04;
XBR0 = 0x03;
XBR1 = 0x45;
*/
/* OSCXCN = (0x67); // Start external oscillator with the appropriate XFCN setting based on crystal frequency
for (i=0; i < 256; i++); // Wait for crystal osc. to start
#if(CRYSTAL_FREQUENCY <= 100000) // If tuning-fork crystal, add extra delay before checking XTLVLD
for (i=0; i < 256; i++); // Add 1ms delay
for (i=0; i < 256; i++); // Add 1ms delay
#endif
while (!(OSCXCN & 0x80)); // Wait for crystal osc. to settle
RSTSRC = 0x06; // Enable missing clock detector and VDD Monitor reset
CLKSEL = 0x01; // Select external oscillator as system clock source
OSCICN = 0x00;
*/
OSCICN = 0x83;
CLKMUL = 0x80;
for (i = 0; i < 20; i++); // Wait 5us for initialization
CLKMUL |= 0xC0;
while ((CLKMUL & 0x20) == 0);
CLKSEL = 0x02;
EA = 1; //允许中断
}
void UART0_Init(int baud)
{
TMOD |= 0x20; //定时器1工作于8位自动重载模式
// CKCON |= 0x00; //使用内部晶振的12分频
if(baud == 38400)
{
TH1 = -26;//0xD8;
TL1 = TH1;
}
else if(baud == 19200)
{
TH1 = -52;//0xB0; //19200bps, 0x60 for 9600bps
TL1 = TH1;
}
else //9600
{
TH1 = -104;//0x60;
TL1 = TH1;
}
TR1 = 1;
SCON0 = 0x10; //接收允许
ES0 = 1; //允许UART0中断
}
void UART0_Interrupt (void) interrupt 4
{
unsigned char c;
if (RI0 == 1)
{
RI0 = 0; // Clear interrupt flag
c = SBUF0;
}
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
p_PB_this++;
// if(p_PB_this > 127) //Buffer总长为128
// p_PB_this = 0;
if(p_PB_this != p_PB_end)
SBUF0 = *(PrintBuffer + p_PB_this);
}
}
void WriteBuffer(unsigned char n, char *Buffer)
{
unsigned char p_PB_temp,i;
p_PB_temp = p_PB_end;
for(i=0;i<n;i++)
{
*(PrintBuffer + p_PB_temp) = *(Buffer + i);
p_PB_temp++;
// if(p_PB_temp > 127) //Buffer总长为128
// p_PB_temp = 0;
}
if(p_PB_end == p_PB_this)
{
p_PB_end = p_PB_temp;
SBUF0 = *(PrintBuffer + p_PB_this);
}
else
p_PB_end = p_PB_temp;
}
void PCA_Init(void)
{ //初始化
b_pb0 = 0;
b_pb1 = 0;
b_pb2 = 0;
b_pb3 = 0;
b_pb4 = 0;
PCA0MD = 0x00; //时基为内部晶振12分频, 不允许PCA定时器溢出中断
PCA0CPM0 = 0x11; //下降沿捕捉
PCA0CPM1 = 0x11;
PCA0CPM2 = 0x11;
PCA0CPM3 = 0x11;
PCA0CPM4 = 0x11;
PCA0CN = 0x40; //运行PCA
EIE1 |= 0x10; //中断允许
}
void PCA_ISR(void) interrupt 11
{
if(CCF0)
{
CCF0 = 0;
if(!CEX0)
{
b_pb0 = 1;
}
}
else if(CCF1)
{
CCF1 = 0;
if(!CEX1)
{
b_pb1 = 1;
}
}
else if(CCF2)
{
CCF2 = 0;
if(!CEX2)
{
b_pb2 = 1;
}
}
else if(CCF3)
{
CCF3 = 0;
if(!CEX3)
{
b_pb3 = 1;
}
}
else if(CCF4)
{
CCF4 = 0;
if(!CEX4)
{
b_pb4 = 1;
}
}
else if(CF)
{
CF = 0;
}
}
void SPI0_Init()
{
SPI0CFG = 0x70;
SPI0CN = 0x0D;
SPI0CKR = 119; //SCK: 100000 //= (SYSCLK/(2*SPI_CLOCK))-1;
ESPI0 = 1; //允许中断
}
void SPI_ISR (void) interrupt 6
{
if (WCOL == 1)
{ // Write collision occurred
WCOL = 0; // Clear the write collision flag
// Error_Flag = 1;
SPIState=0;
}
else
{
SPIF = 0; // Clear the SPIF flag
if(SPI_Cmd == SPI_WRITE)
{
switch(SPIState)
{
case 0:
SPI0DAT = SPI_WrData;
SPIState++; // Advance to the final state (only writing one byte)
break;
case 1:
default:
NSSMD0 = 1; // De-select the Slave
SPIState = 0;
break;
}
}
else if(SPI_Cmd == SPI_READ_16DAT)
{
switch(SPIState)
{
case 0:
if(CHXorY == CH_Y)
{ SPI0DAT = 0x39;
}
else if(CHXorY == CH_X)
{ SPI0DAT = 0x38; // Send a dummy byte so the Slave can start sending the data
}
SPIState++; // Advance to the next state where the data can be received The data from the slave is not available until after the second transfer is completed. The dummy byte allows the slave to send data, since the Master controls SCK.
break;
case 1:
SPI0DAT = 0xFF;
SPIState++; // Advance to the next state where the data can be received The data from the slave is not available until after the second transfer is completed. The dummy byte allows the slave to send data, since the Master controls SCK.
break;
case 2:
SPI_RdData[0] = SPI0DAT;
SPI0DAT = 0xFF;
SPIState++; // Advance to the next state where the data can be received The data from the slave is not available until after the second transfer is completed. The dummy byte allows the slave to send data, since the Master controls SCK.
break;
case 3:
SPI_RdData[1] = SPI0DAT;
NSSMD0 = 1; // De-select the Slave
SPIState = 0; // Advance to the next state where the data can be received The data from the slave is not available until after the second transfer is completed. The dummy byte allows the slave to send data, since the Master controls SCK.
b_flag = 1;
break;
}
}
else
{
NSSMD0 = 1; // De-select the Slave
SPIState = 0; // Reset the state
}
}
}
void Writetoreg(unsigned char dat)
{
while(SPIState);
NSSMD0 = 0; // select the Slave
SPI_Cmd = SPI_WRITE;
SPI_WrData = dat;
SPIF = 1;
}
void ReadAD7705(void)
{
while(SPIState);
NSSMD0 = 0; // select the Slave
SPI_Cmd = SPI_READ_16DAT;
// CHXorY = CH_Y;
CHct++;
if(CHct>= (MAX_BUF_SIZE*2))
{
CHct=0;
}
if(CHct<MAX_BUF_SIZE)
{
CHXorY = CH_X;
}
else if(MAX_BUF_SIZE<=CHct && CHct<(MAX_BUF_SIZE*2))
{
CHXorY = CH_Y;
}
SPIF = 1;
}
void AD7705_Start()
{
unsigned int i;
Writetoreg(0xFF);
Writetoreg(0xFF);
Writetoreg(0xFF);
Writetoreg(0xFF);
Writetoreg(0xFF);
i=65535; while(i--);
Writetoreg(0x20); /* Active Channel is Ain1(+)/Ain1(.), next operation as write to the clock register */
// Writetoreg(0x04); /* master clock enabled, 2.4576MHz Clock, set output rate to 50Hz*/
Writetoreg(0x07); /* master clock enabled, 2.4576MHz Clock, set output rate to 50Hz*/
Writetoreg(0x10); /* Active Channel is Ain1(+)/Ain1(.), next operation as write to the setup register */
Writetoreg(0x40); /* gain = 1, bipolar mode, buffer off, clear FSYNC and perform a Self Calibration*/
i=65535; while(i--);
i=65535; while(i--);
i=65535; while(i--);
i=65535; while(i--);
i=65535; while(i--);
Writetoreg(0x21);
Writetoreg(0x07);
Writetoreg(0x11);
Writetoreg(0x40);
i=65535;
while(i--);
}
void Timer0_Init(void)
{
TMOD |= 0x06;
TH0 = 0xFF;
TL0 = 0xFF;
TR0=1;
ET0 = 1;
}
void Timer0_ISR(void) interrupt 1
{
TF0 = 0;
if(!DRDY)
{
ReadAD7705();
}
}
unsigned Middle(unsigned int *Buf)//起泡排序
{
unsigned char n,k;
unsigned int temp;
unsigned long ltep;
for(n=MAX_BUF_SIZE-1;n>0;n--)
{
for(k=0;k<n;k++)
{
if(*(Buf+k) > *(Buf+k+1))
{
temp = *(Buf+k+1);
*(Buf+k+1) = *(Buf+k);
*(Buf+k) = temp;
}
}
}
ltep = 0;
for(n=1;n<4;n++)
{
ltep += *(Buf+n);
}
return(ltep/3);
}
void main(void)
{
unsigned char i = 0;
bit b_cycle=0;
unsigned int FiltX,FiltY;
int deltaX,deltaY;
float XAngle,YAngle;
p_PB_end = 0; p_PB_this = 0;
SPIState = 0;
CHct = 0;
CHXorY = CH_Y;
b_flag = 0;
LED2 = 0;
Init_Device();
SPI0_Init();
AD7705_Start();
PCA_Init();
UART0_Init(19200);
n_tempBuffer = sprintf(tempBuffer, "Ready.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
while(p_PB_this != p_PB_end);
// Timer3_Init(20.0);
Timer0_Init();
while(1)
{
if(b_flag)
{
b_flag = 0;
if(1<=CHct && CHct<=MAX_BUF_SIZE)
{
ADBufX[CHct-1] = ((int)SPI_RdData[0]<<8 )| SPI_RdData[1];
}
else if((MAX_BUF_SIZE+1)<=CHct && CHct< (MAX_BUF_SIZE * 2))
{
ADBufY[CHct-MAX_BUF_SIZE-1] = ((int)SPI_RdData[0]<<8) | SPI_RdData[1];
}
else if(0==CHct)
{
ADBufY[MAX_BUF_SIZE - 1] = ((int)SPI_RdData[0]<<8) | SPI_RdData[1];
b_cycle = 1;
}
}
if(b_cycle)
{
b_cycle=0;
FiltX = Middle(ADBufX);
deltaX = FiltX - X_MIDDLE;
if(deltaX > X_1G)
{
deltaX = X_1G;
}
else if(deltaX < -X_1G)
{
deltaX = -X_1G;
}
XAngle = 180.0* asin((float)deltaX / X_1G)/3.1415926;
FiltY = Middle(ADBufY);
deltaY = FiltY - Y_MIDDLE;
if(deltaY > Y_1G)
{
deltaY = Y_1G;
}
else if(deltaY < -Y_1G)
{
deltaY = -Y_1G;
}
YAngle = -180.0*asin((float)deltaY / Y_1G)/3.1415926;
i++;
if(i>=20)
{
i=0;
n_tempBuffer = sprintf(tempBuffer, "X:%04X; Y:%04X\t",FiltX, FiltY);
WriteBuffer(n_tempBuffer,tempBuffer);
n_tempBuffer = sprintf(tempBuffer, "X:%.3f; Y:%.3f\t",((float)FiltX)/65536.0*5.0, ((float)FiltY)/65536.0*5.0);
WriteBuffer(n_tempBuffer,tempBuffer);
n_tempBuffer = sprintf(tempBuffer, "X:%.3f; Y:%.3f\r\n",XAngle,YAngle);
WriteBuffer(n_tempBuffer,tempBuffer);
}
}
if(b_pb0)
{
b_pb0 = 0;
n_tempBuffer = sprintf(tempBuffer, "Button 0 Pushed.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
}
if(b_pb1)
{
b_pb1 = 0;
n_tempBuffer = sprintf(tempBuffer, "Button 1 Pushed.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
}
if(b_pb2)
{
b_pb2 = 0;
n_tempBuffer = sprintf(tempBuffer, "Button 2 Pushed.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
}
if(b_pb3)
{
b_pb3 = 0;
n_tempBuffer = sprintf(tempBuffer, "Button 3 Pushed.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
}
if(b_pb4)
{
b_pb4 = 0;
n_tempBuffer = sprintf(tempBuffer, "Button 4 Pushed.\r\n");
WriteBuffer(n_tempBuffer,tempBuffer);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -