⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于c8051f040一个多机通讯程序,开发环境keil
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************************
*  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 + -