翻譯的CCS CAN例程

準備用PIC18F458芯片在CCS編譯器下開始CAN總線的學習,在開始之前首先找來了官方的例程,對照看下。

看英文頭大,翻譯成中文註釋,看着舒服些。


安裝完CCS後,原文件位置...\PICC\Examples\ex_can_ccs_a.c




///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////                         EX_CAN_CCS_A.C                        
////                                                                
//// 例子使用CCS的CAN庫函數, 可以用於 PIC18Fxx8, PIC24 或者dsPIC33. 
////此示例進行了測試 使用 CCS讀寫CAN原型板 CAN Bus 和CAN Bus 24.    
////                                                                
////CCS原型電路板有四個相互連接的CAN節點                            
////節點 A 是一個 18F458, CAN Bus, 或者24HJ256GP7610, CAN Bus 24, 使用內部CAN及外圍設備.                                         

////節點 B 是一個 PIC16F87x, CAN Bus, 或者 30F4011, CAN Bus 24,連接到一個額外的 MCP2510 CAN

////外圍設備, 然而節點 C 和節點 D 都是 MCP250xx 獨立CAN I / O擴展器.                                  

//// 這個例子是節點A的固件                                          
////                                                                
//// 每兩秒鐘,這的固件發出了一個命令到節點B                        
//// 去改變節點B leds (CAN ID 0x202)   的狀態                       
////                                                                
//// 通過A/D讀取值得變化, 一個 0-9的數值被送到                      
//// 節點 D 將此數值顯示在一個 8段 LCD數碼管上 (CAN ID 0x400)       
////                                                                

//// 通過按下節點A 中的按鈕, 向節點B發送一個請求  (CAN ID 0x201) 通過讀節點B中 A/D 的數值,

////節點B將通過CAN把讀來的A/d數值發出(with CAN ID 0x201).                                       

//// 同時, 按下節點A 中的按鈕將會改變節點C中LED燈的狀態(CAN ID 0x300)
////                                 
//// 按節點C中的按鈕會導致節點A的按鈕發生改變                       
//// (節點 C 發送按鈕變化 CAN ID 0x303)                             
////                                                                
//// 使用串行端口,您可以檢查所有 CAN 通訊 比如:觀察18xxx8 或者 PIC24HJ.                                       
////                                                                
//// 想要了解在CCS上更多的CAN庫文件, 可以看到 can-18xxx8.c 和 can-PIC24.c                                                 
////                                                                
//// 這個例子只可以工作在PCH 和 PCD 編譯器                          
////                                                                
////                      官方例程,羊兄臺翻譯                     
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                                                
//// 連接CCS CAN原型板時的波特率設置                                
//// 板頻率 20Mhz:                                                  
////                                                                
////  PIC18Fxx8 設備                                               
////                                                                
////    Baud Rate Prescalar: 4                    //波特率預分頻           
////    Propagation Segment: 3xTq            //傳播段                  
////    Phase Segment 1: 6xTq                   //相位緩衝段1             
////    Phase Segment 2: 6xTq                   //相位緩衝段2            
////    Synchronized Jump Width: 1xTq     //同步跳轉寬度           
////    Sample Rate: 1x                                //採樣率                
////    Wakeup Filter:  Off                             //喚醒過濾器             
////                                                               
////  PIC24HJ 和 dsPIC33FJ 設備             //同上                    
////                                                                
////    Baud Rate Prescalar: 4                                    
////    Propagation Segment: 3xTq                                  
////    Phase Segment 1: 2xTq                                      
////    Phase Segment 2: 2xTq                                       
////    Synchronized Jump Width: 1xTq                               
////    Sample Rate: 1x                                            
////    Wakeup Filter:  Off
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                                                          

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2010 Custom Computer Services        

//// This source code may only be used by licensed users of the CCS C compiler.  This source code may only be distributed to other

//// licensed users of the CCS C compiler.  No other use,  reproduction or distribution is permitted without written permission.  ////Derivative programs created using this software in object code form are not restricted in any way.             
//// 版權信息 翻譯:羊兄臺(billy)                                   
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define CAN_DO_DEBUG TRUE

#if defined(__PCD__)
 #include <24HJ256GP610.h>
 #fuses PR,HS,NOWDT                       
 #device adc=12
 #use delay(clock=20MHz)                  //使用20M晶振
 #use rs232(UART1, baud=9600)             //使用UART1,波特率9600
 
 #define CAN_BRG_PRESCALAR           4    //設置CAN波特率爲125K
 #define CAN_BRG_PHASE_SEGMENT_1     1    //Tq = (2(1+PRESCALAR))/(Fosc/2)
 #define CAN_BRG_PHASE_SEGMENT_2     1    //Tq = (2(1+4)/(20000000/2) = 0.000001
 #define CAN_BRG_PROPAGATION_TIME    2    //Baud Rate = 1/(((PHASE_SEGMENT_1+1)+(PHASE_SEGMENT_2+1)+(PROPAGATION_TIME+1)+(JUMP_WIDTH+1))*Tq)
 #define CAN_BRG_SYNCH_JUMP_WIDTH    0    //Baud Rate = 1/(((1+1)+(1+1)+(2+1)+(0+1))*0.000001) = 125000
 
 #include <can-PIC24.c>
 
 #define PIN_LED1 PIN_B4
 #define PIN_LED2 PIN_A5
 #define PIN_LED3 PIN_B1
#else
 #include <18F458.h>
 #fuses HS,NOPROTECT,NOLVP,NOWDT          //配置HS晶振,不用代碼保護,不準低壓編程,不用看門狗
 #use delay(clock=20000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
 
 #include <can-18xxx8.c>                                        //CAN驅動庫文件
 
 #define PIN_LED1  PIN_A5
 #define PIN_LED2  PIN_B5
 #define PIN_LED3  PIN_B4
#endif


//定義LED燈狀態
#define LED1_HIGH output_low(PIN_LED1)
#define LED1_LOW  output_high(PIN_LED1)
#define LED2_HIGH output_low(PIN_LED2)
#define LED2_LOW  output_high(PIN_LED2)
#define LED3_HIGH output_low(PIN_LED3)
#define LED3_LOW  output_high(PIN_LED3)
//定義按鍵
#define BUTTON    PIN_A4

#define BUTTON_PRESSED  !input(BUTTON)

int16 ms;
//lcd顯示字段
const char lcd_seg[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};   //0 for on, 1 for off
//定時器2 溢出中斷
#int_timer2
void isr_timer2(void) {
   ms++; //運行的定時器,產生需要的時鐘
}

#define ASK_FOR_ID_AD_B      0x201  //向端口B的CAN要AD數據
#define SET_LED_ID_B         0x202       //給端口B的CAN設置LED值
#define RESPOND_TO_LED_C_ID  0x303
#define WRITE_REGISTER_C_ID  0x300
#define WRITE_REGISTER_D_ID  0x400

void main() {
   int8 b_leds=0;
   int8 c_leds=1;
   int8 a_leds=0;
   struct rx_stat rxstat;
   unsigned int32 rx_id;
   unsigned int8 buffer[8];
   int8 rx_len;

   unsigned int8 curr_lcd_output,last_lcd_output=0xFF;
   #if defined(__PCD__)
      unsigned int16 i;
   #else
      int8 i;
   #endif

   #if defined(__PCD__)
      setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);
      setup_adc_ports(sAN20 | VSS_VDD);
      set_adc_channel(20);
   #else
      setup_port_a(RA0_ANALOG);
      setup_adc(ADC_CLOCK_INTERNAL);
      set_adc_channel(0);
   #endif
   
   for(i=0;i<8;i++) {
      buffer[i]=0;
   }

   LED1_HIGH;
   LED2_HIGH;
   LED3_HIGH;
   printf("\r\n\r\nCCS CAN EXAMPLE\r\n");
   delay_ms(1000);
   LED1_LOW;
   LED2_LOW;
   LED3_LOW;

   #if defined(__PCD__)
      setup_timer2(TMR_INTERNAL,10000);   //設置定時器中斷每1ms,如果使用20MHz的時鐘
   #else
      setup_timer_2(T2_DIV_BY_4,79,16);       //設置定時器中斷每1ms,如果使用20MHz的時鐘
   #endif

   can_init();
   #if defined(__PCD__)
      can_enable_b_transfer(TRB0);  //緩衝器0發送緩衝器
   #endif

   enable_interrupts(INT_TIMER2);
   #if defined(__PCD__)
      enable_interrupts(INTR_GLOBAL);
   #else
      enable_interrupts(GLOBAL);
   #endif

   printf("\r\nRunning...");

   while(TRUE)
   {
      if ( can_kbhit() )
      {
         printf("\r\n");
         if(can_getd(rx_id, &buffer[0], rx_len, rxstat)) {
            if (rx_id == ASK_FOR_ID_AD_B) {
               printf("Channel B AD: %X\r\n",buffer[0]);
            }
            else if (rx_id == RESPOND_TO_LED_C_ID) {  //節點C是一種mcp250x0的發出了一個信息,在邊緣檢測IO
               printf("Chaning LEDs\r\n");            //in_data[0]=iointfl, in_data[1]=gpio
               a_leds=~(buffer[1]);
               if (bit_test(a_leds,4)) {LED1_HIGH;} else {LED1_LOW;}
               if (bit_test(a_leds,5)) {LED2_HIGH;} else {LED2_LOW;}
               if (bit_test(a_leds,6)) {LED3_HIGH;} else {LED3_LOW;}
            }
         }
      }

      if ( can_tbe() && (ms > 2000))       //當發送緩衝器爲空,每兩秒鐘,發送新數據
      {
         ms=0;

         //改變b端口LED狀態
         printf("\r\n\r\nSet LEDs on Port B to %U",b_leds);
         can_putd(SET_LED_ID_B, &b_leds, 1, 1, 1, 0);
         b_leds++;
         if (b_leds > 7) {b_leds=0;}
      }

      if (BUTTON_PRESSED) {
         while (BUTTON_PRESSED) {}
         delay_ms(200);

         //從端口b要AD數據
         printf("\r\n\r\nAsking for A/D reading on Port B...");
         can_putd(ASK_FOR_ID_AD_B, &buffer[0], 0, 1, 1, 0);

         //改變c端口LED狀態
         buffer[0]=0x1E;            //addr of gplat on 25050
         buffer[1]=0x0E;            //mask
         buffer[2]=~(c_leds << 1);  //new gplat values
         printf("\r\nIncrementing LED on Port C");
         can_putd(WRITE_REGISTER_C_ID, &buffer[0], 3, 1, 1, 0);
         c_leds++;
         if (c_leds > 7) {c_leds=0;}
      }

         //改變端口d的led字段
         i=read_adc();
         curr_lcd_output=i/410;   //scale to 0-9
         if (curr_lcd_output != last_lcd_output) {
            last_lcd_output=curr_lcd_output;
            printf("\r\nChanging 8-seg LCD on D to current A/D reading (%X, %X)",i,curr_lcd_output);
            buffer[0]=0x1E;                    //addr of gplat
            buffer[1]=0x7F;             //mask
            buffer[2]=lcd_seg[curr_lcd_output];                //new gplat values
            can_putd(WRITE_REGISTER_D_ID, &buffer[0], 3, 1, 1, 0);
         }
   }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章