找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1059|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

關(guān)于stc32g12k128-beta單片機(jī)自帶can的ID過濾配置

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1111967 發(fā)表于 2024-9-19 09:34 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
大家好,我最近剛接觸stc32g系列單片機(jī),聽說這個(gè)單片機(jī)自帶兩個(gè)can口很方便,發(fā)的程序我試過了,通過外接一個(gè)收發(fā)器和官方給的例程可以精準(zhǔn)的進(jìn)行can的發(fā)送。但是我試了下濾單個(gè)id就是解決不了,請(qǐng)教一下大家該如何配置總線驗(yàn)收寄存器。我需要過濾單個(gè)id為10040901報(bào)文
  1. #include"STC32G.h"
  2. #include "intrins.h"

  3. typedef         unsigned char        u8;
  4. typedef         unsigned int        u16;
  5. typedef         unsigned long        u32;

  6. #define MAIN_Fosc        24000000UL

  7. /****************************** 用戶定義宏 ***********************************/
  8. //CAN總線波特率=Fclk/((1+(TSG1+1)+(TSG2+1))*(BRP+1)*2)
  9. #define TSG1    2                //0~15
  10. #define TSG2    1                //1~7 (TSG2 不能設(shè)置為0)
  11. #define BRP     3                //0~63
  12. //24000000/((1+3+2)*4*2)=500KHz

  13. #define SJW     1                //重新同步跳躍寬度

  14. //總線波特率100KHz以上設(shè)置為 0; 100KHz以下設(shè)置為 1
  15. #define SAM     0                //總線電平采樣次數(shù): 0:采樣1次; 1:采樣3次

  16. /*****************************************************************************/


  17. /*************  本地常量聲明    **************/

  18. #define Timer0_Reload   (65536UL -(MAIN_Fosc / 1000))       //Timer 0 中斷頻率, 1000次/秒

  19. #define        STANDARD_FRAME   0     //幀格式:標(biāo)準(zhǔn)幀
  20. #define        EXTENDED_FRAME   1     //幀格式:擴(kuò)展幀

  21. /*************  本地變量聲明    **************/

  22. typedef struct
  23. {
  24.         u8        DLC:4;          //數(shù)據(jù)長(zhǎng)度, bit0~bit3
  25.         u8        :2;             //空數(shù)據(jù), bit4~bit5
  26.         u8        RTR:1;          //幀類型, bit6
  27.         u8        FF:1;           //幀格式, bit7
  28.         u32        ID;             //CAN ID
  29.         u8        DataBuffer[8];  //數(shù)據(jù)緩存
  30. }CAN_DataDef;

  31. CAN_DataDef CAN1_Tx;
  32. CAN_DataDef CAN1_Rx[8];

  33. bit B_CanRead;      //CAN 收到數(shù)據(jù)標(biāo)志
  34. bit B_1ms;          //1ms標(biāo)志
  35. u16 msecond;

  36. /*************  本地函數(shù)聲明    **************/
  37. void CANInit();
  38. u8 CanReadReg(u8 addr);
  39. u8 CanReadMsg(CAN_DataDef *CAN);
  40. void CanSendMsg(CAN_DataDef *CAN);

  41. void Delay1000ms(void)        //@24.000MHz
  42. {
  43.         unsigned long edata i;

  44.         _nop_();
  45.         _nop_();
  46.         i = 5999998UL;
  47.         while (i) i--;
  48. }

  49. /********************* 主函數(shù) *************************/
  50. void main(void)
  51. {
  52.         u8 sr,i,n;
  53.                

  54.     WTST = 0;  //設(shè)置程序指令延時(shí)參數(shù),賦值為0可將CPU執(zhí)行指令的速度設(shè)置為最快
  55.     EAXFR = 1; //擴(kuò)展寄存器(XFR)訪問使能
  56.     CKCON = 0; //提高訪問XRAM速度

  57.     P0M1 = 0x30;   P0M0 = 0x30;   //設(shè)置P0.4、P0.5為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  58.     P1M1 = 0x32;   P1M0 = 0x32;   //設(shè)置P1.1、P1.4、P1.5為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V), P1.1在PWM當(dāng)DAC電路通過電阻串聯(lián)到P2.3
  59.     P2M1 = 0x3c;   P2M0 = 0x3c;   //設(shè)置P2.2~P2.5為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  60.     P3M1 = 0x50;   P3M0 = 0x50;   //設(shè)置P3.4、P3.6為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  61.     P4M1 = 0x3c;   P4M0 = 0x3c;   //設(shè)置P4.2~P4.5為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  62.     P5M1 = 0x0c;   P5M0 = 0x0c;   //設(shè)置P5.2、P5.3為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  63.     P6M1 = 0xff;   P6M0 = 0xff;   //設(shè)置為漏極開路(實(shí)驗(yàn)箱加了上拉電阻到3.3V)
  64.     P7M1 = 0x00;   P7M0 = 0x00;   //設(shè)置為準(zhǔn)雙向口

  65.         AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
  66.         TH0 = (u8)(Timer0_Reload / 256);
  67.         TL0 = (u8)(Timer0_Reload % 256);
  68.         ET0 = 1;    //Timer0 interrupt enable
  69.         TR0 = 1;    //Tiner0 run

  70.         CANInit();
  71.         
  72.         EA = 1;                 //打開總中斷

  73.         CAN1_Tx.FF = EXTENDED_FRAME;    //擴(kuò)展幀
  74.         CAN1_Tx.RTR = 0;                //0:數(shù)據(jù)幀,1:遠(yuǎn)程幀
  75.         CAN1_Tx.DLC = 0x08;             //數(shù)據(jù)長(zhǎng)度
  76.         CAN1_Tx.ID = 0x11040109;        //CAN ID
  77.         CAN1_Tx.DataBuffer[0] = 0x00;   //數(shù)據(jù)內(nèi)容
  78.         CAN1_Tx.DataBuffer[1] = 0x00;
  79.         CAN1_Tx.DataBuffer[2] = 0x30;
  80.         CAN1_Tx.DataBuffer[3] = 0x00;
  81.         CAN1_Tx.DataBuffer[4] = 0x00;
  82.         CAN1_Tx.DataBuffer[5] = 0x00;
  83.         CAN1_Tx.DataBuffer[6] = 0x80;
  84.         CAN1_Tx.DataBuffer[7] = 0x00;
  85.                 P54 = 0;
  86.         Delay1000ms();
  87.         P54 = 1;
  88.         while(1)
  89.         {
  90.                 if(B_1ms)   //1ms到
  91.                 {
  92.                         B_1ms = 0;
  93.                         if(++msecond >= 1000)   //1秒到
  94.                         {
  95.                                 msecond = 0;
  96.                                 sr = CanReadReg(SR);

  97.                                 if(sr & 0x01)                //判斷是否有 BS:BUS-OFF狀態(tài)
  98.                                 {
  99.                                         CANAR = MR;
  100.                                         CANDR &= ~0x04;  //清除 Reset Mode, 從BUS-OFF狀態(tài)退出
  101.                                 }
  102.                                 else
  103.                                 {
  104.                     CanSendMsg(&CAN1_Tx);   //發(fā)送一幀數(shù)據(jù)
  105.                                 }
  106.                         }
  107.                 }

  108.                 if(B_CanRead)
  109.                 {
  110.                         B_CanRead = 0;
  111.                         
  112.             n = CanReadMsg(CAN1_Rx);    //讀取接收內(nèi)容
  113.             if(n>0)
  114.             {
  115.                 for(i=0;i<n;i++)
  116.                 {
  117.                     CanSendMsg(&CAN1_Rx[i]);  //CAN總線原樣返回
  118.                 }
  119.             }
  120.                 }
  121.         }
  122. }


  123. /********************** Timer0 1ms中斷函數(shù) ************************/
  124. void timer0 (void) interrupt 1
  125. {
  126.     B_1ms = 1;      //1ms標(biāo)志
  127. }

  128. //========================================================================
  129. // 函數(shù): u8 ReadReg(u8 addr)
  130. // 描述: CAN功能寄存器讀取函數(shù)。
  131. // 參數(shù): CAN功能寄存器地址.
  132. // 返回: CAN功能寄存器數(shù)據(jù).
  133. // 版本: VER1.0
  134. // 日期: 2020-11-16
  135. // 備注:
  136. //========================================================================
  137. u8 CanReadReg(u8 addr)
  138. {
  139.         u8 dat;
  140.         CANAR = addr;
  141.         dat = CANDR;
  142.         return dat;
  143. }

  144. //========================================================================
  145. // 函數(shù): void WriteReg(u8 addr, u8 dat)
  146. // 描述: CAN功能寄存器配置函數(shù)。
  147. // 參數(shù): CAN功能寄存器地址, CAN功能寄存器數(shù)據(jù).
  148. // 返回: none.
  149. // 版本: VER1.0
  150. // 日期: 2020-11-16
  151. // 備注:
  152. //========================================================================
  153. void CanWriteReg(u8 addr, u8 dat)
  154. {
  155.         CANAR = addr;
  156.         CANDR = dat;
  157. }

  158. //========================================================================
  159. // 函數(shù): void CanReadFifo(CAN_DataDef *CANx)
  160. // 描述: 讀取CAN緩沖區(qū)數(shù)據(jù)函數(shù)。
  161. // 參數(shù): *CANx: 存放CAN總線讀取數(shù)據(jù).
  162. // 返回: none.
  163. // 版本: VER2.0
  164. // 日期: 2023-01-31
  165. // 備注:
  166. //========================================================================
  167. void CanReadFifo(CAN_DataDef *CAN)
  168. {
  169.     u8 i;
  170.     u8 pdat[5];
  171.     u8 RX_Index=0;

  172.     pdat[0] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));

  173.     if(pdat[0] & 0x80)  //判斷是標(biāo)準(zhǔn)幀還是擴(kuò)展幀
  174.     {
  175.         pdat[1] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //擴(kuò)展幀ID占4個(gè)字節(jié)
  176.         pdat[2] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
  177.         pdat[3] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
  178.         pdat[4] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
  179.         CAN->ID = (((u32)pdat[1] << 24) + ((u32)pdat[2] << 16) + ((u32)pdat[3] << 8) + pdat[4]) >> 3;
  180.     }
  181.     else
  182.     {
  183.         pdat[1] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //標(biāo)準(zhǔn)幀ID占2個(gè)字節(jié)
  184.         pdat[2] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
  185.         CAN->ID = ((pdat[1] << 8) + pdat[2]) >> 5;
  186.     }

  187.     CAN->FF = pdat[0] >> 7;     //幀格式
  188.     CAN->RTR = pdat[0] >> 6;    //幀類型
  189.     CAN->DLC = pdat[0];         //數(shù)據(jù)長(zhǎng)度

  190.     for(i=0;((i<CAN->DLC) && (i<8));i++)        //讀取數(shù)據(jù)長(zhǎng)度為len,最多不超過8
  191.     {
  192.         CAN->DataBuffer[i] = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));   //讀取有效數(shù)據(jù)
  193.     }
  194.     while(RX_Index&3)   //判斷已讀數(shù)據(jù)長(zhǎng)度是否4的整數(shù)倍
  195.     {
  196.         CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));  //讀取填充數(shù)據(jù),一幀數(shù)據(jù)占據(jù)4的整數(shù)倍緩沖區(qū)空間,不足補(bǔ)0
  197.     }
  198. }

  199. //========================================================================
  200. // 函數(shù): u8 CanReadMsg(void)
  201. // 描述: CAN接收數(shù)據(jù)函數(shù)。
  202. // 參數(shù): *CANx: 存放CAN總線讀取數(shù)據(jù)..
  203. // 返回: 幀個(gè)數(shù).
  204. // 版本: VER2.0
  205. // 日期: 2023-01-31
  206. // 備注:
  207. //========================================================================
  208. u8 CanReadMsg(CAN_DataDef *CAN)
  209. {
  210.     u8 i;
  211.     u8 n=0;

  212.     do{
  213.         CanReadFifo(&CAN[n++]);  //讀取接收緩沖區(qū)數(shù)據(jù)
  214.         i = CanReadReg(SR);
  215.     }while(i&0x80);     //判斷接收緩沖區(qū)里是否還有數(shù)據(jù),有的話繼續(xù)讀取

  216.     return n;   //返回幀個(gè)數(shù)
  217. }

  218. //========================================================================
  219. // 函數(shù): void CanSendMsg(CAN_DataDef *CAN)
  220. // 描述: CAN發(fā)送標(biāo)準(zhǔn)幀函數(shù)。
  221. // 參數(shù): *CANx: 存放CAN總線發(fā)送數(shù)據(jù)..
  222. // 返回: none.
  223. // 版本: VER1.0
  224. // 日期: 2020-11-19
  225. // 備注:
  226. //========================================================================
  227. void CanSendMsg(CAN_DataDef *CAN)
  228. {
  229.         u32 CanID;
  230.     u8 RX_Index,i;

  231.     if(CAN->FF)     //判斷是否擴(kuò)展幀
  232.     {
  233.         CanID = CAN->ID << 3;
  234.         CanWriteReg(TX_BUF0,CAN->DLC|((u8)CAN->RTR<<6)|0x80);        //bit7: 標(biāo)準(zhǔn)幀(0)/擴(kuò)展幀(1), bit6: 數(shù)據(jù)幀(0)/遠(yuǎn)程幀(1), bit3~bit0: 數(shù)據(jù)長(zhǎng)度(DLC)
  235.         CanWriteReg(TX_BUF1,(u8)(CanID>>24));
  236.         CanWriteReg(TX_BUF2,(u8)(CanID>>16));
  237.         CanWriteReg(TX_BUF3,(u8)(CanID>>8));

  238.         CanWriteReg(TX_BUF0,(u8)CanID);

  239.         RX_Index = 1;
  240.         for(i=0;((i<CAN->DLC) && (i<8));i++)        //數(shù)據(jù)長(zhǎng)度為DLC,最多不超過8
  241.         {
  242.             CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),CAN->DataBuffer[i]);   //寫入有效數(shù)據(jù)
  243.         }
  244.         while(RX_Index&3)   //判斷已讀數(shù)據(jù)長(zhǎng)度是否4的整數(shù)倍
  245.         {
  246.             CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),0x00);  //寫入填充數(shù)據(jù),一幀數(shù)據(jù)占據(jù)4的整數(shù)倍緩沖區(qū)空間,不足補(bǔ)0
  247.         }
  248.     }
  249.     else    //發(fā)送標(biāo)準(zhǔn)幀
  250.     {
  251.         CanID = (u16)(CAN->ID << 5);
  252.         CanWriteReg(TX_BUF0,CAN->DLC|((u8)CAN->RTR<<6));  //bit7: 標(biāo)準(zhǔn)幀(0)/擴(kuò)展幀(1), bit6: 數(shù)據(jù)幀(0)/遠(yuǎn)程幀(1), bit3~bit0: 數(shù)據(jù)長(zhǎng)度(DLC)
  253.         CanWriteReg(TX_BUF1,(u8)(CanID>>8));
  254.         CanWriteReg(TX_BUF2,(u8)CanID);

  255.         RX_Index = 3;
  256.         for(i=0;((i<CAN->DLC) && (i<8));i++)        //數(shù)據(jù)長(zhǎng)度為DLC,最多不超過8
  257.         {
  258.             CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),CAN->DataBuffer[i]);   //寫入有效數(shù)據(jù)
  259.         }
  260.         while(RX_Index&3)   //判斷已讀數(shù)據(jù)長(zhǎng)度是否4的整數(shù)倍
  261.         {
  262.             CanWriteReg((u8)(TX_BUF0 + (RX_Index++&3)),0x00);  //寫入填充數(shù)據(jù),一幀數(shù)據(jù)占據(jù)4的整數(shù)倍緩沖區(qū)空間,不足補(bǔ)0
  263.         }
  264.     }
  265.         CanWriteReg(CMR ,0x04);                //發(fā)起一次幀傳輸
  266. }

  267. //========================================================================
  268. // 函數(shù): void CANSetBaudrate()
  269. // 描述: CAN總線波特率設(shè)置函數(shù)。
  270. // 參數(shù): none.
  271. // 返回: none.
  272. // 版本: VER1.0
  273. // 日期: 2020-11-19
  274. // 備注:
  275. //========================================================================
  276. void CANSetBaudrate()
  277. {
  278.         CanWriteReg(BTR0,(SJW << 6) + BRP);
  279.         CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
  280. }

  281. //========================================================================
  282. // 函數(shù): void CANInit()
  283. // 描述: CAN初始化函數(shù)。
  284. // 參數(shù): none.
  285. // 返回: none.
  286. // 版本: VER1.0
  287. // 日期: 2020-11-19
  288. // 備注:
  289. //========================================================================
  290. void CANInit()
  291. {
  292.         CANEN = 1;          //CAN1模塊使能
  293.         CanWriteReg(MR  ,0x05);  //使能 Reset Mode, 采用單濾波設(shè)置

  294.         CANSetBaudrate();        //設(shè)置波特率
  295.         
  296.         //設(shè)置過濾ID為:xxF8xxxx 的幀才接收
  297.         CanWriteReg(ACR0,0x80);                //總線驗(yàn)收代碼寄存器
  298.         CanWriteReg(ACR1,0x20);
  299.         CanWriteReg(ACR2,0x48);
  300.         CanWriteReg(ACR3,0x08);
  301.         CanWriteReg(AMR0,0x80);                //總線驗(yàn)收屏蔽寄存器
  302.         CanWriteReg(AMR1,0x20);
  303.         CanWriteReg(AMR2,0x48);
  304.         CanWriteReg(AMR3,0x08);

  305.         //取消過濾ID,所有幀都接收
  306. //        CanWriteReg(ACR0,0x00);                //總線驗(yàn)收代碼寄存器
  307. //        CanWriteReg(ACR1,0x00);
  308. //        CanWriteReg(ACR2,0x00);
  309. //        CanWriteReg(ACR3,0x00);
  310. //        CanWriteReg(AMR0,0xFF);                //總線驗(yàn)收屏蔽寄存器
  311. //        CanWriteReg(AMR1,0xFF);
  312. //        CanWriteReg(AMR2,0xFF);
  313. //        CanWriteReg(AMR3,0xFF);

  314.         CanWriteReg(IMR ,0xff);                //中斷寄存器
  315.         CanWriteReg(ISR ,0xff);                //清中斷標(biāo)志
  316.         CanWriteReg(MR  ,0x01);                //退出 Reset Mode, 采用單濾波設(shè)置(設(shè)置過濾器后注意選擇濾波模式)
  317. //        CanWriteReg(MR  ,0x00);                //退出 Reset Mode, 采用雙濾波設(shè)置(設(shè)置過濾器后注意選擇濾波模式)

  318.         P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切換(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.1  0x10:P5.0,P5.1  0x20:P4.2,P4.5  0x30:P7.0,P7.1
  319.         CANICR = 0x02;                //CAN中斷使能
  320. }

  321. //========================================================================
  322. // 函數(shù): void CANBUS_Interrupt(void) interrupt CAN1_VECTOR
  323. // 描述: CAN總線中斷函數(shù)。
  324. // 參數(shù): none.
  325. // 返回: none.
  326. // 版本: VER1.0
  327. // 日期: 2020-11-19
  328. // 備注:
  329. //========================================================================
  330. void CANBUS_Interrupt(void) interrupt CAN1_VECTOR
  331. {
  332.         u8 isr;
  333.         u8 arTemp;
  334.         arTemp = CANAR;     //CANAR現(xiàn)場(chǎng)保存,避免主循環(huán)里寫完 CANAR 后產(chǎn)生中斷,在中斷里修改了 CANAR 內(nèi)容
  335.         
  336.         isr = CanReadReg(ISR);
  337.         if((isr & 0x04) == 0x04)  //TI
  338.     {
  339.                 CANAR = ISR;
  340.                 CANDR = 0x04;    //CLR FLAG
  341.     }        
  342.         if((isr & 0x08) == 0x08)  //RI
  343.     {
  344.                 CANAR = ISR;
  345.                 CANDR = 0x08;    //CLR FLAG
  346.         
  347.                 B_CanRead = 1;
  348.     }

  349.         if((isr & 0x40) == 0x40)  //ALI
  350.     {
  351.                 CANAR = ISR;
  352.                 CANDR = 0x40;    //CLR FLAG
  353.     }        

  354.         if((isr & 0x20) == 0x20)  //EWI
  355.     {
  356.                 CANAR = ISR;
  357.                 CANDR = 0x20;    //CLR FLAG
  358.     }        

  359.         if((isr & 0x10) == 0x10)  //EPI
  360.     {
  361.                 CANAR = ISR;
  362.                 CANDR = 0x10;    //CLR FLAG
  363.     }        

  364.         if((isr & 0x02) == 0x02)  //BEI
  365.     {
  366.                 CANAR = ISR;
  367.                 CANDR = 0x02;    //CLR FLAG
  368.     }        

  369.         if((isr & 0x01) == 0x01)  //DOI
  370.     {
  371.                 CANAR = ISR;
  372.                 CANDR = 0x01;    //CLR FLAG
  373.     }        

  374.         CANAR = arTemp;    //CANAR現(xiàn)場(chǎng)恢復(fù)
  375. }
復(fù)制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

板凳
ID:1111967 發(fā)表于 2024-9-20 09:15 | 只看該作者
lrkeji1982 發(fā)表于 2024-9-19 11:57
手冊(cè)上有說明,這個(gè)是可以過濾的,我用過

精準(zhǔn)的過濾一個(gè)很難算,我找到了一個(gè)軟件可以直接算出來,謝謝回復(fù)
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:314246 發(fā)表于 2024-9-19 11:57 | 只看該作者
手冊(cè)上有說明,這個(gè)是可以過濾的,我用過

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表