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