📄 main.c
字号:
/************************************************************************************
* Copyright (c) 2004,西安铭朗电子科技有限责任公司
* All rights reserved.
*
* 文件名称: main.c
* 文件标识: none
* 适用器件: C8051F040
*
* 摘 要: 本文件是串口0、1测试程序,将跳线器JP7、JP11短接。使用外部22.1184MHz晶振。
* 功能:Uart驱动程序,包括初始化、波特率设置,单字节发送接收、字符串发送接受等。
* 程序运行时向PC机发送"WWW.MLARM.COM";接收到PC机的数据后,再将该数据发送
* 回PC机。按开发板上键盘,将该键值发送到PC机.串口调试最好应用支持中文格式
* 的串口调试助手,否则不能正常显示。
*
* 当前版本:1.2
* 作 者:张宁强
* 完成日期:2006年1月10日
*
* 历史版本:1.0
* 原作者 : 李林利 卢阳
* 完成日期:2005年6月1日
*************************************************************************************/
/************************************************************************************/
// 引用外部头文件
#include "c8051f040.h"
#include "Const.h"
#include "uart.h"
#include "delay.h"
//sbit LED=P3^7;
// 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
////////////////////////////////////////////////////////////////////////////////
//Global Variables
////////////////////////////////////////////////////////////////////////////////
//#define QUENEUART 4
//#define QUENECAN 8 //两个缓存队列的数组大小,用常量表示,方便修改
//xdata最大可以64K,但是F040有4K+256B的内部RAM,所以此处xdata可取4K范围
//idata为内部256B快速寻址RAM区域 pdata为外部寻址空间 data为idata中的前128B bdata是data中的16B
char data MsgNum,status;
unsigned char xdata CAN_Data[8],UART_Data[4],CAN_Datachannel[64];
unsigned int data pp=0,able1=0,able2=0;
unsigned int data ii,jjj=0;pcan=0,puart=0,puart1=0;canlength=0,func=0,pchanh=0,pchanl=0,channelable=0;
bit bdata nexten=1;
unsigned long data BDR;
sbit LED = P1^3;
sfr16 CAN0DAT = 0xD8;
////////////////////////////////////////////////////////////////////////////////
// Function PROTOTYPES
////////////////////////////////////////////////////////////////////////////////
// Initialize Message Object
void clear_msg_objects (void);
void init_msg_object_TX (char MsgNum,ID);
void init_msg_object_RX (char MsgNum,ID);
void start_CAN (void);
void receive_data (char MsgNum);
void CAN_trans (char MsgNum);
/************************************************************************************
// 系统初始化功能子程序
*************************************************************************************/
/************************************************************************************
// 系统初始化功能子程序
*************************************************************************************/
/***********************************************************************************
* 函数名称:SYSCLK_Init;
*
* 函数功能描述:系统时钟初始化,使用外部22.1184MHz晶振作为时钟源,using the PLL;
* This routine initializes the system clock to use an external 22.1184 MHz
* crystal oscillator multiplied by a factor of 9/2 using the PLL as its
* clock source. The resulting frequency is 22.1184 MHz * 8/2 = 88.45 MHz
*
* 输入参数:none;
*
* 返回数据:none;
*
* 注意: none;
************************************************************************************/
void SYSCLK_Init (void)
{
int n; // local variable used in delay FOR loop.
char data SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
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
OSCICN = 0x00; // Disable the internal osc.
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
/***********************************************************************************
* 函数名称:PORT_Init;
*
* 函数功能描述:配置端口初始化,配置交叉开关和端口;
*
* 输入参数:none;
*
* 返回数据:none;
*
* 注意: none;
************************************************************************************/
void PORT_Init (void)
{
char data SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; //Port SFR's on Configuration page
XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull digital output
XBR0 = 0x05; //设置XBR0
XBR1 = 0x14; //设置XBR1
XBR2 = 0x44; //打开交叉开关和弱上拉
P0MDOUT = 0x10; //设置P0口输出
P1MDOUT = 0x00; //设置P1口输出
P1|=0x08;
P3MDOUT = 0xff; //设置P3口输出
P4MDOUT = 0xff; //设置P4为输出口
P5MDOUT = 0x00; //设置P5为输入口
P5 = 0xff;
P6MDOUT = 0xff; //设置P6为输出口
P7MDOUT = 0x3b; //设置P7为输出口,P7.2为数字输入
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
void strcopy(unsigned char *strx,unsigned char *stry)
{
while(*stry)
{
*strx++=*stry++;
}
*strx='\0';
}
/************************************************************************************
// 主循环程序
*************************************************************************************/
void main(void)
{
unsigned char data i;
char command[3];
WDTCN=0xDE; //禁止看门狗定时器
WDTCN=0xAD;
PORT_Init();
SYSCLK_Init();
BDR=115200; //初始默认的波特率
LED=~LED;
for(i=1;i<5;i++){
LED=0;
Delay_ms(50);
LED=1;
Delay_ms(50); }
Uart1_Init(BDR);
clear_msg_objects();
//这是主机节点的配置
init_msg_object_TX (0x0A,0); //10号信箱用于发送广播消息,ID=0 最高优先级
init_msg_object_RX (0x01,1); //1号信箱负责接收 1号节点的消息 优先级1
init_msg_object_RX (0x02,2); //1号信箱负责接收 2号节点的消息 优先级2
init_msg_object_RX (0x03,3); //1号信箱负责接收 3号节点的消息 优先级3
init_msg_object_RX (0x04,4); //1号信箱负责接收 4号节点的消息 优先级4
init_msg_object_RX (0x05,5); //1号信箱负责接收 5号节点的消息 优先级5
EIE2 |= 0x20; //允许CAN0中断
EIP2 |= 0x20; //设置CAN0中断优先级"高",在UART1_Init()中已设置UART1中断低优先级
start_CAN();
ET2=1; //TIMER2 INTERRUPT ENABLE
EA = 1;
command[0] = 0;
command[1] = 0;
command[2] = 0;
while(1)
{
pp=0;
Uart1_ReceiveLong(command);
Uart1_ReceiveLong(command);
jjj=1;//判断确实来了命令
UART_Data[puart++]='*';//'*'表示来的是命令不是数据
while (pp<3)
{
UART_Data[puart++]=command[pp]; //往下甩24位命令
pp++;
}
if((command[1] & 0x07) == 0x07)//判断目前需要8个通道一起测量,即需要开辟8字节空间数组CAN_Datachannel[64]
channelable = 1;
if(command[0]==0xf2)//主节点复位
{
//强制复位
char SFRPAGE_SAVE = SFRPAGE; // Save SFRPAGE
SFRPAGE = RST_PAGE;
RSTSRC |= 0x01;//将硬件上电复位位设为1
SFRPAGE = SFRPAGE_SAVE;
}
while(able1)//收到8字节数据才允许转发;或者是需要8通道一起传送时收到64字节数据
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -