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

📄 mcp2510.c

📁 MSP430单片机C语言应用程序设计实例精讲(秦龙编著)
💻 C
字号:
#include <msp430x14x.h>
#include "MCP2510.h"

void Init_SPI (void);
void Init_Port(void);
void Init_CLK(void);
void CS_Enable(void);
void CS_Disable(void);

void RessetMcp2510(void);
int GetStatusMcp2510(void);
void RtsMcp2510(char RTSn);
void BitModiMcp2510(char addr,char mask,char data);
void ReadMcp2510(int addr,int n,char outBuf[]);
void WriteMcp2510(int addr,int n,char inBuf[]);
void SetNormal(void);
void IsSendComplete(int addr);
void InitMcp2510(void);
void SendMsg(int nDLC,char inBuf[]);
int ReceiveMsg(char outBuf[]);



int nTX0_Len;
char nTX0_Flag;
int nSend_TX0;
char UART0_TX_BUF[26];
int nRX0_Len_temp;

int nRX0_Len;
char nRX0_Flag;
int nRev_UART0;
char UART0_RX_BUF[26];

char nRecID_Hi;
char nRecID_Lo;

void main(void)
{
	char inBuf[8];
	char outBuf[8];
	int i;
	WDTCTL = WDTPW + WDTHOLD;   // 关闭看门狗
        
    _DINT();			// 关闭中断    
    /////////////////////////////////
    // 初始化
    Init_CLK();
    Init_Port();
	Init_SPI();
	nSend_TX0 = 0;
	nRecID_Hi = 0;
    nRecID_Lo = 0;
	for(i = 0;i < 8;i++)
	{
		inBuf[i] = i;
		outBuf[i] = 0;
	}
	_EINT();
	for(;;)
	{
		ReceiveMsg(outBuf);
		SendMsg(8,inBuf);
	}
}

void Init_CLK(void)
{
    unsigned int i;
    BCSCTL1 = 0X00;			//将寄存器的内容清零
					//XT2震荡器开启
					//LFTX1工作在低频模式
					//ACLK的分频因子为1
					
    do 
    {
	IFG1 &= ~OFIFG; // 清除OSCFault标志
	for (i = 0x20; i > 0; i--);                
    }
    while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1   
					
    BCSCTL2 = 0X00;			//将寄存器的内容清零
    BCSCTL2 += SELM1;		//MCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELS;		//SMCLK的时钟源为TX2CLK,分频因子为1
}
void Init_SPI (void)
{
	//SPI0模块允许     
	ME1 |= USPIE0; 
	//将寄存器的内容清零
    U0CTL = 0X00;	
    //数据为8比特,选择SPI模式,单片机为主机模式
    U0CTL |= CHAR + SYNC + MM;
	//将寄存器的内容清零
    U0TCTL = 0X00;	
    // 时钟源为SMCLK,选择3线模式
    U0TCTL = CKPH + SSEL1 + SSEL0 + STC; 
	//传输时钟为SMCLK / 4
    UBR0_0 = 0X02;  
    UBR1_0 = 0X00;
	//调整寄存器,没有调整
    UMCTL_0 = 0X00;     
	//发送接收中断允许
	IE1 |= UTXIE0; 
	IE1 |= URXIE0; 
}
void Init_Port(void)
{
    //将P3口所有的管脚在初始化的时候设置为输入方式
    P3DIR = 0;
    //将P3口所有的管脚设置为一般I/O口
    P3SEL = 0;
	//P3.1 P3.2 P3.3被分配为SPI口
    P3SEL = BIT3 + BIT2 + BIT1;
	//P1.0作为输出管脚
	P1DIR |= BIT0;
	//P3.3作为输出管脚
	P3DIR |= BIT3;
	//P3.1作为输出管脚
	P3DIR |= BIT1;
	//P1.0 输出高电平,MCP2510不被选通
	P1OUT |= BIT0; 
    return;
}
void CS_Enable(void)
{
	//P1.0输出低电平
	P1OUT &=~(BIT0);
	return ;
}
void CS_Disable(void)
{
	//P1.0输出高电平
	P1OUT|=BIT0;
	return ;
}
interrupt [UART0TX_VECTOR] void UART0_TX_ISR(void)
{
    if(nTX0_Len != 0)
    {
		// 表示缓冲区里的数据没有发送完
    	nTX0_Flag = 0;				    	
    	TXBUF0 = UART0_TX_BUF[nSend_TX0];
    	nSend_TX0 += 1;   
    	if(nSend_TX0 >= nTX0_Len)
    	{
    	    nSend_TX0 = 0;
    	    nTX0_Len = 0;
    	    nTX0_Flag = 1;
    	}
    }
}
interrupt [UART0RX_VECTOR] void UART0_RX_ISR(void)
{
	//接收来自的数据
    UART0_RX_BUF[nRX0_Len_temp] = RXBUF0;	
    
    nRX0_Len_temp += 1;
	if(nRX0_Len_temp >= nRX0_Len)
	{
        nRev_UART0 = 1;
    	nRX0_Len_temp = 0;
		nRX0_Len = 0;
	}
}

void RessetMcp2510(void)
{
	int i;
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//复位命令
    UART0_TX_BUF[0] = (char)(0xC0);
    nTX0_Len = 1;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return;
}
int GetStatusMcp2510(void)
{
	int i;
	int nStatus = 0;
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//读状态命令
    UART0_TX_BUF[0] = 0xA0;
    nTX0_Len = 1;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;

	nRX0_Len = 1;
	while(1)
	{
		if(nRev_UART0 == 1)
		{
			nRev_UART0 = 0;
            nStatus = (int)(UART0_RX_BUF[0]);
			break;
		}
	}
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return nStatus;
}
void RtsMcp2510(char RTSn)
{
	int i;
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//请求发送命令
	UART0_TX_BUF[0] = (char)(0x80 | RTSn);
    nTX0_Len = 1;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return;
}
void BitModiMcp2510(char addr,char mask,char data)
{
	int i;
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//位修改送命令
	UART0_TX_BUF[0] = 0x05;
	UART0_TX_BUF[0] = addr;
	UART0_TX_BUF[0] = mask;
	UART0_TX_BUF[0] = data;
    nTX0_Len = 4;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return;
}
void ReadMcp2510(int addr,int n,char outBuf[])
{
	int i;
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//读命令
	UART0_TX_BUF[0] = 0x03;
	UART0_TX_BUF[0] = addr;
	for(i = 0;i < n;i++)
	{
		UART0_TX_BUF[i + 2] = 0;
	}
    nTX0_Len = 2 + n;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;
	//接收数据
    nRX0_Len = n;
	while(1)
	{
		if(nRev_UART0 == 1)
		{
			nRev_UART0 = 0;
			for(i = 0;i < n;i++)
			{
				outBuf[i] = UART0_RX_BUF[i];
			}
			break;
		}
	}
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return;
}
void WriteMcp2510(int addr,int n,char inBuf[])
{
	int i;	
	CS_Enable();
	for(i = 10;i > 0;i--) ;
	//写命令
	UART0_TX_BUF[0] = 0x02;
	UART0_TX_BUF[0] = addr;
	for(i = 0;i < n;i++)
	{
		UART0_TX_BUF[i + 2] = inBuf[i];
	}
    nTX0_Len = 2 + n;
    // 设置中断标志,进入发送中断程序
    IFG1 |= UTXIFG0;
	for(i = 100;i > 0;i--) ;
	CS_Disable();
	return;
}
void SetNormal(void)
{
    int nFlag = 1;
	int i;
	char outBuf[10];
	for(i = 0;i < 10;i++)
	{
		outBuf[i] = 0;
	}
	//设置成正常模式
	BitModiMcp2510(CANSTAT,0xe0,0x00);
	do
	{
        ReadMcp2510(CANSTAT,1,outBuf);
		nFlag = outBuf[0] & 0xe0;
	}while(nFlag);

    return;
}
void IsSendComplete(int addr)
{
	int i;
	int nFlag = 1;
	char outBuf[10];
	for(i = 0;i < 10;i++)
	{
		outBuf[i] = 0;
	}
	
	do
	{
        ReadMcp2510(addr,1,outBuf);
		nFlag = outBuf[0] & 0x08;
	}while(nFlag);
    return;
}
void InitMcp2510(void)
{
	char inBuf[10];
	//复位
	RessetMcp2510();
	//设置拨特率
	inBuf[0] = 0x02;
	inBuf[1] = 0x90;
	inBuf[2] = 0x07;
    WriteMcp2510(CNF3,3,inBuf);
	//RX0接收,屏蔽位为0,过滤器为0
    inBuf[0] = 0x00;
	inBuf[1] = 0x00;
    WriteMcp2510(RXM0SIDH,2,inBuf);
	inBuf[0] = 0x00;
	inBuf[1] = 0x00;
    WriteMcp2510(RXF0SIDH,2,inBuf);
	//CAN中断不使能
    inBuf[0] = 0x00;
    WriteMcp2510(CANINTE,1,inBuf);
	//设置成正常模式
	SetNormal();
}
void SendMsg(int nDLC,char inBuf[])
{
	int i;
	char sndBuf[16];
	for(i = 0;i < nDLC;i++)
	{
		sndBuf[i] = inBuf[i];
	}
	WriteMcp2510(TXB0D0,nDLC,sndBuf);
    sndBuf[0] = nDLC;
    WriteMcp2510(TXB0DLC,1,sndBuf);
    sndBuf[0] = 0x03;
	sndBuf[1] = nRecID_Hi;
	sndBuf[2] = nRecID_Lo;
    WriteMcp2510(TXB0CTRL,3,sndBuf);
	RtsMcp2510(0x01);
	IsSendComplete(TXB0CTRL);
	return;
}
int ReceiveMsg(char outBuf[])
{
	int i;
	int nFlag;
	int nDLC;
	char revBuf[16];
	for(i = 0;i < 16;i++)
	{
		revBuf[i] = 0;
	}
	ReadMcp2510(CANINTF,1,revBuf);
    nFlag = revBuf[0] & 0x01;
	if(nFlag == 0)
	{
		return 0;
	}
	BitModiMcp2510(CANINTF,0x01,0x00);
	ReadMcp2510(TXB0SIDH,2,revBuf);
	nRecID_Hi = revBuf[0];
	nRecID_Lo = revBuf[1] & 0xe0;
	ReadMcp2510(RXB0DLC,1,revBuf);
    nDLC = revBuf[0] & 0x0f;
    ReadMcp2510(RXB0D0,nDLC,outBuf);
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -