PICマイコンを使って測定ツールを作ってみよう(4) ―― ネットワークでセンサ・データを集めて省電力生活を目指す

中西 紫朗

tag: 組み込み 電子回路

エレキ系DIY 2011年6月10日

リスト2 RS-485スレーブ・ノードのソース・リスト(userS110525.c)

/*********************************************************************
 *
 *                Microchip USB C18 Firmware Version 1.2
 *
 *********************************************************************
 * FileName:        userS.c
 * Dependencies:    See INCLUDES section below
 * Processor:       PIC18
 * Compiler:        C18 3.11+
 **********************************************************************
 * Company:         NSL 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     05/24/11    Added RS485/UART monitor.
 * Shiroh Nakanishi     05/25/11    Split MASTER & SLAVE version.
 * Shiroh Nakanishi     06/02/11    Fixed Network comm fialure
 ********************************************************************/

/** 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
#define Reset_RS485 0
#define Ping 1
#define Read 2
#define Write 3
#define ACK 0x41
#define NAK 0x4E
#define myID 3  //  ***スレーブを変更するときのこのIDも変更してください****

char input_buffer[16];  // USB command buffer
char output_buffer[16];  // USB reply buffer
char UART_rd_buffer[uart_ptr_max]; // UART receive buffer (MASTER --> SLAVE)
char UART_wr_buffer[uart_ptr_max]; // UART send buffer (SLAVE --> MASTER)
byte uart_wr_ptr,uart_rd_ptr,uart_buf_bytes,n_uart_wrbuf,uart_rcv_complete;
byte ctstart,REGC7,COM_stage,SW[3];
static byte message_state = 0;
byte CMND,SID,ID,LEN,msg[13],MA,nSA,SA[12];

//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

/** 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 put_UART(byte data);
void Send_RS485(byte CMND, byte ID, byte LEN);
int get_UART(void);
int Rcv_RS485(void);
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);

/** D E C L A R A T I O N S **************************************************/
#pragma code
static byte aa[32] = { "aaaaaaa\r\n" };
static byte va1[18] = { "        " };
const byte tt[12] = { "MULTI   " };
const byte tt2[12] = { " MONITOR" };
const byte nm[8]="(ユ)NSL  ";
const byte dt[8]="08/10/09";
const byte mn1[8] = { "1 COUNTR" };
const byte mn2[8] = { "2 I2C   " };
const byte mn3[8] = { "3 RS485 " };
const byte mn4[8] = { "4 SPI   " };
const byte mn5[8] = { "5 UART  " };
const byte mn6[8] = { "6 VDC   " };
const byte mn7[8] = { "7 ADC   " };
const byte mn0[8] = { "  N/A   " };
const byte mn9[8] = { "RS485NET" };
const byte mn10[8] = { "RST #   " };
const byte mn11[8] = { "PNG #   " };
const byte mn12[8] = { "READ #  " };
const byte mn13[8] = { "WRT #   " };
const byte mn14[8] = { "        " };


static unsigned char cnt=4;            // cnt,cnt1はLED更新周期用カウンタ
static unsigned char cnt1=10;
static byte a,menu,x,y,RCVFLG,oldRA1,oldRA2,oldRA3,dsp_on,menu_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 Resp,rcv_count; 

void UserInit(void)
{
 
    TRISC = 0x81;   // ProtC RC0:SW3 BLUE,RC1:BLUE LED/TXRX, RC2:YELLOW LED,RC3:VSUB
     //  RC$:D-,RC5:D+,RC6:TX,RC7:RX/SDO
    PORTC|= 0x0D;   // PortC
    TRISA = 0x3E;   // PORTA RA0:ANALOG CURRENT,RA1:ANALOG VOLT,
     // RA2:SW1 YELLOW,RA3:SW2 GREEN, RA4:CLOCK IN,RA5:#SS
    PORTA = 0x01;   // 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プリスケーラ
    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();   // UART設定
 COM_stage=1;
//    InitializeI2C();
 LEN=7;
 PIE1bits.RCIE = 1;
    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);  

 LCDlocate(0x40);  
 LCDstring(tt2,8);

 waitmsec(255);
 waitmsec(255);
 
 LCDlocate(0x47);
 menu=7; menu_selected=0; PORTAbits.RA0 = 0;
 PORTCbits.RC1 = 0;
 uart_rd_ptr=0;
 uart_wr_ptr=0;
}//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 RSP,Resp,data;              

// Push button Switch interpreter
  menu_change=0;
  if(PORTAbits.RA3==1){
   if(oldRA3==0){
    oldRA3=1;
    if(menu_selected) {
     menu_selected=0;
     PORTAbits.RA0=0;
     LCDlocate(0x40);
     LCDmenu2();
    } else {
     menu_selected=menu+1;
     PORTAbits.RA0=1;
    }
   } else {
    oldRA3=1;
   }
  } else oldRA3=0;
  if(PORTAbits.RA2==1){
   if(oldRA2==0){
    oldRA2=1;
    menu_change=1;
    menu--;
    if(menu==0) menu=7;
   } else {
    oldRA2=1;
   }
  } else oldRA2=0;
  if(PORTCbits.RC0==1){ 
   if(oldRA1==0){
    oldRA1=1;
    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;
  LCDmenu2();  
  LCDlocate(0);
 }
// menu=2;
// dsp_on=1;
// menu proccessor
 if((menu_selected)&&(dsp_on)){
  switch(menu){
   case 0 : // Counter
    dsp_on=0;
    LCDlocate (0x40);
    LCDstring("        ",8);
    freq=(cnt01*0x10000+TMR0H1*0x100+TMR0L1)*256/100;
    sprintf(va1,"%8ld",freq);
    LCDlocate(0x46-strlen(va1));
    LCDstring(va1,strlen(va1));
//    LCDwrite(0x30);
//    LCDwrite(0x4B);
    break;
   case 1 : // I2C
   case 2 : // RS485
    if(uart_rcv_complete==1){
     if(rcv_count%2!=0) {
      LCDlocate(0);
      LCDstring(mn14,8);
      LCDlocate(0);
     } else {
      LCDlocate(0x40);
      LCDstring(mn14,8);
      LCDlocate(0x40);
     }
     for(i=0; i<uart_buf_bytes; i++){
      LCDwrite(UART_rd_buffer[i]+0x30);
     }
     rcv_count++;
     LCDlocate(0x46);
     LCDwrite(rcv_count+0x30);
     LCDwrite(uart_buf_bytes+0x30);
     uart_rcv_complete=0;
     uart_buf_bytes=0;
     uart_rd_ptr=0;
    }
    break;
   case 3 : // SPI
   case 4 : // UART
    LCDlocate(0x40);
    LCDstring(mn0,8);
    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/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;
  }
 }
// goto end_of_USB_process;
// USB command interpreter
   if(getsUSBUSART(input_buffer,7))
    {
  CMND = input_buffer[0];
        ID   = input_buffer[1];
        LEN  = input_buffer[2];
  for(i=0; i<LEN; i++){
    msg[i] = input_buffer[i+3];
  } 
  for (i=0; i<LEN+3; i++){
   aa[i]=input_buffer[i];
  }
// USB command processor
//  Packet format
//            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
//             0xC3 : WRITE
//  RS485 Command state machine
//     Send Command PC>MASTER>SLAVE : COM_stage=0
//         Receive Reply SLAVE>MASTER>PC : COM_stage=1
//
//
        switch(CMND){
      case Reset_RS485 : //  Reset command
//   LCDcontrol(1); // LCD clear
//   waitusec(53);
   LCDlocate(0x0);
//   LCDstring(mn9,8); // Print "RS485NET"
   LCDlocate(0x40);
   LCDstring(mn10,8); // Print "RST #   "
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data); // Print ID
   COM_stage=1;
   uart_rcv_complete=0;
            Send_RS485(Reset_RS485,0xFE,LEN);
   Resp=0;
   for (i=0; i<LEN; i++) {
    SA[i]=aa[i+2];
//    Send_RS485(Ping,SA[i],N,msg);
//    if(!Rcv_RS485(Reset_RS485,ID,N,msg)) {
//     aa[LEN+3]=0;
//     Resp++;
//    } 
    }
   MA=myID;
   nSA=LEN-1;
   if(Resp==0) {
    aa[0]=0x41;  // ACK
   } else {
    aa[0]=0x4E;  // NAK
   } 
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);
   break;

      case Ping : //  Ping command
   LCDlocate(0x0);
   LCDstring(mn10,8);
   LCDlocate(0x40);
   LCDstring(mn11,8);
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data);
   COM_stage=1;
   uart_rcv_complete=0;
   Send_RS485(Ping,ID,LEN);
            if(!Rcv_RS485()){
    aa[0]=0x41;  // ACK
   } else {
    aa[0]=0x4E;  // NAK
   } 
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;
   case Read : //  Read command
   LCDlocate(0x0);
//   LCDstring(mn9,8);
   LCDlocate(0x40);
   LCDstring(mn12,8);
   data=0x30+ID;
   LCDlocate(0x46);
   LCDwrite(data);
   COM_stage=1;
   uart_rcv_complete=0;
   Send_RS485(Read,ID,N);
            if(!Rcv_RS485()){
    aa[0]=0x41;  // ACK
   } else {
    aa[0]=0x4E;  // NAK
   } 
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;

   case Write :  // Write command
   LCDlocate(0x0);
//   LCDstring(mn9,8);
   LCDlocate(0x40);
   LCDstring(mn13,8);
   data=0x30+ID;
   LCDlocate(0x45);
   LCDwrite(data);
   COM_stage=1;
   uart_rcv_complete=0;
   Send_RS485(Write,ID,LEN);
    if(!Rcv_RS485()){
    aa[0]=0x41;  // ACK
    for (i=0; i<msg[2]; i++) {
     aa[3+i]=msg[i];
    }
   } else {
    aa[0]=0x4E;  // NAK
   } 
//    while(mUSBUSARTIsTxTrfReady()==0);
    mUSBUSARTTxRam(aa,LEN+3);      
   break;
  }
 }  // End of 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   |
//             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
//
// RS485 Ack packet proccessor
 if(uart_buf_bytes>0){
//  LCDlocate(0);
//  LCDwrite(LEN+0x30);
//  LCDlocate(0x40+uart_rd_ptr-1);
//  LCDwrite(uart_buf_bytes+0x30);
 }
 if(uart_rcv_complete){
  Resp=Rcv_RS485();
  LCDlocate(0x0);
//  LCDstring(mn9,5);   // Put "RS485" in 1st Line of LCD
//  LCDlocate(0x7);
//  LCDwrite(ID+0x30);
//  for (i=0; i<LEN+1; i++){
//    LCDwrite(UART_rd_buffer[i+4]+0x30);
//  }
  if((ID==0xFE)||(ID==myID)){
   LCDlocate(0x5);
   LCDwrite(CMND+0x30);
   LCDwrite(ID+0x30);
   switch(CMND){
     case Reset_RS485:
    LCDlocate(0x40);
    LCDstring(mn10,8); // Print "RST #   "
    LCDlocate(0x45);
    LCDwrite(myID+0x30);
    if(ID==myID){
     if(Resp==0) {
      RSP=0x41;  // ACK
     } else {
      RSP=0x4E;  // NAK
     }
     Send_RS485(RSP,ID,LEN);
    } 
//    while(mUSBUSARTIsTxTrfReady()==0);
//    mUSBUSARTTxRam(aa,LEN+3);
    break;
     case Ping:
    LCDlocate(0x40);
    LCDstring(mn11,8); // Print "PNG #   "
    LCDlocate(0x45);
    LCDwrite(myID+0x30);
    if(ID==myID){
     if(Resp==0) {
      RSP=0x41;  // ACK
     } else {
      RSP=0x4E;  // NAK
     }
     Send_RS485(RSP,ID,LEN);
    } 
//    while(mUSBUSARTIsTxTrfReady()==0);
//    mUSBUSARTTxRam(aa,LEN+3);
    break;
   case Read:
    LCDlocate(0x40);
    LCDstring(mn12,8); // Print "Read #"
    LCDlocate(0x46);
    LCDwrite(myID+0x30);
    if(ID==myID){
     if(Resp==0) {
      RSP=0x41;  // ACK
     } else {
      RSP=0x4E;  // NAK
     }
     Send_RS485(RSP,ID,LEN);
    } 
//    while(mUSBUSARTIsTxTrfReady()==0);
//    mUSBUSARTTxRam(aa,LEN+3);
    break;
   case Write:
    LCDlocate(0x40);
    LCDstring(mn13,8);
    LCDlocate(0x45);
    LCDwrite(myID+0x30);
    if(ID==myID){
     if(Resp==0) {
      RSP=0x41;  // ACK
     } else {
      RSP=0x4E;  // NAK
     }
     Send_RS485(RSP,ID,LEN);
    } 
//    while(mUSBUSARTIsTxTrfReady()==0);
//    mUSBUSARTTxRam(aa,LEN+3);
    break;
   }    
  }
  
  } // End of COM_stage switch

// UART TX serialization
  if(TXSTAbits.TRMT==1){
   if(n_uart_wrbuf==0) PORTCbits.RC1=0;
   if(n_uart_wrbuf!=0){
    LCDlocate(uart_wr_ptr);
//    LCDwrite(n_uart_wrbuf+0x30);
    TXREG=UART_wr_buffer[uart_wr_ptr];
    LCDwrite(UART_wr_buffer[uart_wr_ptr]+0x30);
    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;
    }
   }
  }
  end_of_USB_process:
   i=0;
}//end of COMM_USB

void InitializeUSART(void)
{
  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,data,chksum;
    chksum=0;
 
 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);
 chksum+=n;
 for (i=0; i<n; i++){
  data=UART_rd_buffer[5+i];
  put_UART(data);
        chksum+=data;
 }
    put_UART(chksum&0xFF);
    uart_wr_ptr=0;
}
int get_UART(void)
{
 byte data;

 if(uart_buf_bytes>0) {
  data=UART_rd_buffer[uart_rd_ptr];
  uart_rd_ptr++;
  uart_buf_bytes--;
  return data;
 } else {
  return -1;
 } 
}
int Rcv_RS485(void)
{
 byte i,ret,data;

 ret=0;

 LCDlocate(0x40);
 LCDstring(mn14,8);   // Erase 2nd line in LCD
 LCDlocate(0x40);     
 LCDwrite(uart_buf_bytes+0x30);  // Put UART recieve count in LCD(0,1)
 for(i=0; i<uart_buf_bytes; i++){
       LCDwrite(UART_rd_buffer[i]+0x30);
 }
 uart_rd_ptr=0;
 data=get_UART();
 if(data!=0xFF)  { 
  while(data!=0xFF){ data=get_UART(); }
  }
 data=get_UART();
 if(data!=0xFF){ 
  uart_rd_ptr=0;
  uart_buf_bytes=0;
  uart_rcv_complete=0;
  return 1;
  }
 data=get_UART();
 if((data>=0)&&(data<5 )) {
    CMND=data;
   } else {
  uart_rd_ptr=0;
  uart_buf_bytes=0;
  uart_rcv_complete=0;
   return 3;
  }
 

 ID=get_UART();
 LEN=get_UART();
 LCDlocate(0x6);
 LCDwrite(LEN+0x30);
 LCDwrite(ID+0x30);
 for( i=0; i<LEN+4; i++){
//  data=get_UART();
  UART_wr_buffer[i]=UART_rd_buffer[i];
  msg[i]=data;
 }
 uart_rd_ptr=0;
 uart_buf_bytes=0;
 uart_rcv_complete=0;

 return 0;

}

        
   
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 save = PROD
#pragma interruptlow tmr0 save = WREG,BSR,STATUS,PROD

//***** 割込みベクタジャンプ命令セット
#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=4;                // cnt1にLEDの更新周期を書き戻す
            if(PORTCbits.RC2)  //    100m秒@20MHz
                PORTCbits.RC2=0;    //LED YELLOWを1秒間隔で点滅
            else
                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割り込み?
   PIR1bits.RCIF=0;
   RCVFLG=1;
   a=RCREG;
//   if(PORTCbits.RC1) { PORTCbits.RC1=0; } else { PORTCbits.RC1=1; }
   if(uart_rcv_complete==0){
     UART_rd_buffer[uart_rd_ptr]=a;
    uart_rd_ptr++;
    uart_buf_bytes++;
    if(uart_buf_bytes==6) {
     LEN=UART_rd_buffer[4];
    }
    if(uart_buf_bytes>=LEN+5 ) {
     uart_rcv_complete=1;
     uart_rd_ptr=0;
    }
   }
  }
    INTCONbits.GIEH=1;          // 高レベル許可
    INTCONbits.GIEL=1;          // 低レベル許可
 INTCONbits.T0IE = 1;
 PIE1bits.TMR1IE = 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日