📄 hello.c
字号:
/******************************************************************************/
/* This file is part of the uVision/ARM development tools */
/* Copyright KEIL ELEKTRONIK GmbH 2002-2004 */
/******************************************************************************/
/* */
/* HELLO.C: Hello World Example */
/* */
/******************************************************************************/
#include <LPC2294.H> /* LPC21xx definitions */
#define OUTB(x,y) (*((volatile unsigned char *)(x)) = y)
#define INB(x) (*((volatile unsigned char *)(x)))
#define OUTW(x,y) (*((volatile unsigned long *)(x)) = y)
#define INW(x) (*((volatile unsigned long *)(x)))
/**
* Data structure for a CAN message to be transmitted
*/
typedef struct
{
unsigned long TFI; //0x8xxxxxxx for 29bits length ID, 0x0xxxxxxx for 11 bits
unsigned long ID;
unsigned long DataField[2];
}CAN_TX, *pCAN_TX;
/**
* Data structure for a CAN message to be received
*/
typedef struct
{
unsigned long RFS;
unsigned long ID;
unsigned long DataField[2];
} CAN_RX, *pCAN_RX;
/*---------------------------------------------------------------------------*/
/* CAN Global Variable */
/*---------------------------------------------------------------------------*/
/**
* Data structure for a CAN message to be transmitted
*/
CAN_TX CAN_Send_Data = {0x00080000,0x00000001,0x04030201,0x08070605}; // Tx Message Object
CAN_RX CAN1_Rcv_Data;
CAN_RX CAN2_Rcv_Data;
unsigned long CAN1Tx_Return_Message[5] = {0,0,0,0,0};
unsigned long CAN2Rx_Return_Message_Flag[10] = {0,0,0,0,0,0,0,0,0,0};
unsigned char CAN_Rcv_Data_Counter=0;
unsigned long Return_Value = 0;
unsigned long CAN_Rcv_Status = 0;
#define CR 0x0D
#define LED1CON (1<<6) // P0.4 control LED4
unsigned long LED_Counter=0;
unsigned char LED_Flag=0;
unsigned char CAN1_Rec_Interrupt,CAN2_Rec_Interrupt;
// lcd
extern void ShowWelcomeLog(void);
extern void Clear_Lcd(void);
extern void checkLCD(void);
extern invertchar(unsigned char data);
extern unsigned long KeyOut[4];
#define LCDRST 21
//key
extern unsigned char Get_Key(void);
extern unsigned char KeyNum;
extern unsigned char bKeyDown;
#define KEY_SUB 0x13; //00010011
#define KEY_RETURN 0x23; //00100011
#define KEY_DOWN 0x43; //01000011
#define KEY_LEFT 0x83; //10000011
#define KEY_OK 0x15; //00010101
#define KEY_PULS 0x25; //00100101
#define KEY_RIGHT 0x45; //01000101
#define KEY_UP 0x85; //10000101
#define KEY_F4 0x16; //00010110
#define KEY_F3 0x26; //00010110
#define KEY_F2 0x46; //00010110
#define KEY_F1 0x86; //00010110
/****************************************************************************
* Name: Delay()
* Function: Delay
* Input(s): delaytime
* Returns : none
****************************************************************************/
void delay(unsigned long delaytime)
{
unsigned long i;
for(; delaytime>0; delaytime--)
for(i=0; i<50000; i++);
}
void InitTimer1(void)
{
//-----------------------------------------------
//Config Timer1
//Fcclk = Fosc/2 = 5MHz
//Fpclk = Fosc/4 = 2.5MHz
//-----------------------------------------------
T1PR = 0; // Disable prescaler
T1MCR = 0x03; // Using T1MR0 match T1TC,Enable interrupt,reset T1TC
T1MR0 = 25000; // 10ms each Timer interrupt
T1TCR = 0x02; // Reset T1TC, by set TCR:2
T1TCR = 0x01; // Must CLR TCR:2, then can Start T1TC
}
/******************************************************************************/
// UART0
/* Initial Uart0 */
void InitUart0(void)
{
PINSEL0 |= 0x00000005; /* Enable RxD0 and TxD0 */
U0FCR = 7;
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
U0DLL = 0x10; /* 9600 Baud Rate @ 2.5 MHz VPB Clock */
U0DLM = 0;
U0LCR = 0x03; /* DLAB = 0 */
}
/* Write character to Serial Port */
void putchar (unsigned char ch)
{
if (ch == '\n')
{
while (!(U0LSR & 0x20));
U0THR = CR;
}
while (!(U0LSR & 0x20));
U0THR = ch;
}
void puthex (int hex) { /* Write Hex Digit to Serial Port */
if (hex > 9) putchar('A' + (hex - 10));
else putchar('0' + hex);
}
void putlong (unsigned long longchar)
{
unsigned char data[4];
unsigned char i;
data[3] = (unsigned char) longchar & 0x000000ff;
data[2] = (unsigned char) (longchar>>8 & 0x000000ff);
data[1] = (unsigned char) (longchar>>16 & 0x000000ff);
data[0] = (unsigned char) (longchar>>24 & 0x000000ff);
for(i=0;i<4;i++)
{
puthex((data[i]>>4) & 0x0f);puthex(data[i] & 0x0f);
}
}
/* Read character from Serial Port */
unsigned char getchar (void)
{
while (!(U0LSR & 0x01));
return (U0RBR);
}
/* Write string to Serial Port */
void putstr(char *p)
{
while(*p)
{
putchar(*p++);
}
}
/******************************************************************************/
/******************************************************************************/
//CAN
void InitCan(void)
{
//unsigned long acfword_upper;
//unsigned long acfword_lower;
PCONP |= 1<<13;
PCONP |= 1<<14;
PINSEL1 |= 0x00054000; // 把P0中3个引脚分配给RD2、TD2、RD1; TD1是专用引脚,不再P0-P3内,不需要分配
C1MOD = 0x01; /* Enter reset mode */
C1BTR = 0x00140018; /* 50K@ 10 MHz VPB Clock */
AFMR = 0x00000002; /* receive all messages, no filtering */
C1IER = 0x000007ff; //Enable CAN2Rx interrupt
C1MOD = 0x00; /* Enter operation mode */
/* BRP = 24;SJW = 0;TSEG1=4;TSED2=1;SAM=0 */
C2MOD = 0x01; /* Enter reset mode */
C2BTR = 0x00140018; /* 50K@ 10 MHz VPB Clock */
AFMR = 0x00000002; /* receive all messages, no filtering */
C2IER = 0x000007ff; //Enable CAN2Rx interrupt
C2MOD = 0x00; /* Enter operation mode */
/* BRP = 24;SJW = 0;TSEG1=4;TSED2=1;SAM=0 */
CAN1_Rec_Interrupt = 0;
CAN2_Rec_Interrupt = 0;
// SFF_GRP_sa = 0; // Set Standard Frame Group Startaddress
//验收滤波器...
// acfword_lower = (0x0000 << 16) + (2 << 29); //low`=0x00.CAN2
// acfword_upper = (0x00ff) + (2 << 13); //upper=0x0ff.CAN2
// OUTW(AFRAM, acfword_lower + acfword_upper);
// AFRAM = acfword_lower + acfword_upper;
//验收滤波器...
// C1IER = 0x000007FF; //Enable all CAN1 interrupt
// C2IER = 0x000007ff; //Enable CAN2Rx interrupt
}
/****************************************************************************
* Name: IRQ_Timer1()
* Function: Timer1 interrupt function, inverse LED1(P0.4)
* Input(s): none
* Returns : none
****************************************************************************/
void __irq IRQ_Timer1(void)
{
LED_Counter++;
if( LED_Counter == 100) // 10ms*50=0.5s led inverse
{
if( LED_Flag == 0)
{
LED_Flag = 1;
IOCLR0 = LED1CON;
}
else
{
LED_Flag = 0;
IOSET0 = LED1CON; //Control LED1
}
LED_Counter = 0;
}
T1IR = 0x01; // CLR Timer1 interrupt flag
VICVectAddr = 0x00; // Inform VIC interrupt is end
}
/****************************************************************************
* Name: IRQ_CAN1Rx()
* Function: IRQ_CAN1Rx interrupt
* Input(s): none
* Returns : none
****************************************************************************/
void __irq IRQ_CAN1Rx(void)
{
unsigned long Temp_CAN1Rx_IRQ=0;
CAN1_Rec_Interrupt = 1;
Temp_CAN1Rx_IRQ = C1ICR;
if( (Temp_CAN1Rx_IRQ & 0x00000001) == 0x00000001 ) //接收到有用信息
{
// put Rcv data to Rcv-Buffer, must assign value to pointer before used
// CAN Channel 1
CAN1_Rcv_Data.RFS = C1RFS;
CAN1_Rcv_Data.ID = C1RID;
CAN1_Rcv_Data.DataField[0] = C1RDA;
CAN1_Rcv_Data.DataField[1] = C1RDB;
// Release Receive Buffer
C1CMR = 0x04; // Release Rx Buffer
Return_Value = 1;
CAN_Rcv_Status = 1; // communication successful
}
VICVectAddr = 0x00;
}
void CAN1_Transmit (void) //using CAN1
{
unsigned long TransmitBufferStatus;
unsigned long TransmitBufferFree;
// Read Global Status Register
putstr("\nsend1 begin!\n");
TransmitBufferStatus = C1SR;
TransmitBufferFree = TransmitBufferStatus & 0x0000000C;
if (TransmitBufferFree == 0) // one of Two(TBS,TCS) fits will pass
{
putstr("\n40 error 1!\n");
}
putstr("\nsend1 TransmitBufferFree!\n");
// Copy message contents into local variable(s)
C1TFI1 = CAN_Send_Data.TFI;
C1TID1 = CAN_Send_Data.ID;
C1TDA1 = CAN_Send_Data.DataField[0];
C1TDB1 = CAN_Send_Data.DataField[1];
C1CMR = 0x21;
while((C1GSR & 0x48) == 0x00);
putstr("\nsend1 OK!\n");
if ((C1GSR & 0x40) == 0x40)
{
C1CMR = 0x02;
putstr("\nsend1 error 0x40!\n");
}
} // lpc2000CANdriver_PrepareTransmitMessage;
/****************************************************************************
* Name: IRQ_CAN2Rx()
* Function: IRQ_CAN2Rx interrupt
* Input(s): none
* Returns : none
****************************************************************************/
void __irq IRQ_CAN2Rx(void)
{
unsigned long Temp_CAN2Rx_IRQ=0;
putstr("\nIRQ_CAN2 enter!\n");
CAN2_Rec_Interrupt = 1;
Temp_CAN2Rx_IRQ = C2ICR;
if( (Temp_CAN2Rx_IRQ & 0x00000001) == 0x00000001 ) //接收到有用信息
{
// put Rcv data to Rcv-Buffer, must assign value to pointer before used
// CAN Channel 2
CAN2_Rcv_Data.RFS = C2RFS;
CAN2_Rcv_Data.ID = C2RID;
CAN2_Rcv_Data.DataField[0] = C2RDA;
CAN2_Rcv_Data.DataField[1] = C2RDB;
// Release Receive Buffer
C2CMR = 0x04; // Release Rx Buffer
Return_Value = 1;
CAN_Rcv_Status = 1; // communication successful
}
VICVectAddr = 0x00;
}
void CAN2_Transmit (void) //using CAN2
{
unsigned long TransmitBufferStatus;
unsigned long TransmitBufferFree;
// Read Global Status Register
putstr("\nsend2 begin!\n");
TransmitBufferStatus = C2SR;
TransmitBufferFree = TransmitBufferStatus & 0x0000000C;
if (TransmitBufferFree == 0) // one of Two(TBS,TCS) fits will pass
{
putstr("\n40 error 2!\n");
}
putstr("\nsend TransmitBufferFree!\n");
// CAN Channel 2
// Copy message contents into local variable(s)
C2TFI1 = CAN_Send_Data.TFI;
C2TID1 = CAN_Send_Data.ID;
C2TDA1 = CAN_Send_Data.DataField[0];
C2TDB1 = CAN_Send_Data.DataField[1];
C2CMR = 0x21;
while((C2GSR & 0x48) == 0x00);
putstr("\nsend2 OK!\n");
if ((C2GSR & 0x40) == 0x40)
{
C2CMR = 0x02;
putstr("\nsend2 error 0x40!\n");
}
} // lpc2000CANdriver_PrepareTransmitMessage;
/****************/
/* main program */
/****************/
int main (void) /* execution starts here */
{
unsigned char i;
//unsigned char temp1,temp2;
//unsigned long temp3;
PINSEL0 = 0x00000000;
PINSEL1 = 0x00000000;
PINSEL2 = 0x00000000;
IODIR0 = 0x000000D0; /* P0.4 P0.6,P0.7 defined as Outputs */
IOCLR0 = 0x000000D0; // Turn off LED1 P0.4 P0.6,P0.7
InitUart0(); /* initialize the serial interface */
InitCan();
InitTimer1();
//InitLCD
IODIR0 |= 0x00030000; /* P0.16,P0.17 defined as Outputs */
IODIR1 |= 0x01F00000; /* P1.20:24 defined as Outputs */
IOCLR1 = 1<<LCDRST;
for(i=0;i<250;i++);
for(i=0;i<250;i++);
for(i=0;i<250;i++);
for(i=0;i<250;i++);
IOSET1 = 1<<LCDRST;
//key
KeyNum = 0;
bKeyDown = 0;
IODIR0 |= 0x00780000; //P0.19:22 output;
IODIR0 &= 0xc7ffffff; //P27:29; input;
//-----------------------------------------------
//Config VIC,
//In <Starup.s> enable IRQ by CLR I bit in CPSR
//Vectored interrupt Timer1 by slot-0
//Vectored interrupt UART0 by slot-1
//Vectored interrupt CAN2Rx by slot-2
//-----------------------------------------------
VICIntSelect = 0x00000000; // All interrupt be IRQ
VICVectCntl0 = 0x20|5; // Assign Timer1 to IRQ Slot0
VICVectAddr0 = (unsigned long)IRQ_Timer1; // Assign IRQ Address for IRQ_Timer1
// VICVectCntl1 = 0x20|6; // Assign UART0 to IRQ slot1
// VICVectAddr1 = (unsigned long)IRQ_UART0; // Assign IRQ Address for IRQ_UART0
VICVectCntl2 = 0x20|26; // Assign CAN2Rx to IRQ Slot1
VICVectAddr2 = (unsigned long)IRQ_CAN1Rx; // Assign IRQ Address for IRQ_CAN1Rx
VICVectCntl3 = 0x20|27; // Assign CAN2Rx to IRQ Slot2
VICVectAddr3 = (unsigned long)IRQ_CAN2Rx; // Assign IRQ Address for IRQ_CAN2Rx
VICIntEnable = (1<<5)|(0<<6)|(1<<26)|(1<<27); // Enable Timer1+UART0+CAN1Rx+CAN2Rx interrupt
putstr("\nHello!\n");
//TEST CODE
//TEST CODE end
// ShowWelcomeLog();
// putstr("ShowWelcomeLog();!\n");
while (1)
{ /* An embedded program does not stop and */
putstr("\nLoop OK!*************************************\n");
/* Get_Key();
if(bKeyDown == 1)
{
bKeyDown = 0;
}
*/
if(CAN1_Rec_Interrupt == 1)
{
putstr("\nCAN1 Rcv_interrupt_OK!\n");
CAN1_Rec_Interrupt = 0;
}
if(CAN2_Rec_Interrupt == 1)
{
putstr("\nCAN2 Rcv_interrupt_OK!\n");
CAN2_Rec_Interrupt = 0;
}
CAN2_Transmit();
// CAN1_Transmit();
delay(10);
} /* loop. You may wish to put in your own */
} /* code were we've printed the dots (...). */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -