|
|
View previous topic :: View next topic |
Author |
Message |
RHA
Joined: 25 Apr 2006 Posts: 31 Location: Germany
|
Simple RS232 <--> I2C with very small protocol |
Posted: Tue Apr 25, 2006 5:07 am |
|
|
A simple RS232 <--> I2C Communication with very small protocol :
Sending 0x00 from PC to Hardware for Connect-Inquiry gets 0x00 as an answer from the hardware.
Then the first byte high-nibble are the number of bytes to send to I2C and the low-nibble are the numer of bytes to receive from I2C (leave 0 if not needed).
The next bytes are the bytes which would be sended to I2C.
If all Data is collected the hardware sends a 0xe0 to the PC for confirmation.
At next the hardware sends/receives data to/from I2C and puts the received data to the RS232.
After all the hardware sends a 0xee to the PC.
Itīs a simple way to test some I2C-Hardware.
Greets
RHA
Code: |
#include <16F876.h>
#define CLOCK_SPEED 8000000 // Hz
#use delay(clock=CLOCK_SPEED, RESTART_WDT)
#fuses HS,WDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
#zero_ram
#byte TMR0 = 0x01
#byte PCL = 0x02
#byte STATUS = 0x03
#byte FSR = 0x04
#byte PortA = 0x05
#byte PortB = 0x06
#byte PortC = 0x07
#bit STAT_C = STATUS.0
//***************************************************************************************************************************
//***************************************************************************************************************************
//#bit = PortA.0 //
//#bit = PortA.1 //
//#bit = PortA.2 //
//#bit = PortA.3 //
//#bit = PortA.4 //
//#bit = PortA.5 //
#define TrisA_Ini 0b11111111 // PortA Input/Output
#define PortA_Ini 0b00000000 // PortA Output Init
//-----------------------------------------------------------------------------------
//#bit = PortB.0 //
//#bit = PortB.1 //
//#bit = PortB.2 //
//#bit = PortB.3 //
//#bit = PortB.4 //
//#bit = PortB.5 //
//#bit PGC = PortB.6 //
//#bit PGD = PortB.7 //
#define TrisB_Ini 0b11111111 // PortB Input/Output
#define PortB_Ini 0b00000000 // PortC Output Init
//-----------------------------------------------------------------------------------
//#bit = PortC.0 //
//#bit = PortC.1 //
//#bit = PortC.2 //
//#bit SCL = PortB.3 //
//#bit SDA = PortB.4 //
//#bit = PortB.5 //
//#bit TX = PortC.6 //
//#bit RX = PortC.7 //
#define TrisC_Ini 0b11111111 // PortC Input/Output
#define PortC_Ini 0b00000000 // PortC Output Init
//-----------------------------------------------------------------------------------
// Variables for generate basic timers //
int Pre_01ms; // Prescaler 1ms
int Pre_50ms; // Prescaler 50ms
int Pre_01s; // Prescaler 1s
short CLK_01ms; // 1ms ready
#define Time_RTCC 0xc8 // RTCC 200us (0.0002 / (((1 / 8MHz) * 4) * 2))
#define Time_01ms 0x05 // Prescaler 1ms ( 5*Time_RTCC)
#define Time_50ms 0x32 // Prescaler 50ms ( 50*Time_01ms)
#define Time_01s 0x14 // Prescaler 1s ( 20*Time_50ms)
//-----------------------------------------------------------------------------------
// Variables for the RS232-Connection //
int RS232_Rx; // Inputbyte
int RS232_Tx[15]; // Outputbytes
int RS232_TxCount; // Counter for Outputbytes
//-----------------------------------------------------------------------------------
// Variablen für die RS232-Schnittstelle //
int I2C_Rx; // Inputbyte
int I2C_RxCount; // Counter for Inputbytes
int I2C_Tx[5]; // Outputbytes
int I2C_TxCount; // Counter for Outputbytes
int I2C_TxPtr; // Pointer for Outputbytes
//-----------------------------------------------------------------------------------
#use rs232 (baud=9600,xmit=PIN_C6,rcv=PIN_C7, RESTART_WDT)
#use i2c (master,slow,sda=PIN_C4,scl=PIN_C3,force_HW,RESTART_WDT)
//***************************************************************************************************************************
//***************************************************************************************************************************
#int_rtcc // Serviceroutine for RTCC
rtcc_isr() {
TMR0 = TMR0 - Time_RTCC; // Restart Counter (Overflow would be considered)
if (!--Pre_01ms) { // 1ms ready ?
CLK_01ms = True; // Yes --> Set Indicator
Pre_01ms = Time_01ms; // Reset Prescaler
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
void send_RS232(int Tx_Byte) { // Send a Byte over RS232
if (RS232_TxCount < 15) { // Another free byte in buffer ?
RS232_Tx[RS232_TxCount] = Tx_Byte; // Write byte in buffer
++RS232_TxCount; // Increment Buffer-Counter
enable_interrupts(INT_TBE); // Enable RS232-Transmit
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
void I2C_TxRx() { // Send/Receive at I2C
if (I2C_TxCount && (I2C_TxCount == I2C_TxPtr)) { // Data for sending collected?
send_RS232(0xe0); // Send confirmation on RS232
I2C_TxPtr = 0; // Reset pointer from I2C-Sendingbuffer
i2c_start(); // Start I2C-Communication
while (I2C_TxCount) { // Send data on I2C-Bus
i2c_write(I2C_Tx[I2C_TxPtr]); //
--I2C_TxCount; //
++I2C_TxPtr; //
}
while (I2C_RxCount) { // Receive data from I2C-Bus
I2C_Rx = i2c_read(); //
send_RS232(I2C_Rx); //
--I2C_RxCount; //
}
i2c_stop(); // Stop I2C-Communication
I2C_TxPtr = 0; // Reset pointer from I2C-Receivebuffer
send_RS232(0xee); // Send End-Code on RS232
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
#int_rda // Serviceroutine for RS232 Receive
rda_isr() {
RS232_Rx = getc(); // Read-Out received byte
if (!I2C_TxCount) { // Starting protocol (first byte) ?
if (RS232_Rx == 0x00) { // Connect-Inquiry ?
send_RS232(0x00); // Yes --> Answer
}
else { // No --> Load counter for protocol
I2C_RxCount = RS232_Rx & 0x0f ; // (Receive-Counter)
I2C_TxCount = swap(RS232_Rx) & 0x0f; // (Send-Counter)
}
}
else { // Collect I2C-Sendingdata ?
I2C_Tx[I2C_TxPtr] = RS232_Rx; // Put received byte in I2C-Sendingbuffer
++I2C_TxPtr; // Increment pointer on I2C-Sendingbuffer
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
#int_tbe // Serviceroutine for RS232 Transmit
tbe_isr() {
if (RS232_TxCount != 0) { // Another Byte ?
putc(RS232_Tx[0]); // Send first byte in buffer
--RS232_TxCount; // Decrement counter
memcpy(RS232_Tx,RS232_Tx+1,14); // Shift buffer
}
else { // Last byte transmitted ?
disable_interrupts(INT_TBE); // Disable RS232-Transmit
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
void timer() { // Softwaretimer
if (CLK_01ms) { // 1ms ready ?
CLK_01ms = False; // Reset statusbit
if (!--Pre_50ms) { // Decrement Counter for 50ms
Pre_50ms = Time_50ms; // Reset Counter
if (!--Pre_01s) { // Decrement Counter for 1s
Pre_01s = Time_01s; // Reset Counter
}
}
}
}
//***************************************************************************************************************************
//***************************************************************************************************************************
void init() { // Initialisation
PortA = PortA_Ini; // Preset Outputs
PortB = PortB_Ini; //
PortC = PortC_Ini; //
set_tris_a (TrisA_Ini); // Set Inputs/Outputs
set_tris_b (TrisB_Ini); //
set_tris_c (TrisC_Ini); //
port_b_pullups(TRUE); // Switch on PortB - Pullups
setup_adc_ports(NO_ANALOGS); // No Analoginputs
setup_adc(ADC_CLOCK_DIV_2); //
Pre_01ms = Time_01ms; // Preset Prescaler
Pre_50ms = Time_50ms; //
Pre_01s = Time_01s; //
// setup_ccp1(CCP_PWM); // Setup PWM
// set_pwm1_duty(MOT_DISABLE); //
// out_PWM = MOT_DISABLE; //
// setup_timer_3(T3_DISABLED); // Timer3 (not needed)
setup_timer_2(T2_DISABLED,0,1); // Timer2 (not needed)
setup_timer_1(T1_DISABLED); // Timer1 (not needed)
setup_counters(RTCC_INTERNAL,RTCC_DIV_2); // Timer0 for RTCC
set_rtcc(-Time_RTCC); // Set RTCC-Initialvalue
enable_interrupts(INT_RTCC); // Enable RTCC-Interrupt
enable_interrupts(INT_RDA); // Enable RS232-Receive
enable_interrupts(GLOBAL); // Enable Interrupts global
}
//***************************************************************************************************************************
//***************************************************************************************************************************
void main() { // Main loop
init(); // Initialise Program
while(true) {
restart_WDT(); // Reset Watchdog
timer(); // Softwaretimer
I2C_TxRx(); // Send/Receive on I2C
}
}
|
|
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
|
RHA
Joined: 25 Apr 2006 Posts: 31 Location: Germany
|
|
Posted: Tue Apr 25, 2006 2:43 pm |
|
|
Pretty cool,
but i think for most persons itīs easier to work with a standard terminal program and a RS232 connection then with the parallel port.
ciao
RHA |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|