⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad7705zh.c

📁 这是单片机C8051F340与AD7705之间的通讯,使用的是SPI方式
💻 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 + -