PICマイコンを使って測定ツールを作ってみよう(6) ―― PIC12F1822を搭載したRS-485ネットワーク対応のセンサ基板を作成

中西 紫朗

tag: 組み込み 電子回路

エレキ系DIY 2011年12月 7日

●PIC18F2550のファームウェアは初期化の部分を修正

 マルチインターフェースPICマイコン基板に搭載しているPIC18F2550用のファームウェアも,前回とあまり変わっていません.前回,動作が不安定だったところを修正しています.初期値が設定されていないため,不安定になっていました.PICマイコンでは,変数を定義しても0にクリアされている保証がありません.動作を確実にするためには,初期化のときに0を代入する必要があります.

 リスト2にソース・コードを示します.

 

リスト2 PIC18F2550のファームウェアのソース・コード(userM110525.c)

/*********************************************************************
 *
 *                Microchip USB C18 Firmware Version 1.2
 *
 *********************************************************************
 * FileName:        user.c
 * Dependencies:    See INCLUDES section below
 * Processor:       PIC18
 * Compiler:        C18 3.11+
 * Company:         Microchip Technology, Inc.
 *
 *
 * Author               Date        Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Shiroh Nakanishi  08/09/09    Original.
 * Shiroh Nakanishi  08/10/09 Added the counter function.
 * Shiroh Nakanishi     08/28/09    Added SW status initialize.
 * Shiroh Nakanishi     11/03/10    Added ADC function.
 * Shiroh Nakanishi     11/07/10    Added RS485/UART control.
 * Shiroh Nakanishi     05/22/11    Split MASTER & SLAVE version
 * Shiroh Nakanishi     05/25/11    Modified USB command interpreter
 * Shiroh Nakanishi     05/28/11    Added RS485_UART init/putc/getc.
 * Shiroh Nakanishi     06/02/11    Fixed Network comm error
 * Shiroh Nakanishi     08/04/11    Modified RS485 Master Hook for Temperature Measure.
 * Shiroh Nakanishi     09/08/11    Added Stand-Alone UART RS485 function.
 * Shiroh Nakanishi     09/10/11    Added COUNTER option (CLOCK or Event)
 * Shiroh Nakanishi     09/11/11    Added UART option (9600/14400/57600bps)
 ********************************************************************/

/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "typedefs.h"
#include "usb.h"
#include "io_cfg.h"             // I/O pin mapping
#include "user.h"
#include "stdio.h"
#include "string.h"

//#include "i2c.h"

/** V A R I A B L E S ********************************************************/
#pragma udata
#define uart_ptr_max 32
char input_buffer[16];
char output_buffer[16];


//rom char welcome[]={"Full-Speed USB - CDC RS-232 Emulation Demo\r\n\r\n"};
rom char welcome[]={"Full-Speed USB - CDC RS-232 Emulation Demo\r\n\r\n"};
rom char ansi_clrscr[]={"\x1b[2J"};         // ANSI Clear Screen Command
rom char lastmessage[]={"Start Demo\r\n"};         // ANSI Clear Screen Command
#define E 2  // RB2  LCD R
#define RS 3 // RB3  LCD RS
#define Reset_RS485 0xC0
#define Ping 0xC1
#define Read 0xC2
#define Write 0xC3
#define SAmode 0xC4
#define RReset_RS485 0x0
#define RPing 0x1
#define RRead 0x2
#define RWrite 0x3
#define myID 10

/** P R I V A T E  P R O T O T Y P E S ***************************************/
void InitializeUSART(void);
void InitializeI2C(void);
//void BlinkUSBStatus(void);
BOOL Switch2IsPressed(void);
BOOL Switch3IsPressed(void);

void Exercise_Example(void);
void COMM_USB(void);
void WR_EEPROM(byte address, byte data);
byte RD_EEPROM(byte address);
void CONN_ALL_OFF(byte device);
void CONN_ALL_ON(void);
void CONN_ON(byte ASD_type, byte ASD_num);
void namecpy(byte i, byte j, byte length);
void LCDmenu2(void);
void LCDcontrol(byte data);
void LCDlocate(byte data);
void LCDstring(char *ptr, byte n);
void LCDwrite(byte data);
void waitmsec(byte wait);
void waitusec(byte wait);
void put_UART(byte data);
void Send_RS485(byte CMND,byte ID,byte n);
int get_UART(byte data);
int Rcv_RS485(byte *msg);

/** D E C L A R A T I O N S **************************************************/

rom char mn3C[] = { "19200bps" };
rom char mn3D[] = { "57600bps" };

#pragma code
static char UART_rd_buffer[uart_ptr_max];
static char UART_wr_buffer[uart_ptr_max];
static byte uart_wr_ptr,uart_rd_ptr,uart_buf_bytes,n_uart_wrbuf,uart_rcv_complete;
static byte ctstart,REGC7,COM_stage,SW[3];
static byte message_state = 0;
byte CMND,ID,LEN,msg[13],MA,nSA,SA[12];
static byte aa[32] = { "aaaaaaa\r\n" };
static byte va1[18] = { "        " };
const byte tt[12] = { "MULTI   " };
const byte tt2[12] = { " MONITOR" };
const byte nm[9]="(ユ)NSL  ";
const byte dt[9]="08/10/09";
const byte mn1[9] = { "1 COUNTR" };
const byte mn1A[9] = { "CLK<>EVT" };
const byte mn2[9] = { "2 I2C   " };
const byte mn3[9] = { "3 RS485 " };
const byte mn3A[9] = { " SPEED? " };
const byte mn3B[9] = { " 9600bps" };
const byte mn4[9] = { "4 SPI   " };
const byte mn5[9] = { "5 UART  " };
const byte mn6[9] = { "6 VDC   " };
const byte mn7[9] = { "7 ADC   " };
const byte mn0[9] = { "  N/A   " };
const byte mn9[9] = { "RS485NET" };
const byte mn10[9] = { "RST #   " };
const byte mn11[9] = { "PNG #   " };
const byte mn12[9] = { "READ #  " };
const byte mn13[9] = { "WRT #   " };
const byte mn14[9] = { "        " };
const word cnt1_clock = 4;   // 25ms*4=100ms
const word cnt1_event = 400;   // 25ms*400=10sec

static unsigned char cnt=4;            // cnt,cnt1はLED更新周期用カウンタ
static word cnt1=4;
static byte a,menu,x,y,RCVFLG,oldRA1,oldRA2,oldRA3,dsp_on,cnt1init;
static byte menu_selected,submenu_selected;
static byte I2C_state,I2C_DA,I2C_MDATA,I2C_SDATA,I2C_RA,TMR0L1,TMR0H1;
static unsigned long freq,ADout;
static word cnt0,cnt01;
static byte COM_mode,count_mode,uart_mode,ll,FF_mode;

void UserInit(void)
{
 
//    InitializeI2C();
    TRISC = 0x41;   // ProtC RC0:SW3 BLUE,RC1:YELLOW LED/TXRX, RC2:BLUE LED,RC3:VUSB
     //  RC4:D+,RC5:D-,RC6:RX,RC7:TX/SDO
    PORTC = 0x0D;   // PortC
    TRISA = 0x1F;   // PORTA RA0:ANALOG CURRENT,RA1:ANALOG VOLT,
     // RA2:SW1 YELLOW,RA3:SW2 GREEN, RA4:CLOCK IN,RA5:#SS/DEBUG LED
    PORTA = 0x00;   // PortA
    TRISB = 0x00;   // PORTB  RB4-RB7:LCD DB4-DB7, RB2:LCD E,
     //   RB3:LCD RS 、RB0:SDA/SDI,RB1:SCL/SCK
    PORTB|= 0xF3;   // PortB


//    T0CON = 0xB7;           // タイマ0の設定, 16ビットモード, 割込み使用
                            //外部クロック、1:256プリスケーラ
    T0CON = 0xB0;           // タイマ0の設定, 16ビットモード, 割込み使用
                            //外部クロック、1:2プリスケーラ
    T1CON = 0xB1;           //タイマ1の設定,16ビットモード、割込み使用
                            //内部クロック、1:8プリスケーラ

 CCP1CON = 0;

//***** 優先順位割込み使用宣言
    RCONbits.IPEN=1;
    IPR1bits.TMR1IP=1;
//***** 低レベル使用周辺の定義
 INTCON2bits.TMR0IP = 0;
//***** 割込み許可
    INTCONbits.GIEH=1;          // 高レベル許可
    INTCONbits.GIEL=1;          // 低レベル許可
 INTCONbits.T0IE = 1;  // タイマ0割込み許可
 PIE1bits.TMR1IE = 1;  // タイマ1割込み許可
 UIE = 0x7F;     // USB割込み許可
    ADCON0= 0x01;
 ADCON1 = 0x0D;    // ADC設定 Vref+=VDD,Vref-=Vss,AN0,AN1
    ADCON2 = 0x14;              // ADRESH[7:0]:ADRESL[7:6],Fosc/32,8Tad
    InitializeUSART();
 PIE1bits.RCIE = 1;   // UART割り込み許可
    oldRA3 = 1; oldRA2=1; oldRA1=1;
 waitmsec(60);
 PORTBbits.RB3 = 0;  // RS=0
 PORTB = 0x20;   // set high niblle
 PORTBbits.RB2 = 1;  // E=1
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;  // E=0
 LCDcontrol(0x28);  // Set Font(5x7), Lines(2)
 waitusec(39);
 LCDcontrol(0x0F); // Set Display(ON), Cursor(ON),Blink(OFF)
 waitusec(39);
 LCDcontrol(1);  // Display CLEAR

 waitmsec(1);
 waitusec(53);

 LCDcontrol(0x06);  // Set Moving(Increment),SHIFT(OFF)
 waitusec(39);

 RCVFLG = 0;

 LCDlocate(0);
 LCDstring(tt,8);   // Display "MULTI "  

 LCDlocate(0x40); // Display " MONITOR"  
 LCDstring(tt2,8);

 waitmsec(255);
 waitmsec(255);
 
 LCDlocate(0x47);
 menu=7; menu_selected=0; PORTAbits.RA0 = 0;
 PORTCbits.RC2=1;
 COM_stage=0;
 menu_selected=0;
 submenu_selected=0;
 count_mode=0;
 cnt1init=4;
 uart_rd_ptr=0;
 uart_buf_bytes=0;
 uart_mode=0;
 COM_mode=0;
 FF_mode=0;
 LEN=10;
}//end UserInit

void Exercise_Example(void)
{
    static byte start_up_state = 0;


    if(start_up_state == 0)
    {
            start_up_state++;
    }
    else if(start_up_state == 1)
    {
        if(mUSBUSARTIsTxTrfReady())
        {
            putrsUSBUSART(ansi_clrscr);
            start_up_state++;
        }
    }
    else if(start_up_state == 2)
    {
        if(mUSBUSARTIsTxTrfReady())
        {
            putrsUSBUSART("\rMicrochip Technology Inc., 2007\r\n");
            start_up_state++;
        }
    }
    else if(start_up_state == 3)
    {
        if(mUSBUSARTIsTxTrfReady())
        {
            putrsUSBUSART(welcome);
   message_state++;
   if(message_state > 5) {
    start_up_state ++;
//             putrsUSBUSART(lastmessage);
   }
   else start_up_state = 0;
        }
    }

}//end Exercise_Example

void COMM_USB(void)
{

   static byte devaddr, regaddr, i2cdata, i2cdata2 ;
   byte N,i,j,k,ch,I2Cdata2,ASD_type,ASD_num, *mm0, *mm1,menu_change;
 byte Resp,data,*msg0;              

// Push button Switch interpreter
//    menu
//      bit 7 : 0: main menu, 1: submenu
//      bit 6-4 : reserved
//      bit 3-0 : menu number
//                  0=COUNT,1=I2C,2=RS485,3=SPI,4=UART,5=VDC,6=ADC
//
  menu_change=0;
  if(PORTAbits.RA3==1){   // GREEN PB_SW
   if(oldRA3==0){
    oldRA3=1;
    if(menu_selected<127) {
      if(menu_selected){
     menu_selected =0;
     LCDlocate(0x40);
     LCDmenu2();
         } else {
     menu_selected=menu+1;
      }
    } else {
      if (submenu_selected) {
                      submenu_selected=4;
       LCDlocate(0x40);
       menu_selected&=0x7F;
       LCDmenu2();
         } else {
     submenu_selected=3;
      }
    }
    } else {
       oldRA3=1;
    }   
  } else oldRA3=0;
  if(PORTAbits.RA2==1){
//    LCDlocate(5);
//    LCDwrite(uart_mode+0x30);
//    LCDwrite(menu_selected+0x30);
//    LCDwrite(submenu_selected+0x30);
   if(oldRA2==0){    // YELLOW PB_SW
    oldRA2=1;
    if(menu_selected>127){
     submenu_selected=2;
    } else {
     menu_change=1;
     if(menu==0) {
      menu=7;
     } else {
      menu--;
     }
    }
   } else {
    oldRA2=1;
   }
  } else oldRA2=0;
  if(PORTCbits.RC0==1){ 
//    LCDlocate(5);
//    LCDwrite(uart_mode+0x30);
//    LCDwrite(menu_selected+0x30);
//    LCDwrite(submenu_selected+0x30);
   if(oldRA1==0){    // BLUE PB_SW
    oldRA1=1;
    if(menu_selected>127){
     submenu_selected=1; 
    } else {
     menu_change=1;
     menu++;
     if(menu>7) menu=0;
    }
   } else {
    oldRA1=1;
   }
  } else oldRA1=0; 
  LCDlocate(0);
 if(menu_change){
     switch(menu){
   case 0 : LCDstring(mn1,8); break;
   case 1 : LCDstring(mn2,8); break;
   case 2 : LCDstring(mn3,8); break;
   case 3 : LCDstring(mn4,8); break;
   case 4 : LCDstring(mn5,8); break;
   case 5 : LCDstring(mn6,8); break;
   case 6 : LCDstring(mn7,8); break;
  }
  LCDlocate(0x40);
 }

 if(menu_change){

  PORTAbits.RA0= 0;
  if((!count_mode)||(!uart_mode)) LCDmenu2();  
  LCDlocate(0);
 }
// PORTCbits.RC1=1; // Yellow LED on
// menu proccessor
 if((menu_selected)&&(dsp_on)){
  switch(menu){
   case 0 : // Counter
    if(submenu_selected){
     if(count_mode==0) {
      count_mode=submenu_selected;
                        if(count_mode==2){
       T0CON=0xB7;
       cnt1init=4;
      } else {
       T0CON=0xB8;
       cnt1init=400;
      }       
     } else {      
      if(submenu_selected==4){
       submenu_selected=0;
       menu_selected=0;
       count_mode=0;
      } else { 
       dsp_on=0;
       LCDlocate (0x40);
       LCDstring("        ",8);
       if(count_mode==1) {
        freq=(cnt01*0x10000+TMR0H1*0x100+TMR0L1)*256/100; // clock count
       } else {
        freq=(cnt01*0x10000+TMR0H1*0x100+TMR0L1);  // event count
       }
       sprintf(va1,"%8ld",freq);
       LCDlocate(0x46-strlen(va1));
       LCDstring(va1,strlen(va1));
       LCDlocate(7);
       LCDwrite(count_mode+0x30);
//       LCDwrite(0x30);
//       LCDwrite(0x4B);
      }
     }
    } else {
     LCDlocate(0x40);
     LCDstring(mn1A,8); // Display "CLK<>EVT")
     menu_selected|=0x80;
    }
    break;
   case 1 : // I2C
   case 3 : // SPI
    LCDlocate(0x40);
    LCDstring(mn0,8);
    break;
   case 2 : // RS485
   case 4 : // UART
    if(submenu_selected){
     if(uart_mode==0) {
      uart_mode=submenu_selected;
      LCDlocate(7);
      LCDwrite(uart_mode+0x30);
      LCDlocate(0x0);
                       if(uart_mode==2){    // 9600bps
       SPBRGH=0x04;
       SPBRG=0xE1;
       LCDstring(mn3B,8);
      } else if(uart_mode==3 ){  // 19200bps
       SPBRGH=0x02;
       SPBRG=0x71;              
//       LCDstring(mn3C,8);
      } else if(uart_mode==1){  // 57600bps
       SPBRGH=0x00;
       SPBRG=0xCE;
//       LCDstring(mn3D,8);
      }
      LCDlocate(5);
      LCDwrite((RCSTA&0x0F)+0x30);
      LCDlocate(0x40);
      LCDstring(mn14,8);  // clear 2nd line of LCD
       LCDlocate(0x40);
       ll=8;
       if(uart_buf_bytes<8){ll=uart_buf_bytes;}
       for(i=0; i<ll; i++){
        LCDwrite(UART_rd_buffer[uart_rd_ptr+i]);
       }             
     } else {      
      if(submenu_selected==4){
       submenu_selected=0;
       menu_selected=0;
       uart_mode=0;
      } else { 
       dsp_on=1;
       LCDlocate(6);
       LCDwrite((uart_rd_ptr&0x0F)+0x30);
       LCDwrite((uart_buf_bytes&0x0F)+0x30);
       LCDlocate (0x40);
//       LCDstring(mn14,8);  // clear 2nd line of LCD
       LCDlocate (0x40);
       ll=8;
//       if(uart_buf_bytes<8){ll=uart_buf_bytes;}
       for(i=0; i<ll; i++){
        LCDwrite(UART_rd_buffer[uart_rd_ptr+i]);
       }
      }
     }
    } else {
     LCDlocate(0x40);
     LCDstring(mn3A,8); // Display "SPEED?")
//       LCDlocate(5);
//       LCDwrite(uart_rd_ptr+0x30);
//       LCDwrite(uart_buf_bytes+0x30);
     menu_selected|=0x80;
    }
    break;
   case 5 : // VDC
                dsp_on=0;
                ADCON0 = 0x07;
                while((ADCON0&0x02) == 1);  // ADC Complete?
                ADout=(unsigned long) (ADRESH);
              
    ADout=(ADout*5000/1024)*4+(ADRESL*5000/1024)/64;

     sprintf(va1,"%6ld",ADout);
    LCDlocate(0x40);
    LCDstring(va1,strlen(va1));
    LCDlocate(0x46);
    LCDwrite(0x6D);
    LCDwrite(0x56);
                break;
               
            case 6 : // ADC
                dsp_on=0;
                ADCON0 = 0x03;
                while((ADCON0&0x02) == 1);  // ADC Complete?
                ADout=((ADRESH*4+ADRESL/64)*3300)/1024;
     sprintf(va1,"%6ld",ADout);
    LCDlocate(0x44-strlen(va1));
    LCDstring(va1,strlen(va1));
    LCDlocate(0x46);
    LCDwrite(0x6D);
    LCDwrite(0x41);

                break;
  }
 }
// PORTCbits.RC1=1; // Yellow LED on
// USB command interpreter
   if(getsUSBUSART(input_buffer,7))
    {
  CMND = input_buffer[0];
        ID   = input_buffer[1];
        LEN  = input_buffer[2];
  if ((CMND>0xC0)&&(LEN<15)){
          COM_stage=0;
    for(i=0; i<LEN; i++){
    msg[i] = input_buffer[i+3];
      } 
    for (i=0; i<LEN+3; i++){
   aa[i]=input_buffer[i];
    }
  } else {
           COM_stage=9;
  }
//
//  Packet format ( HOST comm PC(VB6) <-> MASTER )
//            aa[0]    aa[1]   aa[2]    aa[3]   aa[4]            aa[2+LEN]
//   | CMND  |  ID   |  LEN   |  PRM0  | PRM1 | ------- | PRMx   |
//             0xC0 : RESET
//      0xC1 : PING
//             0xC2 : READ               FUNC    PERIOD  NUM
//             0xC3 : WRITE
//             0xC4 : SAmode
//                       bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
//                FUNC : OPT  ADC  VDC  UART SPI  RS485 I2C COUNT
//                PEIROD ON/OT    |<----- TIME COUNT ----------->
//                NUM    Type     |<- BER of DATA IN A PACKET -->
//                      CON/OT : 0=CONSECUTIVE, 1=ONE TIME, 2,3=Reserved
//                      TYpe   : 0-8bit, 1-10bit, 2=12bit, 3=16bit
//           
//  RS485 Command state machine
//     Send Command PC>MASTER>SLAVE : COM_stage=0
//         Receive Reply SLAVE>MASTER>PC : COM_stage=1
//
//
// PORTCbits.RC1=~PORTCbits.RC1; // Yellow LED on
 if(COM_stage==0){
  if(ID!=0xFE) COM_stage=1;
        switch(CMND){
      case Reset_RS485 : //  Reset command
//   LCDcontrol(1); // LCD clear
//   waitusec(53);
   COM_mode=1;
   LCDlocate(0x0);
   LCDstring(mn9,8);
   LCDlocate(0x40);
   LCDstring(mn10,8);
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data);
            Send_RS485(RReset_RS485,ID,LEN);
   LEN++;
   if (ID!=0xFE){
    COM_stage=1;
    uart_rcv_complete=0;
   } else {
    Resp=0;
    for (i=0; i<LEN; i++) {
     SA[i]=aa[i+2];
     }
   }
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);
   break;

      case Ping : //  Ping command
   COM_mode=1;
   LCDlocate(0x0);
   LCDstring(mn9,8);
   LCDlocate(0x40);
   LCDstring(mn11,8);
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data);
   uart_rcv_complete=0;
   COM_stage=1;
   Send_RS485(RPing,ID,LEN);
   LEN++;
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;
   case Read : //  Read command
   COM_mode=1;
   LCDlocate(0x0);
   LCDstring(mn9,8);  // Print "RS485NET"
   LCDlocate(0x0);
   LCDstring(mn12,8); // Print "READ #"
//   data=0x30+ID;
//   LCDlocate(0x6);
//   LCDwrite(data);
//   data=LEN+0x30;
//   LCDwrite(data);
   if(ID==myID){
                ADCON0 = 0x07;
                while((ADCON0&0x02) == 1);  // ADC Complete?
                ADout=(unsigned long) (ADRESH);
              
    ADout=(ADout*5000/1024)*4+(ADRESL*5000/1024)/64;
    aa[3]=ADout/256;
    aa[4]=ADout%256;
    COM_stage=0;
   } else {
    uart_rcv_complete=0;
    COM_stage=1;
    Send_RS485(RRead,ID,LEN);
   }
   LEN++;
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;

   case Write :  // Write command
   COM_mode=1;
   COM_stage=1;
   LCDlocate(0x0);
   LCDstring(mn9,8);
   LCDlocate(0x40);
   LCDstring(mn13,8);
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data);
   uart_rcv_complete=0;
   Send_RS485(RWrite,ID,LEN);
   LEN++;
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;
    case SAmode :  // return to Stand=alone mode
   COM_mode=0;
   break;
   
  }  // end of switch(CMND)
   }   // end of if(COM_stage==0)  
 }    //  end of if(getUSBUSART)  USB Command interpreter
//
//  Packet format ( RS485 network MASTER <-> SLAVE )
//            aa[0]    aa[1]   aa[2]    aa[3]   aa[4]          aa[2+LEN]
//   | ID     |  LEN   | CMND |  PRM0  | PRM1 | ------- | PRMx  | checksum |
//             0x00 : RESET
//      0x01 : PING
//             0x02 : READ
//             0x03 : WRITE
//  RS485 Command state machine
//     Send Command PC>MASTER>SLAVE : COM_stage=0
//         Receive Reply SLAVE>MASTER>PC : COM_stage=1
//
//
// UART Ack packet proccessor 
// PORTCbits.RC1=1; // Yellow LED on
// if((uart_rcv_complete==1)&&(COM_stage==1)&&(ID!=myID)){
 if((uart_rcv_complete==1)&&(COM_stage==1)){
// if(uart_rcv_complete==1){
   LCDlocate(0x5);
   LCDwrite(0x41); // print "A";
   COM_stage=0;
   Resp=0;
   msg0=msg;
   Rcv_RS485(*msg);
   aa[0]=CMND;
   aa[1]=ID;
   aa[2]=LEN;
   for(i=0; i<LEN; i++){
    aa[3+i]=UART_rd_buffer[5+i];
    
   }
   FF_mode=0;
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+4);
   PORTAbits.RA5=1;
  
  }  // end of if(uart_rcv_complete==1)
 
// UART serialization
//   LCDlocate(0x6);
//   LCDwrite(n_uart_wrbuf+0x30);
  if(TXSTAbits.TRMT==1){
   if(n_uart_wrbuf==0) PORTCbits.RC1=0; // Change RXTX to RX
   if(n_uart_wrbuf!=0){
    LCDlocate(1+uart_wr_ptr);
//    LCDwrite(UART_wr_buffer[uart_wr_ptr]+0x30);
    TXREG=UART_wr_buffer[uart_wr_ptr];
    uart_wr_ptr++;
    if(uart_wr_ptr>uart_ptr_max) uart_wr_ptr=0;
    n_uart_wrbuf--;
    if(n_uart_wrbuf==0) {
     uart_wr_ptr=0;
//     PORTCbits.RC1=0;  // Change LTC485 to RX mode
    }
   }
  }
// LCDlocate(7);
// LCDwrite(COM_stage+030);
// PORTCbits.RC1=1; // Yellow LED on
// PORTCbits.RC2=0;
 
}//end of COMM_USB
void InitializeUSART(void)
{
     unsigned char c;

//        UART_TRISRx=1;    // RX
//        UART_TRISTx=0;    // TX
        TXSTA = 0x24;        // TX enable BRGH=1
        RCSTA = 0x90;        // Single Character RX
        SPBRG = 0x71;
        SPBRGH = 0x02;       // 0x0271 for 48MHz -> 19200 baud
        SPBRG = 0xE1;
        SPBRGH = 0x04;       // 0x0271 for 48MHz -> 9600 baud
        BAUDCON = 0x08;      // BRG16 = 1
        c = RCREG;    // read
}
void put_UART(byte data)
{
 UART_wr_buffer[uart_wr_ptr]=data;
 uart_wr_ptr++;
 n_uart_wrbuf++;

void Send_RS485(byte CMND,byte ID,byte n)
{
 byte i,chksum;
    chksum=0;

 uart_wr_ptr=0;
 uart_buf_bytes=0; // Clear Read Buffer byte count
 n_uart_wrbuf=0;  // Clear uart_rd_ptr 
 PORTCbits.RC1=1;  // Change LTC485 to TX mode
 put_UART(0xFF);
 put_UART(0xFF);
 put_UART(CMND);
 chksum+=CMND;
 put_UART(ID);
    chksum+=ID;
 put_UART(n+1);
 chksum+=(n+1);
 for (i=0; i<n; i++){
  put_UART(msg[i]);
        chksum+=msg[i];
 }
    put_UART(chksum&0xFF);
 uart_wr_ptr=0;
// LCDlocate(0);
// LCDwrite(n_uart_wrbuf+0x30);
}
int get_UART(byte data)
{
 if(uart_buf_bytes>0) {
  data=UART_rd_buffer[uart_rd_ptr++];
  uart_buf_bytes--;
  return 0;
 } else {
  return -1;
 } 
}
int Rcv_RS485(byte *msg)
{
 byte i,ret,data;

 ret=0;
 LCDlocate(0x40);
 LCDstring(mn14,8);  // Erase 2nd Line
 LCDlocate(0x40);
// LCDwrite(uart_buf_bytes+0x30);
 for(i=0; i<uart_buf_bytes; i++){
  LCDwrite(UART_rd_buffer[i]+0x30);
 }

    if(get_UART(data)){
   if(data!=0xFF) ret++;
  } else { ret++; }
    if(get_UART(data)){
   if(data!=0xFF) ret++;
  } else { ret++; }
    if(get_UART(data)){
   if(data<5) {
    CMND=data;
   } else { ret++; }
  }
    if(get_UART(data)){
   ID=data;
   } else { ret++; }
 if(get_UART(data)){
   LEN=data;
   } else { ret++; }
 for( i=0; i<LEN; i++){
   *msg=data;
   msg++;
  }
 uart_rd_ptr=0;
    if(ret>0){
  return 0;
 } else {
  return -1;
  }  
}
        
   
void WR_EEPROM(byte addr, byte data)
{
    EEADR = addr;
 EEDATA = data;
 EECON1bits.WREN = 1;
 EECON2 = 0x55;
 EECON2 = 0xAA;
 EECON1bits.WR = 1;
 while (EECON1bits.WR);      
}//end of WR_EEPROM

byte RD_EEPROM(byte address)
{
    EEADR = address;

 EECON2 = 0x55;
 EECON2 = 0xAA;
 return EEDATA;
}      

void LCDmenu2(void){
 switch(menu){
    case 0 : LCDstring(mn2,8); break;
    case 1 : LCDstring(mn3,8); break;
    case 2 : LCDstring(mn4,8); break;
    case 3 : LCDstring(mn5,8); break;
    case 4 : LCDstring(mn6,8); break;
    case 5 : LCDstring(mn7,8); break;
    case 6 : LCDstring(mn1,8); break;
 }
}
     
void LCDstring(char *ptr, byte n)
{
 byte i,a;

 PORTBbits.RB3 = 1;  
 for(i=0; i<n; i++){
  if(*ptr==0){
   LCDwrite(0x20);
  } else {
    LCDwrite(*ptr);
  }
  ptr++;
 } 
}
void LCDcontrol(byte data)
{
 byte db;

 PORTBbits.RB3 = 0;
 db = data&0xF0;
 PORTB = db;   // set high niblle
 PORTBbits.RB2 = 1;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 db = (data&0x0F)<<4;  
 PORTB = db;   // Set low nibble
 PORTBbits.RB2 = 1;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
}
void LCDwrite(byte data)
{
 byte db;

 PORTBbits.RB3 = 1;
 db = data&0xF0;
 PORTBbits.RB2 = 1;
 PORTB = 0x0C|db;   // set high niblle
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 db = (data&0x0F)<<4;  
 PORTBbits.RB2 = 1;
 PORTB = 0x0C|db;   // Set low nibble
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 waitusec(39); 
}
void LCDlocate(byte data)
{
 byte db;

 PORTBbits.RB3 = 0;  
 db = data&0xF0;
 PORTB = 0x80|db;
 PORTBbits.RB2 = 1;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 db = (data&0x0F)<<4;  
 PORTB = db;   // Set Moving(Increment),SHIFT(ON)
 PORTBbits.RB2 = 1;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 _asm NOP _endasm;
 PORTBbits.RB2 = 0;
 waitusec(39); 
}
void waitusec(byte wait)
{
    int i,j;
/*
    T1CON = 0x34  ;  //1:8 prescale, Fosc/4(16MHz)
    if(wait>16) wait= 16;
    TMR1H = 16*wait;
    TMR1L = 0;
    T1CONbits.TMR1ON = 1; //Timer start
    while(PIR1.TMR1IF);
*/
    for (i=0; i<wait; i++)
      for (j=0; j<6; j++);

}


     
void waitmsec(byte wait)
{
    int i,j,k;
/*
    T1CON = 0x34  ;  //1:8 prescale, Fosc/4(16MHz)
    if(wait>16) wait= 16;
    TMR1H = 16*wait;
    TMR1L = 0;
    T1CONbits.TMR1ON = 1; //Timer start
    while(PIR1.TMR1IF);
*/
    for (i=0; i<wait; i++)
      for (j=0; j<6; j++)
        for (k=0; k<100; k++){};
}
byte hexH(byte data)
{
  int a;
 a=(data&0xF0)>>4;
 if(a<10){
  return 0x30+a;
 } else {
  return 0x37+a;
 }
}
byte hexL(byte data)
{
  int a;
 a=data&0x0F;
 if(a<10){
  return 0x30+a;
 } else {
  return 0x37+a;
 }
}
/*********************************************************
   優先順位を使った複数割込み
    高レベル:タイマ1  低レベル:タイマ0
  機能
    タイマ0   :外部クロックのカウント
    タイマ1   :25msごとの割込み、100msごとのタイマ0値読み出し
********************************************************/ 
//****** 割込みの宣言 優先順位使用
#pragma interrupt isr
#pragma interruptlow tmr0

//***** 割込みベクタジャンプ命令セット
#pragma code isrcode = 0x8
void isr_direct(void)
{
    _asm
    goto isr
    _endasm
}
#pragma code lowcode = 0x18
void low_direct(void)
{   _asm
    goto tmr0
    _endasm
}
//**** 高レベル 割込み処理関数
#pragma code
void isr(void)                      // 割り込み関数
{
     INTCONbits.GIEH=0;          // 高レベル禁止
     INTCONbits.GIEL=0;          // 低レベル禁止
  INTCONbits.T0IE = 0;  // Timer0割り込み禁止
  PIE1bits.TMR1IE = 0;  // Timer1割り込み禁止
    if(PIR1bits.TMR1IF){            // タイマ1割り込み25ms=8x37500 @48MHz
        PIR1bits.TMR1IF=0;          // タイマ1割り込みフラグを0にする
  TMR1H = 0x6D;
  TMR1L = 0x84+24;
//  TMR1H = 0x0B;
//  TMR1L = 0xDC;
        if(--cnt1==0){              // cnt1を-1して結果が0?
            cnt1=cnt1init;                // cnt1にLEDの更新周期を書き戻す
            if(PORTCbits.RC2) {  //    100m秒@48MHz
//                PORTC=PORTC^0x06;    //LED BLUEを0.1秒間隔で点滅
    PORTCbits.RC2=0;
   } else {
//                PORTC=PORTC^0x06;
    PORTCbits.RC2=1;
   }
   TMR0L1=TMR0L;
   TMR0H1=TMR0H;
   cnt01=cnt0;
//   TMR0H=0;
   dsp_on =1;
   cnt0=0;
//   TMR0L=0;
      INTCONbits.GIEL=1;          // 低レベル許可
        }
 } else if(PIR1bits.SSPIF){  //I2C割り込み?
//  PORTAbits.RA0 = 1;
  PIR1bits.SSPIF=0;
  switch(I2C_state){
   case 0:
     if(SSPSTATbits.BF){
      I2C_DA=SSPBUF;
      I2C_state=1;
     }
     break;
   case 1:
     if(SSPSTATbits.BF){
      I2C_RA=SSPBUF;
      I2C_state=2;
     }
     break;
   case 2:
     if(SSPSTATbits.BF){
      if(SSPSTATbits.R_W==1){
       I2C_state=3;
      } else {
       I2C_MDATA=SSPBUF;
       I2C_state=0;
      }
     }
     break;
   case 3:
     if(!SSPSTATbits.BF){
      SSPBUF=I2C_SDATA;
      I2C_state=0;
     }
     break;
   }    
  PIE1bits.SSPIE=1;
  } else if(PIR1bits.RCIF){  //USART割り込み?
   RCVFLG=1;
   a=RCREG;
//   LCDlocate(0x47);
//   LCDwrite((a&0x0F)+0x30);
   if(COM_mode==0){   // UART/RS485 monitor AT STAND ALONNE MODE
    UART_rd_buffer[uart_rd_ptr]=a;
    uart_rd_ptr++;
    uart_buf_bytes++;
    if(uart_rd_ptr>uart_ptr_max){
     uart_rd_ptr=0;
     uart_buf_bytes=uart_ptr_max;     
    }
   } else {
    if(uart_rcv_complete==0) {
     UART_rd_buffer[uart_rd_ptr]=a;
     uart_rd_ptr++;
     uart_buf_bytes++;
     if(FF_mode==0) {
      if(a==0xFF) {
       FF_mode=1;
      } else {
       uart_rd_ptr=0;
       uart_buf_bytes=0;
      }
     } else if(FF_mode==1) {
      if(a==0xFF) {
       FF_mode=2;
      } else {
       uart_rd_ptr=1;
       uart_buf_bytes=1;
      }

     } else if(FF_mode==2){
      if(uart_rd_ptr>uart_ptr_max) uart_rd_ptr=0;
      if(uart_buf_bytes>=5){
       LEN=UART_rd_buffer[4];
      }
//      LCDlocate(0x6);
//      LCDwrite((uart_buf_bytes&0x0F)+0x30);
//      LCDwrite(LEN+0x30);
      if(uart_buf_bytes>=LEN+6) {
       uart_rcv_complete=1;
//       LCDlocate(0x40);
//       LCDwrite(0x2F);  // Print "/"
       FF_mode=0;
      }
       }
    }
   } 
   PIR1bits.RCIF=0;
  }
    INTCONbits.GIEH=1;          // 高レベル許可
    INTCONbits.GIEL=1;          // 低レベル許可
 INTCONbits.T0IE = 1;
 PIE1bits.TMR1IE = 1;
 PIE1bits.RCIE = 1;

}                                  
//***** 低レベル割込み処理関数
void tmr0(void)                     // 割り込み関数
{
    if(INTCONbits.T0IF){            // タイマ0割り込み?
        INTCONbits.T0IF=0;          // タイマ0割り込みフラグを0にする
   cnt0++;
        if(--cnt==0){               // cntを-1して結果が0?
            cnt=10;                  // cntにLEDの更新周期を書き戻す
        }
    }
}                      


/** EOF user.c ***************************************************************/

 

 

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日