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

📄 974040.c

📁 ad974同c8051f040spi通讯的例程。实现了16位对8位spi控制器的操作。使用时须将程序中can和显示等模块剔除(及其定义)即可编译通过。此程序是产品中实用的。只是将算法剔除了。
💻 C
字号:
#include<candeal0.h>	//包含文件
#include<kk1.c>			//包含显示模块


sbit busy 		= P0^7;	//AD忙
sbit CS   		= P2^2;	//AD片选
sbit RC   		= P2^3;	//AD读写控制
sbit A0   		= P2^4;	//AD选址0
sbit A1   		= P2^5;	//AD选址1
sbit WR   		= P2^6;	//AD混合多路转换
sbit PWRD 		= P2^7;	//AD休眠

sbit POWERLED	= P3^7;	//电源灯
sbit T2LED		= P3^6;	//进T2中断
sbit SPILED		= P3^4;	//SPI工作
sbit CANLED		= P3^0;	//CAN指示灯;定义位操作


sfr16 TMR2		=0xcc;
sfr16 RCAP2		=0xca;	//定义特殊寄存器地址


data union tcfint16
					{
						uint 	myword;
						struct	{uchar hi;uchar low;}bytes;
					}	myint16;		//myint16联合定义


union 	tcfint16 	ad3,ad4;			//AD通道3、4值,可联合操作
data 	uint 		ledflag=1,val=0,test,temp=0,temphi=0,templow=0;
										//显示完成标志、其它中间变量
data	uint		fwdata=0,gddata=0;	//


void Ad();						//AD						
void canini();					//CAN初始化
void dac0_cfg(uchar cfg);		//DAC0初始化
void dac1_cfg(uchar cfg);		//DAC1初始化
void dac0_updata(uint val);		//DAC0
void dac1_updata(uint val);		//DAC1
void Oscillator_Init();			//晶振设置
void SPI_Init();				//SPI
void t2_ini();					//T2
void xianshi(unsigned int fwdata,unsigned int gddata);
								//显示数据;程序声明

void Ad()//AD及SPI通讯程序
{
unsigned int j;
	PWRD=0;
	PWRD=1;
	PWRD=0;
	WR=1;
	CS=1;
	RC=1;
	CS=0;
	RC=0;
	RC=1;
	A0=0;
	A1=1;
	WR=0;
	WR=1;							//AD转换启动
	test=1;
	while(test)test=~busy;			//测试检查转换是否完毕
	SFRPAGE=0X00;
	SPI0DAT=0x00;
	ad3.bytes.low=SPI0DAT;
	for(j=0;j<100;j++)				//等待,之后读取高字节
	SPI0CN=0x01;
	SPI0DAT=0x00;
	ad3.bytes.hi=SPI0DAT;
	SPI0CN=0X01;
	if(ledflag)fwdata=ad3.myword;

for(j=0;j<120;j++)					//等待,之后启动下次AD操作

	WR=1;
	CS=1;
	RC=1;
	CS=0;
	RC=0;
	RC=1;
	A0=1;
	A1=1;
	WR=0;
	WR=1;
	test=1;
	while(test)test=~busy;
	SFRPAGE=0X00;
	SPI0DAT=0x00;
	ad4.bytes.low=SPI0DAT;
	for(j=0;j<100;j++)
	SPI0CN=0x01;
	SPI0DAT=0x00;
	ad4.bytes.hi=SPI0DAT;
	SPI0CN=0X01;
	if(ledflag)gddata=ad4.myword;






	if(val==1)SPILED=~SPILED;		//SPI指示灯闪烁,时间由主程序中val确定

}



void canini(){//CAN初始化程序
	clear_msg_objects();
	init_msg_object_RX (0x04,2);	//初始化发送
	init_msg_object_TX (0x02,1);
	EIE2 |= 0x20;
	SFRPAGE = CAN0_PAGE;
	CAN0CN=0X41;
	CAN0ADR=BITREG;
	CAN0DAT=0x1c01;					//7b6;//011c;//34c0;//调波特率
	start_CAN();
}


void config(void)//F040硬件配置子程序
{
 WDTCN=0x07;
 WDTCN=0xDE;
 WDTCN=0xAD;   //看门狗禁止
 
 SFRPAGE=0x0F;

 XBR0=0x02;    //使能SPI
 XBR1=0x14;    //使能INT0,INT1
 XBR2=0x00;    //全局禁止弱上拉,交叉开关使能清零
 XBR3=0x00;    //CAN发送为漏极开路

 SFRPAGE=0x0F;

 P0MDOUT=0x00; //SCK,MISO,/INT0,/INT1为开漏输出 
 P1MDOUT=0x00; 
 P2MDOUT=0xff; //推挽方式输出 
 P3MDOUT=0x00; 
 P4MDOUT=0xff;  
 P5MDOUT=0x00; 
 P6MDOUT=0x00;  
 P7MDOUT=0x00; 

 P1MDIN=0xFF;  //其它所有端口为数字输入 
 P2MDIN=0xFF; 
 P3MDIN=0xFF; 
 
 XBR2=0x40;    //交叉开关使能启动

 SFRPAGE=0x0F;

 Oscillator_Init();
}


void dac0_cfg(uchar cfg){//DAC0配置子程序
	SFRPAGE=0X00;
	DAC0CN=cfg;
	REF0CN|=0X03;		 //DAC参考电平只能由VREFD输入
}


void dac1_cfg(uchar cfg){//DAC1配置子程序
	SFRPAGE=0X01;
	DAC0CN=cfg;
	REF0CN|=0X03;		 //DAC参考电平只能由VREFD输入
}


void dac0_updata(uint val){//DAC0更新子程序
	SFRPAGE=0x00;
	myint16.myword=val;		//利用联合体进行快速uint型数据操作
	DAC0L=myint16.bytes.low;
	DAC0H=myint16.bytes.hi; //在直接更新模式下,此时开始更新DAC0输出
}


void dac1_updata(uint val){ //DAC1更新子程序
	SFRPAGE=0x01;
	myint16.myword=val;		//利用联合体进行快速uint型数据操作
	DAC1L=myint16.bytes.low;
	DAC1H=myint16.bytes.hi; //在直接更新模式下,此时开始更新DAC1输出
}	


void Oscillator_Init()//晶振初始化子程序
{
	int i = 0;
    SFRPAGE   = CONFIG_PAGE;
    OSCXCN    = 0x67;
    for (i = 0; i < 4000; i++);  	//Wait about 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    CLKSEL    = 0x01;
    OSCICN    = 0x00;				//时钟的初始化,外晶振16兆赫

//	SFRPAGE   = CONFIG_PAGE;
//	OSCICN    = 0x83;				//内晶振24兆赫
}


void SPI_Init()//SPI初始化子程序
{
    SFRPAGE   = SPI0_PAGE;
    SPI0CFG   = 0x40;
    SPI0CN    = 0x01;
	SPI0CKR   = 0x27;//SPI初始化100K//0x50
}


void t2_ini(){//T2定时器初始化子程序
    SFRPAGE   = TMR2_PAGE;
    TMR2CN    = 0x04;
    RCAP2     = 0xf594;//f594;//2ms定时器2的初始化
}


main()//主程序
{   

	uint i=0;
	config();			//硬件配置
    cshua();
	dac0_cfg(0x80);		//DAC0配置
	dac1_cfg(0x80);		//DAC1配置
	SPI_Init();			//初始化SPI
	t2_ini();			//初始化定时器
	canini();			//CAN初始化
	ET2=1;				//开定时器中断
	EA=1;				//开中断
	
	POWERLED=0;			//电源指示灯亮
	CANLED=0;			//CAN指示灯亮
	
	while(1){xianshi(gddata/11,fwdata/11);}//单片机循环等待中断
}


void T2_ISR() interrupt 5{//T2定时中断
	TF2=0;								//TF2清零
	Ad();								//AD工作
	val++;
	if(val>=250){val=0;T2LED=~T2LED;}	//val每250次闪烁T2指示灯
	dac0_updata(ad3.myword>>4);			//DAC0输出
	dac1_updata(ad3.myword>>4);			//DAC1输出
}


void ISRname (void) interrupt 19//CAN中断

{
	temppage=SFRPAGE;
	SFRPAGE = CAN0_PAGE;
	status = CAN0STA;
		if ((status&0x10) != 0)	{
		CAN0STA&=0xef;
		receive_data (0x04);	} 
	SFRPAGE=temppage;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -