📄 lcdc_040.c
字号:
////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////
#include <c8051f040.h> // SFR declarations
// CAN Protocol Register Index for CAN0ADR, from TABLE 18.1 of the C8051F040
// datasheet 212页表18.2 寄存器索引号
////////////////////////////////////////////////////////////////////////////////
#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
////////////////////////////////////////////////////////////////////////////////
//Global Variables
////////////////////////////////////////////////////////////////////////////////
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
union intchar{
uint tempval;
struct{uchar hi;uchar low;}bytek;
};
bit isnewdata;
data uchar temppage;
data uchar status;
xdata uchar sdata[8]={0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
uchar xdata rdata[8];
char MsgNum;
int i;
bit lcdtoken=0;
sfr16 CAN0DAT = 0xD8;//CAN数据寄存器的低地址
#define uchar unsigned char
#define uint unsigned int
uchar xdata virt_port;
bit SPI_BUSY;
sbit LcdCs=P2^5;
////////////////////////////////////////////////////////////////////////////////
// Function PROTOTYPES
////////////////////////////////////////////////////////////////////////////////
// Initialize Message Object
void clear_msg_objects (void);
void init_msg_object_TX (char MsgNum,uint id);
void init_msg_object_RX (char MsgNum,uint id);
void start_CAN (void);
void external_osc (void);
void config_IO (void);
void stop_CAN (void);
void delay(int tim);
void receive_data(uchar MsgNum,char *p,char len);
void transmit(char MsgNum,char *p,char len);
void spi_init();
void writecode(uchar ins);
void writedata(uchar d);
void lcdchar (void);
void lcdinit();
void writelcd(uchar spi_data);
/*void delay(uint d)
{uint i,j;
for(i=0;i<d;i++);
{
for(j=10;j>0;j--);
}
}
*/
////////////////////////////////////////////////////////////////////////////////
// MAIN Routine
////////////////////////////////////////////////////////////////////////////////
#define LEN 8
main () {
//char vid;
// disable watchdog timer
//xdata uchar ss1[8]={0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};
//xdata uchar ss2[8]={0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28};
WDTCN = 0xde;
WDTCN = 0xad;
//configure Port I/O
config_IO();
// switch to external oscillator
external_osc();
spi_init();
////////////////////////////////////////////////////////////////////////////////
// Configure CAN communications
//
// IF1 used for procedures calles by main program
// IF2 used for interrupt service procedure receive_data
//
// Message Object assignments:
// 0x02: Used to transmit commands to toggle its LED, arbitration number 1
//
////////////////////////////////////////////////////////////////////////////////
// Clear CAN RAM
clear_msg_objects();
// Initialize message object to transmit data
init_msg_object_RX (0x04,2);
// Initialize message object to receive data
init_msg_object_TX (0x02,1);
//init_msg_object_TX (0x03,4);
// Enable CAN interrupts in CIP-51
EIE2 = 0x20;
EIE1= 0x01;
//Function call to start CAN
start_CAN();
//Global enable 8051 interrupts
EA = 1;
//Loop and wait for interrupts
while (1)
{
if(lcdtoken==1)
{
lcdtoken=0;
lcdinit();
lcdchar();
for(i=0;i<1000;i++)
delay(1000);
}
// transmit(3,ss2,LEN);
}
}
////////////////////////////////////////////////////////////////////////////////
// Set up C8051F040
////////////////////////////////////////////////////////////////////////////////
// Switch to external oscillator
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.05 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
}
void config_IO (void)//I/O端口初始化
{
SFRPAGE = CONFIG_PAGE; //Port SFR's on Configuration page
P0MDOUT=0xff;
XBR0 = 0x06;
XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull digital output
// P1MDOUT |= 0x40; // Configure P1.6 as push-pull to drive LED
XBR2 = 0x40; // Enable Crossbar/low ports
}
////////////////////////////////////////////////////////////////////////////////
//CAN Functions
////////////////////////////////////////////////////////////////////////////////
//Clear Message Objects
void clear_msg_objects (void)//将所有消息清0
{
SFRPAGE = CAN0_PAGE;
//向CAN 相关寄存器写入数据的方法
//间接访问方式 地址索引寄存器指向索引号,相应数据写入数据寄存器
CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1
CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to Msg Obj
for (i=1;i<33;i++)//32个消息对象
{
CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
CAN0DATL = i;//Message Number 写入
}
}
//Initialize Message Object for RX
void init_msg_object_RX (char MsgNum,uint id)
{ uint temp;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00b8; // Set to WRITE, and alter all Msg Obj except ID MASK
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to "0"
CAN0DAT = 0x8004; // and data bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register标准桢
CAN0DAT = 0x0000; // Set arbitration1 ID to "0"
temp=id<<2;
temp&=0x1fff;
temp|=0x8000;
// Arb2 high byte:Set MsgVal bit, no extended ID,
// Dir = RECEIVE
CAN0DAT = temp; // Msg Cntrl: set RXIE, remote frame function disabled
CAN0DAT =0x0488;
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DATL = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
}
//Initialize Message Object for TX
/*void init_msg_object_TX (char MsgNum,unsigned int id)
{ uint temp;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B3; // Set to WRITE, & alter all Msg Obj except ID MASK bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to highest priority
temp=id<<2; // Autoincrement to Arb2 high byte:
temp&=0x1fff; // Set MsgVal bit, no extended ID, Dir = WRITE
temp|=0xa000;
CAN0DAT = temp; // Msg Cntrl: DLC = 1, remote frame function not enabled
CAN0DAT=0x0088;
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}
*/
//Start CAN
void start_CAN (void)
{
/* Calculation of the CAN bit timing :
System clock f_sys = 22.1184 MHz/2 = 11.0592 MHz.
System clock period t_sys = 1/f_sys = 90.422454 ns.
CAN time quantum tq = t_sys (at BRP = 0)
Desired bit rate is 1 MBit/s, desired bit time is 1000 ns.
Actual bit time = 11 tq = 996.65ns ~ 1000 ns
Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381%
CAN bus length = 10 m, with 5 ns/m signal delay time.
Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns
(maximum loop delay between CAN nodes)
Prop_Seg = 5 tq = 452 ns ( >= 400 ns).
Sync_Seg = 1 tq
Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq
Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq
SJW = (min(Phase_Seg1, 4) tq = 2 tq
TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6
TSEG2 = (Phase_Seg2 - 1) = 2
SJW_p = (SJW - 1) = 1
Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -