翻译的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);
         }
   }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值