/**************************************************************
Multi Interface PIC board
for PIC12F1822
**************************************************************
author Shiroh Nakanishi
version 1.00
Tools:
MPLAB v8.76
Hitech PIC C pro9.82
---------------------------------------------------------------
Date :Time Version Build Note
20111026:0053 1.00 --- Begin the program for 12F1822
---------------------------------------------------------------
Project folder(default)
C:\PIC\CQMM
Source Files
CQMMACP.c
Header Files
---------------------------------------------------------------
Pin assignment(PIC12F1822,8P)
7:RA0:O: TXD
6:RA1:I: RXD
5:RA2:A: SEnsor INPUT (ADC)
4:RA3:O:
3:RA4:O:
2:RA5:O: TXRX zelection
8:VSS:P:
1:VDD:P:
---------------------------------------------------------------
*/
#include <htc.h>
typedef unsigned char byte; // 8-bit
//__CONFIG(UNPROTECT & BORDIS & MCLREN & PWRTEN & WDTDIS & INTIO);
__CONFIG( CP_OFF & WDTE_OFF & MCLRE_OFF & WRT_OFF & FOSC_INTOSC & CLKOUTEN_OFF );
void InitializeUSART(void);
void InitializeI2C(void);
// PROTYPE DECLARATION
void COMM_RS485(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 waitmsec(byte wait);
void waitusec(byte wait);
// Definition
#define uart_ptr_max 10
#define Reset_RS485 0
#define Ping 1
#define Read 2
#define Write 3
#define ACK 0x41
#define NAK 0x4E
#define myID 1 // ***スレーブを変更するときのこのIDも変更してください****
//unsigned char input_buffer[16]; // USB command buffer
//unsigned char output_buffer[16]; // USB reply buffer
unsigned char UART_rd_buffer[uart_ptr_max]; // UART receive buffer (MASTER --> SLAVE)
unsigned char UART_wr_buffer[uart_ptr_max]; // UART send buffer (SLAVE --> MASTER)
unsigned char uart_wr_ptr,uart_rd_ptr,uart_buf_bytes,n_uart_wrbuf,uart_rcv_complete;
unsigned char ctstart,REGC7,COM_stage,SW[3];
static unsigned char message_state = 0;
unsigned short a,cnt,tick_count,I2C_state,I2C_DA,I2C_RA,I2C_MDATA,I2C_SDATA,RCVFLG,cnt1;
unsigned char uart_rd_ptr,LEN;
int TMR0L,TMR0H,TMR0L1,TMR0H1,cnt01,cnt0;
unsigned char CMND,SID,ID,msg[8],FF_mode;
void interrupt isr(void) // 割り込み関数
{
/*
T0IE = 0; // Timer0割り込み禁止
TMR1IE = 0; // Timer1割り込み禁止
if(TMR1IF){ // タイマ1割り込み25ms=8x37500 @48MHz
TMR1IF=0; // タイマ1割り込みフラグを0にする
TMR1H = 0x6D;
TMR1L = 0x84+24;
// TMR1H = 0x0B;
// TMR1L = 0xDC;
if(--cnt1==0){ // cnt1を-1して結果が0?
cnt1=4; // cnt1にLEDの更新周期を書き戻す
if(PORTAbits.RA4) // 100m秒@20MHz
PORTAbits.RA4=0; //LED YELLOWを1秒間隔で点滅
else
PORTAbits.RA4=1;
TMR0L1=TMR0L;
TMR0H1=TMR0H;
cnt01=cnt0;
TMR0H=0;
cnt0=0;
TMR0L=0;
GIE=1; // 割り込みレベル許可
}
} else if(SSP1IF){ //I2C割り込み?
SSP1IF=0;
switch(I2C_state){
case 0:
if(SSP1STATbits.BF){
I2C_DA=SSPBUF;
I2C_state=1;
}
break;
case 1:
if(SSP1STATbits.BF){
I2C_RA=SSP1BUF;
I2C_state=2;
}
break;
case 2:
if(SSP1STATbits.BF){
if(SSP1STATbits.R_nW==1){
I2C_state=3;
} else {
I2C_MDATA=SSP1BUF;
I2C_state=0;
}
}
break;
case 3:
if(!SSP1STATbits.BF){
SSP1BUF=I2C_SDATA;
I2C_state=0;
}
break;
}
PIE1bits.SSP1IE=1;
} else
*/
if(RCIF){ //USART割り込み?
// if(RA4) { RA4=0; } else { RA4=1; }
a=RCSTA;
a=RCREG;
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_rcv_complete==0){
if(uart_buf_bytes==5) LEN=a;
if(uart_buf_bytes>=LEN+5 ) {
uart_rcv_complete=1;
RA4=1;
uart_rd_ptr=0;
FF_mode=0;
}
}
}
/* if(RCIF){
// if(RA4) { RA4=0; } else { RA4=1; }
a=RCREG;
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+7 ) {
uart_rcv_complete=1;
RA4=1;
uart_rd_ptr=0;
}
}
*/
// if(!uart_rcv_complete) if(RA4) { RA4=0; } else { RA4=1; }
// if(OERR) if(RA4) { RA4=0; } else { RA4=1; }
// if(OERR) if(RA4) { RA4=0; } else { RA4=1; }
if(OERR) {
CREN=0;
CREN=1;
}
}
CREN=1;
RCIE=1;
PEIE=1;
INTCONbits.GIE=1; // レベル許可
// INTCONbits.T0IE = 1;
// PIE1bits.TMR1IE = 1;
}
void COMM_RS485(void)
{
static unsigned char devaddr, regaddr, i2cdata, i2cdata2 ;
unsigned char N,i,j,k,ch,I2Cdata2,ASD_type,ASD_num;
unsigned char RSP,Resp,data;
// Push button Switch interpreter
// RS485 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){
}
if(uart_rcv_complete){
Resp=Rcv_RS485();
RA4=0;
for(i=0; i<10; i++){
for(j=0; j<10; j++);
}
// Send_RS485(Resp,ID,LEN);
if((ID==0xFE)||(ID==myID)){
switch(CMND){
case Reset_RS485:
if(ID==myID){
if(Resp==0) {
RSP=0x41; // ACK
} else {
RSP=0x4E; // NAK
}
Send_RS485(RSP,ID,LEN);
}
break;
case Ping:
if(ID==myID){
if(Resp==0) {
RSP=0x41; // ACK
} else {
RSP=0x4E; // NAK
}
Send_RS485(RSP,ID,LEN);
}
break;
case Read:
if(ID==myID){
if(Resp==0) {
ADCON0 = 0x0B; // ADC=AN2, GODONE, ADC ON
while((ADCON0&0x02) == 1); // ADC Complete?
UART_rd_buffer[5]=ADRESH;
UART_rd_buffer[6]=ADRESL;
RSP=0x41; // ACK
} else {
RSP=0x4E; // NAK
}
Send_RS485(RSP,ID,LEN);
}
break;
case Write:
if(ID==myID){
if(Resp==0) {
RSP=0x41; // ACK
} else {
RSP=0x4E; // NAK
}
Send_RS485(RSP,ID,LEN);
}
break;
}
}
} // End of COM_stage switch
for(i=0; i<10; i++){
for(j=0; j<10; j++);
}
// UART TX serialization
if(TXSTAbits.TRMT==1){
if(n_uart_wrbuf==0) { RA5=0; } else { RA5=1; }
if(n_uart_wrbuf!=0){
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;
}
}
}
// end_of_USB_process:
i=0;
} //end of COMM_RS485
void InitializeUSART(void)
{
char c;
// UART_TRISRx=1; // RX
// UART_TRISTx=0; // TX
TXSTA = 0x24; // TX enable BRGH=1
RCSTA = 0x90; // SP enable,Single Character RX
SPBRG = 0x67;
SPBRGH = 0x00; // 0x067 for 16MHz -> 19200 baud
SPBRG = 0xA0;
SPBRGH = 0x01; // 0x1A0 for 16MHz -> 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,j,data,chksum;
chksum=0;
RA5=1; // Change LTC485 to TX mode
RA4=1;
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[i+5];
put_UART(data);
chksum+=data;
}
put_UART(chksum&0xFF);
uart_wr_ptr=0;
for(i=0; i<10; i++){
for(j=0; j<10; j++);
}
}
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;
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();
a=get_UART();
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 main()
{
unsigned short LED;
int i,j,k;
//OPTION = 0x87; // prescaler 1:256 65.536ms@4MHz
OPTION_REG = 0x80; // prescaler 1:2 512us@4MHz
OSCCON=0xFF; // 16MHz
APFCON = 0x00; // TXD(RA0),RXD(RA1)
ANSELA = 0x04; // AN2(RA2)
CCP1CON =0x00; // Capture/Compare/PWM disabled
TRISA = 0x06; // RXD(RA1),AN2(RA2)
PORTA = 0x00;
TMR0 = 0;
INTCON = 0x00; // GIE:1,T0IE:1
ANSELA = 0x04;
ADCON0=0x09; // ADFM:Left
ADGO=0;
InitializeUSART();
uart_rcv_complete=0;
RCIE=1;
PEIE=1;
GIE=1;
RA5=1; // Change LTC485 to TX mode
RA5=0; // Change LTC485 to TX mode
RA4=0;
LEN=3;
FF_mode=0;
/*
while(1){
for(k=0; k<10; k++){
if(TRMT==1){
TXREG=0x30+k;
}
for(i=0; i<10; i++){
for(j=0; j<100; j++);
}
// RA5^=1; // Change LTC485 to TX mode
}
}
*/
while(1){
COMM_RS485();
for(i=0; i<10; i++){
for(j=0; j<10; j++);
}
}
}
|