📄 uart_can.c
字号:
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051F040.h> // SFR declarations
#include <stdio.h>
#include <string.h>
// CAN Protocol Register Index for CAN0ADR, from TABLE 18.1 of the C8051F040
// datasheet
////////////////////////////////////////////////////////////////////////////////
#define CANCTRL 0x00 //Control Register
#define CANSTAT 0x01 //Status register
#define ERRCNT 0x02 //Error Counter Register
#define BITREG 0x03 //Bit Timing Register
#define INTREG 0x04 //Interrupt Low Byte Register
#define CANTSTR 0x05 //Test register
#define BRPEXT 0x06 //BRP Extension Register
////////////////////////////////////////////////////////////////////////////////
//IF1 Interface Registers
////////////////////////////////////////////////////////////////////////////////
#define IF1CMDRQST 0x08 //IF1 Command Rest Register
#define IF1CMDMSK 0x09 //IF1 Command Mask Register
#define IF1MSK1 0x0A //IF1 Mask1 Register
#define IF1MSK2 0x0B //IF1 Mask2 Register
#define IF1ARB1 0x0C //IF1 Arbitration 1 Register
#define IF1ARB2 0x0D //IF1 Arbitration 2 Register
#define IF1MSGC 0x0E //IF1 Message Control Register
#define IF1DATA1 0x0F //IF1 Data A1 Register
#define IF1DATA2 0x10 //IF1 Data A2 Register
#define IF1DATB1 0x11 //IF1 Data B1 Register
#define IF1DATB2 0x12 //IF1 Data B2 Register
////////////////////////////////////////////////////////////////////////////////
//IF2 Interface Registers
////////////////////////////////////////////////////////////////////////////////
#define IF2CMDRQST 0x20 //IF2 Command Rest Register
#define IF2CMDMSK 0x21 //IF2 Command Mask Register
#define IF2MSK1 0x22 //IF2 Mask1 Register
#define IF2MSK2 0x23 //IF2 Mask2 Register
#define IF2ARB1 0x24 //IF2 Arbitration 1 Register
#define IF2ARB2 0x25 //IF2 Arbitration 2 Register
#define IF2MSGC 0x26 //IF2 Message Control Register
#define IF2DATA1 0x27 //IF2 Data A1 Register
#define IF2DATA2 0x28 //IF2 Data A2 Register
#define IF2DATB1 0x29 //IF2 Data B1 Register
#define IF2DATB2 0x2A //IF2 Data B2 Register
////////////////////////////////////////////////////////////////////////////////
//Message Handler Registers
////////////////////////////////////////////////////////////////////////////////
#define TRANSREQ1 0x40 //Transmission Rest1 Register
#define TRANSREQ2 0x41 //Transmission Rest2 Register
#define NEWDAT1 0x48 //New Data 1 Register
#define NEWDAT2 0x49 //New Data 2 Register
#define INTPEND1 0x50 //Interrupt Pending 1 Register
#define INTPEND2 0x51 //Interrupt Pending 2 Register
#define MSGVAL1 0x58 //Message Valid 1 Register
#define MSGVAL2 0x59 //Message Valid 2 Register
sbit BUTTON = P3^7;
sbit LED = P1^6;
////////////////////////////////////////////////////////////////////////////////
// Function PROTOTYPES
////////////////////////////////////////////////////////////////////////////////
void clear_msg_objects (void);
void start_CAN (void);
void transmit_ON (char MsgNum);
void external_osc (void);
void PORT_Init (void);
void UART0_Init (void);
/*****************新加的******************/
void UART0_set(void);
void data_DCM(void);
void init_msg_object_TX_STD (char MsgNum);
void init_msg_object_TX_EXT (char MsgNum);
/***************************************/
////////////////////////////////////////////////////////////////////////////////
// 16-bit SFR Definitions for 'F04x
////////////////////////////////////////////////////////////////////////////////
sfr16 DP = 0x82; // data pointer
sfr16 RCAP2 = 0xCA; // Timer2 reload/capture value
sfr16 RCAP3 = 0xCA; // Timer3 reload/capture value
sfr16 RCAP4 = 0xCA; // Timer4 reload/capture value
sfr16 TMR2 = 0xCC; // Timer2 counter/timer
sfr16 TMR3 = 0xCC; // Timer3 counter/timer
sfr16 TMR4 = 0xCC; // Timer4 counter/timer
sfr16 ADC0 = 0xBE; // ADC0 data
sfr16 ADC0GT = 0xC4; // ADC0 greater than window
sfr16 ADC0LT = 0xC6; // ADC0 less than window
sfr16 DAC0 = 0xD2; // DAC0 data
sfr16 DAC1 = 0xD2; // DAC1 data
sfr16 CAN0DAT = 0xD8; // CAN data window
////////////////////////////////////////////////////////////////////////////////
//Global Variables
////////////////////////////////////////////////////////////////////////////////
#define BAUDRATE 115200 // Baud rate of UART in bps
#define SYSCLK 221184000 // Internal oscillator frequency in Hz
typedef unsigned char uchar;
char MsgNum;
int i=0;
uchar SBUFFER[32];
uchar baud[2];
uchar datas[8];
union longint {
unsigned long ID;
struct{uchar hi1;uchar hi0;uchar low1;uchar low0; }bytek;
};
union longint tcflong;
struct TPWK{
uchar *pRXD;
int RXDS;
int RXDW,RXDR;
}PWK;
int Pr,Pw;
int STDID;
////////////////////////////////////////////////////////////////////////////////
// MAIN Routine
////////////////////////////////////////////////////////////////////////////////
void main (void)
{
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
external_osc ();
PORT_Init (); // initialize crossbar and GPIO
UART0_Init (); // initialize UART0
////////////////////////////////////////////////////////////////////////////////
//串口接收缓存区分配
////////////////////////////////////////////////////////////////////////////////
UART0_set();
////////////////////////////////////////////////////////////////////////////////
//Clear CAN RAM
////////////////////////////////////////////////////////////////////////////////
clear_msg_objects();
EA = 1; //IE.7开放所有中断
////////////////////////////////////////////////////////////////////////////////
//Loop and wait for interrupts
////////////////////////////////////////////////////////////////////////////////
while (1)
{
data_DCM();
};
}
////////////////////////////////////////////////////////////////////////////////
// Initialization Subroutines
// This routine initializes the system clock to use the external oscillator
// at 22.1184 MHz.
////////////////////////////////////////////////////////////////////////////////
void external_osc (void)
{
int n; // local variable used in delay FOR loop.
SFRPAGE = CONFIG_PAGE; // switch to config page to config oscillator
OSCXCN = 0x77; // start external oscillator; 22.1 MHz Crystal
// system clock is 22.1 MHz / 2 = 11.0592 MHz
// OSCXCN = 0x67; // system clock is 22.1 MHz
for (n=0;n<255;n++); // delay about 1ms
while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
CLKSEL |= 0x01; // switch to external oscillator
}
////////////////////////////////////////////////////////////////////////////////
// PORT_Init
// This routine configures the crossbar and GPIO ports.
////////////////////////////////////////////////////////////////////////////////
void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // set SFR page
XBR0 = 0x04; //Enable UART0
XBR1 = 0x00;
XBR3 = 0x80; //Configure CAN TX pin (CTX) as push-pull digital output
XBR2 = 0x44; // Enable crossbar and weak pull-up
P0MDOUT |= 0x05; // Set TX1 pin to push-pull
//P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
////////////////////////////////////////////////////////////////////////////////
// UART0_Init
//
// Configure the UART1 using Timer1, for <baudrate> and 8-N-1.
////////////////////////////////////////////////////////////////////////////////
void UART0_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = UART0_PAGE;
SSTA0 = 0x1A;
SCON0 = 0x50; // SCON0: mode 1, 8-bit UART, enable RX 忽视停止位
SFRPAGE = TMR3_PAGE;
TMR3CN = 0x00; // Stop Timer3; Clear TF3;auto-reload mode; timer function:t3m1:t3m0;
TMR3CF = 0x08; // use SYSCLK as timebase
//RCAP3 = 0xfdc0; // br=1200
RCAP3 = 0xFFB8; // br=9600
TMR3 = RCAP3; // set to reload immediately
EIE2 &= ~0x01; // disable Timer3 interrupts
TR3 = 1; // start Timer3
SFRPAGE = UART0_PAGE;
TI0 = 0; // Indicate TX1 NO ready
PS=1; //将UART0优先级设置为高
ES0=1; //允许UART0中断
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
////////////////////////////////////////////////////////////////////////////////
//串口接收缓存区分配
////////////////////////////////////////////////////////////////////////////////
void UART0_set(void)
{
PWK.RXDS=0x001F;
PWK.pRXD=&SBUFFER[0];
PWK.RXDR=PWK.RXDW=0;
}
////////////////////////////////////////////////////////////////////////////////
//UART数据解析
////////////////////////////////////////////////////////////////////////////////
void data_DCM(void)
{
unsigned long temp;
struct TPWK *pwk;
static uchar cmd[16];
static int cnt=0,STAT=0,state,CN,XTD;
pwk=&PWK;
Pw=pwk->RXDW;
Pr=pwk->RXDR;
while(Pr!=Pw){
switch(STAT){
case 0:
cmd[0]=pwk->pRXD[Pr];
if(cmd[0]=='$'){
STAT=1;
cnt=0;
}break;
case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -