mcp2510.c
上传用户:xs588588
上传日期:2021-03-30
资源大小:242k
文件大小:7k
源码类别:

DSP编程

开发平台:

C/C++

  1. #include <msp430x14x.h>
  2. #include "MCP2510.h"
  3. void Init_SPI (void);
  4. void Init_Port(void);
  5. void Init_CLK(void);
  6. void CS_Enable(void);
  7. void CS_Disable(void);
  8. void RessetMcp2510(void);
  9. int GetStatusMcp2510(void);
  10. void RtsMcp2510(char RTSn);
  11. void BitModiMcp2510(char addr,char mask,char data);
  12. void ReadMcp2510(int addr,int n,char outBuf[]);
  13. void WriteMcp2510(int addr,int n,char inBuf[]);
  14. void SetNormal(void);
  15. void IsSendComplete(int addr);
  16. void InitMcp2510(void);
  17. void SendMsg(int nDLC,char inBuf[]);
  18. int ReceiveMsg(char outBuf[]);
  19. int nTX0_Len;
  20. char nTX0_Flag;
  21. int nSend_TX0;
  22. char UART0_TX_BUF[26];
  23. int nRX0_Len_temp;
  24. int nRX0_Len;
  25. char nRX0_Flag;
  26. int nRev_UART0;
  27. char UART0_RX_BUF[26];
  28. char nRecID_Hi;
  29. char nRecID_Lo;
  30. void main(void)
  31. {
  32. char inBuf[8];
  33. char outBuf[8];
  34. int i;
  35. WDTCTL = WDTPW + WDTHOLD;   // 关闭看门狗
  36.         
  37.     _DINT(); // 关闭中断    
  38.     /////////////////////////////////
  39.     // 初始化
  40.     Init_CLK();
  41.     Init_Port();
  42. Init_SPI();
  43. nSend_TX0 = 0;
  44. nRecID_Hi = 0;
  45.     nRecID_Lo = 0;
  46. for(i = 0;i < 8;i++)
  47. {
  48. inBuf[i] = i;
  49. outBuf[i] = 0;
  50. }
  51. _EINT();
  52. for(;;)
  53. {
  54. ReceiveMsg(outBuf);
  55. SendMsg(8,inBuf);
  56. }
  57. }
  58. void Init_CLK(void)
  59. {
  60.     unsigned int i;
  61.     BCSCTL1 = 0X00; //将寄存器的内容清零
  62. //XT2震荡器开启
  63. //LFTX1工作在低频模式
  64. //ACLK的分频因子为1
  65.     do 
  66.     {
  67. IFG1 &= ~OFIFG; // 清除OSCFault标志
  68. for (i = 0x20; i > 0; i--);                
  69.     }
  70.     while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1   
  71.     BCSCTL2 = 0X00; //将寄存器的内容清零
  72.     BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
  73.     BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
  74. }
  75. void Init_SPI (void)
  76. {
  77. //SPI0模块允许     
  78. ME1 |= USPIE0; 
  79. //将寄存器的内容清零
  80.     U0CTL = 0X00;
  81.     //数据为8比特,选择SPI模式,单片机为主机模式
  82.     U0CTL |= CHAR + SYNC + MM;
  83. //将寄存器的内容清零
  84.     U0TCTL = 0X00;
  85.     // 时钟源为SMCLK,选择3线模式
  86.     U0TCTL = CKPH + SSEL1 + SSEL0 + STC; 
  87. //传输时钟为SMCLK / 4
  88.     UBR0_0 = 0X02;  
  89.     UBR1_0 = 0X00;
  90. //调整寄存器,没有调整
  91.     UMCTL_0 = 0X00;     
  92. //发送接收中断允许
  93. IE1 |= UTXIE0; 
  94. IE1 |= URXIE0; 
  95. }
  96. void Init_Port(void)
  97. {
  98.     //将P3口所有的管脚在初始化的时候设置为输入方式
  99.     P3DIR = 0;
  100.     //将P3口所有的管脚设置为一般I/O口
  101.     P3SEL = 0;
  102. //P3.1 P3.2 P3.3被分配为SPI口
  103.     P3SEL = BIT3 + BIT2 + BIT1;
  104. //P1.0作为输出管脚
  105. P1DIR |= BIT0;
  106. //P3.3作为输出管脚
  107. P3DIR |= BIT3;
  108. //P3.1作为输出管脚
  109. P3DIR |= BIT1;
  110. //P1.0 输出高电平,MCP2510不被选通
  111. P1OUT |= BIT0; 
  112.     return;
  113. }
  114. void CS_Enable(void)
  115. {
  116. //P1.0输出低电平
  117. P1OUT &=~(BIT0);
  118. return ;
  119. }
  120. void CS_Disable(void)
  121. {
  122. //P1.0输出高电平
  123. P1OUT|=BIT0;
  124. return ;
  125. }
  126. interrupt [UART0TX_VECTOR] void UART0_TX_ISR(void)
  127. {
  128.     if(nTX0_Len != 0)
  129.     {
  130. // 表示缓冲区里的数据没有发送完
  131.      nTX0_Flag = 0;     
  132.      TXBUF0 = UART0_TX_BUF[nSend_TX0];
  133.      nSend_TX0 += 1;   
  134.      if(nSend_TX0 >= nTX0_Len)
  135.      {
  136.          nSend_TX0 = 0;
  137.          nTX0_Len = 0;
  138.          nTX0_Flag = 1;
  139.      }
  140.     }
  141. }
  142. interrupt [UART0RX_VECTOR] void UART0_RX_ISR(void)
  143. {
  144. //接收来自的数据
  145.     UART0_RX_BUF[nRX0_Len_temp] = RXBUF0;
  146.     
  147.     nRX0_Len_temp += 1;
  148. if(nRX0_Len_temp >= nRX0_Len)
  149. {
  150.         nRev_UART0 = 1;
  151.      nRX0_Len_temp = 0;
  152. nRX0_Len = 0;
  153. }
  154. }
  155. void RessetMcp2510(void)
  156. {
  157. int i;
  158. CS_Enable();
  159. for(i = 10;i > 0;i--) ;
  160. //复位命令
  161.     UART0_TX_BUF[0] = (char)(0xC0);
  162.     nTX0_Len = 1;
  163.     // 设置中断标志,进入发送中断程序
  164.     IFG1 |= UTXIFG0;
  165. for(i = 100;i > 0;i--) ;
  166. CS_Disable();
  167. return;
  168. }
  169. int GetStatusMcp2510(void)
  170. {
  171. int i;
  172. int nStatus = 0;
  173. CS_Enable();
  174. for(i = 10;i > 0;i--) ;
  175. //读状态命令
  176.     UART0_TX_BUF[0] = 0xA0;
  177.     nTX0_Len = 1;
  178.     // 设置中断标志,进入发送中断程序
  179.     IFG1 |= UTXIFG0;
  180. nRX0_Len = 1;
  181. while(1)
  182. {
  183. if(nRev_UART0 == 1)
  184. {
  185. nRev_UART0 = 0;
  186.             nStatus = (int)(UART0_RX_BUF[0]);
  187. break;
  188. }
  189. }
  190. for(i = 100;i > 0;i--) ;
  191. CS_Disable();
  192. return nStatus;
  193. }
  194. void RtsMcp2510(char RTSn)
  195. {
  196. int i;
  197. CS_Enable();
  198. for(i = 10;i > 0;i--) ;
  199. //请求发送命令
  200. UART0_TX_BUF[0] = (char)(0x80 | RTSn);
  201.     nTX0_Len = 1;
  202.     // 设置中断标志,进入发送中断程序
  203.     IFG1 |= UTXIFG0;
  204. for(i = 100;i > 0;i--) ;
  205. CS_Disable();
  206. return;
  207. }
  208. void BitModiMcp2510(char addr,char mask,char data)
  209. {
  210. int i;
  211. CS_Enable();
  212. for(i = 10;i > 0;i--) ;
  213. //位修改送命令
  214. UART0_TX_BUF[0] = 0x05;
  215. UART0_TX_BUF[0] = addr;
  216. UART0_TX_BUF[0] = mask;
  217. UART0_TX_BUF[0] = data;
  218.     nTX0_Len = 4;
  219.     // 设置中断标志,进入发送中断程序
  220.     IFG1 |= UTXIFG0;
  221. for(i = 100;i > 0;i--) ;
  222. CS_Disable();
  223. return;
  224. }
  225. void ReadMcp2510(int addr,int n,char outBuf[])
  226. {
  227. int i;
  228. CS_Enable();
  229. for(i = 10;i > 0;i--) ;
  230. //读命令
  231. UART0_TX_BUF[0] = 0x03;
  232. UART0_TX_BUF[0] = addr;
  233. for(i = 0;i < n;i++)
  234. {
  235. UART0_TX_BUF[i + 2] = 0;
  236. }
  237.     nTX0_Len = 2 + n;
  238.     // 设置中断标志,进入发送中断程序
  239.     IFG1 |= UTXIFG0;
  240. //接收数据
  241.     nRX0_Len = n;
  242. while(1)
  243. {
  244. if(nRev_UART0 == 1)
  245. {
  246. nRev_UART0 = 0;
  247. for(i = 0;i < n;i++)
  248. {
  249. outBuf[i] = UART0_RX_BUF[i];
  250. }
  251. break;
  252. }
  253. }
  254. for(i = 100;i > 0;i--) ;
  255. CS_Disable();
  256. return;
  257. }
  258. void WriteMcp2510(int addr,int n,char inBuf[])
  259. {
  260. int i;
  261. CS_Enable();
  262. for(i = 10;i > 0;i--) ;
  263. //写命令
  264. UART0_TX_BUF[0] = 0x02;
  265. UART0_TX_BUF[0] = addr;
  266. for(i = 0;i < n;i++)
  267. {
  268. UART0_TX_BUF[i + 2] = inBuf[i];
  269. }
  270.     nTX0_Len = 2 + n;
  271.     // 设置中断标志,进入发送中断程序
  272.     IFG1 |= UTXIFG0;
  273. for(i = 100;i > 0;i--) ;
  274. CS_Disable();
  275. return;
  276. }
  277. void SetNormal(void)
  278. {
  279.     int nFlag = 1;
  280. int i;
  281. char outBuf[10];
  282. for(i = 0;i < 10;i++)
  283. {
  284. outBuf[i] = 0;
  285. }
  286. //设置成正常模式
  287. BitModiMcp2510(CANSTAT,0xe0,0x00);
  288. do
  289. {
  290.         ReadMcp2510(CANSTAT,1,outBuf);
  291. nFlag = outBuf[0] & 0xe0;
  292. }while(nFlag);
  293.     return;
  294. }
  295. void IsSendComplete(int addr)
  296. {
  297. int i;
  298. int nFlag = 1;
  299. char outBuf[10];
  300. for(i = 0;i < 10;i++)
  301. {
  302. outBuf[i] = 0;
  303. }
  304. do
  305. {
  306.         ReadMcp2510(addr,1,outBuf);
  307. nFlag = outBuf[0] & 0x08;
  308. }while(nFlag);
  309.     return;
  310. }
  311. void InitMcp2510(void)
  312. {
  313. char inBuf[10];
  314. //复位
  315. RessetMcp2510();
  316. //设置拨特率
  317. inBuf[0] = 0x02;
  318. inBuf[1] = 0x90;
  319. inBuf[2] = 0x07;
  320.     WriteMcp2510(CNF3,3,inBuf);
  321. //RX0接收,屏蔽位为0,过滤器为0
  322.     inBuf[0] = 0x00;
  323. inBuf[1] = 0x00;
  324.     WriteMcp2510(RXM0SIDH,2,inBuf);
  325. inBuf[0] = 0x00;
  326. inBuf[1] = 0x00;
  327.     WriteMcp2510(RXF0SIDH,2,inBuf);
  328. //CAN中断不使能
  329.     inBuf[0] = 0x00;
  330.     WriteMcp2510(CANINTE,1,inBuf);
  331. //设置成正常模式
  332. SetNormal();
  333. }
  334. void SendMsg(int nDLC,char inBuf[])
  335. {
  336. int i;
  337. char sndBuf[16];
  338. for(i = 0;i < nDLC;i++)
  339. {
  340. sndBuf[i] = inBuf[i];
  341. }
  342. WriteMcp2510(TXB0D0,nDLC,sndBuf);
  343.     sndBuf[0] = nDLC;
  344.     WriteMcp2510(TXB0DLC,1,sndBuf);
  345.     sndBuf[0] = 0x03;
  346. sndBuf[1] = nRecID_Hi;
  347. sndBuf[2] = nRecID_Lo;
  348.     WriteMcp2510(TXB0CTRL,3,sndBuf);
  349. RtsMcp2510(0x01);
  350. IsSendComplete(TXB0CTRL);
  351. return;
  352. }
  353. int ReceiveMsg(char outBuf[])
  354. {
  355. int i;
  356. int nFlag;
  357. int nDLC;
  358. char revBuf[16];
  359. for(i = 0;i < 16;i++)
  360. {
  361. revBuf[i] = 0;
  362. }
  363. ReadMcp2510(CANINTF,1,revBuf);
  364.     nFlag = revBuf[0] & 0x01;
  365. if(nFlag == 0)
  366. {
  367. return 0;
  368. }
  369. BitModiMcp2510(CANINTF,0x01,0x00);
  370. ReadMcp2510(TXB0SIDH,2,revBuf);
  371. nRecID_Hi = revBuf[0];
  372. nRecID_Lo = revBuf[1] & 0xe0;
  373. ReadMcp2510(RXB0DLC,1,revBuf);
  374.     nDLC = revBuf[0] & 0x0f;
  375.     ReadMcp2510(RXB0D0,nDLC,outBuf);
  376. return 1;
  377. }