|
4. |
|
 |
Quellcode
in der
Programmiersprache C
Dokumentation zum
LPC900-Experimentierboard (LPC-Experimentierboard.pdf)
Quelltext |
/**************************************************************************************
* C-Programm zur Auswertung von externen Ereignissen *
* Projekt-Name: i2c_bus_ansteuerung_7_segment_led.uv2 *
**************************************************************************************/
#include <reg932.h>
unsigned int uiLoop;
enum enSAASEG {NULL = 0x3F, EINS = 0x06,
ZWEI = 0x5B, DREI = 0x4F,
VIER =
0x66,
FUENF = 0x6D,
SECHS = 0x7D, SIEBEN = 0x07,
ACHT = 0x7F, NEUN = 0x67,
PUNKT =
0x80};
struct stI2C
{
unsigned char Adr;
unsigned char DataLen;
unsigned char Val[10];
};
struct stI2C Slave;
bit btI2cFinished;
v_InitI2C(void)
{
P1M1 |= 0x0C; // SDA und SCL als Open-Drain
P1M2 |= 0x0C;
I2SCLH = 19; // I2C-Geschwindigkeit ~100 KHz
I2SCLL = 19;
I2CON = 0x44; // I2C-Hardware aktivieren (STO, STA, SI = 0, ACK =1)
EI2C = 1; // I2C Interrupt freigeben
}
v_SetNextI2CVal( unsigned char ucVal )
{
Slave.Val[Slave.DataLen] = ucVal;
Slave.DataLen++;
}
v_StartI2CTrans( void )
{
btI2cFinished = 0;
I2CON = 0x64; // Startbedingung setzen
}
void v_WaitI2CFinish(void)
{
while (btI2cFinished == 0);
}
main()
{
unsigned char ucVal;
v_InitI2C();
EA = 1; // allgemeine Interruptsperre aufheben
Slave.Adr = 0x70; // Adresse SAA1064
v_SetNextI2CVal( 0 ); // set Subadresse auf 0 (Control-Byte)
v_SetNextI2CVal( 0xF7 ); // dynamic alternating mode (digits 1+3 and 2+4)
v_StartI2CTrans();
v_WaitI2CFinish();
while( 1 )
{
v_SetNextI2CVal( 1 );
switch ( ucVal )
{
case 0x00: v_SetNextI2CVal( NULL ); break;
case 0x01: v_SetNextI2CVal( EINS ); break;
case 0x02: v_SetNextI2CVal( ZWEI ); break;
case 0x03: v_SetNextI2CVal( DREI ); break;
case 0x04: v_SetNextI2CVal( VIER ); break;
case 0x05: v_SetNextI2CVal( FUENF ); break;
case 0x06: v_SetNextI2CVal( SECHS ); break;
case 0x07: v_SetNextI2CVal( SIEBEN ); break;
case 0x08: v_SetNextI2CVal( ACHT ); break;
case 0x09: v_SetNextI2CVal( NEUN ); break;
default:
v_SetNextI2CVal( 0xF7 );
}
v_StartI2CTrans();
v_WaitI2CFinish();
if( ucVal == 0x09 )
{
ucVal = 0x00;
// Rücksetzung des Zählers
}
ucVal++;
for( uiLoop = 0; uiLoop < 50000; uiLoop++
);
// Wartezeit, sonst Zählung nicht sichtbar
}
}
unsigned char ucI2COff;
void vI2C_Interrupt( void ) interrupt 6
{
switch( I2STAT ) // Auswertung des Statusregisters
{
case 0x08: // Status: "START transmitted"
I2DAT = Slave.Adr;
ucI2COff = 0;
I2CON = 0x44; // (STO, STA, SI = 0, ACK =1)
break;
case 0x18: // Status: "SLA+W transmitted; ACK received"
case 0x28: // Status: "byte transmitted; ACK received"
if ( ucI2COff < Slave.DataLen )
{
I2DAT = Slave.Val[ucI2COff]; // set next value
ucI2COff++;
I2CON = 0x44;
}
else
{
Slave.DataLen = 0;
btI2cFinished = 1;
I2CON = 0x54; // Stoppbedingung setzen (STO =1)
}
break;
case 0x20: // Status: "SLA+W transmitted; NOT ACK
received"
I2CON = 0x54; // Stoppbedingung setzen (STO =1)
break;
default:
Slave.Adr = I2STAT ;
break;
}
}