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

📄 main.c

📁 发开环境 CCS 基于DSP2407的SPI模块程序
💻 C
字号:
#include   "ZCY_DSP_0508.h"

#include <math.h>
#include <stdlib.h>
int result1;
int pid_feb;
int pid_ref=0;
int pid_kp=1000;
int pid_ki=333;
int pid_kd=1000;
int pid_error,pid_err1=0,pid_err2=0;
int uo=220;
int delt_u,delt_ud;
int pid_up=0; 
int new_result;
int RData,a;
#define DUMMY_DATA 0
void Sys_init()
{
	asm(" clrc CNF");
	asm(" clrc SXM");
	asm(" setc OVM");
	*SCSR1 = 0x00Fd;
	*SCSR2 = 0x000f;
/*
 bit 15-6      0's:    reserved
 bit 5         0:      do NOT clear the WD OVERRIDE bit
 bit 4         0:      XMIF_HI-Z, 0=normal mode, 1=Hi-Z'd
 bit 3         1:      disable the boot ROM, enable the FLASH
 bit 2     no change   MP/MC* bit reflects state of MP/MC* pin
 bit 1-0      11:      11 = SARAM mapped to prog and data
*/


/*** Disable the watchdog timer ***/
    *WDCR  = 0x00E8;
/*
 bits 15-8     0's:     reserved
 bit 7         1:       clear WD flag
 bit 6         1:       disable the dog
 bit 5-3       101:     must be written as 101
 bit 2-0       000:     WDCLK divider = 1
*/
/*** Setup external memory interface for LF2407 EVM ***/
    WSGR = 0x0000;
/*
 bit 15-11     0's:    reserved
 bit 10-9      00:     bus visibility off
 bit 8-6       001:    1 wait-state for I/O space
 bit 5-3       000:    0 wait-state for data space
 bit 2-0       000:    0 wait state for program space
*/
	*IMR = 0x0000;
	*IFR = 0xffff;		//	清除中断标志
	*IMR = 0x0001;
	*EVAIFRA = 0xFFFF;                  /* clear all EVA group A interrupts */
    *EVAIFRB = 0xFFFF;                  /* clear all EVA group B interrupts */
    *EVAIFRC = 0xFFFF;                  /* clear all EVA group C interrupts */
    *EVAIMRA = 0x0000;                  /* disable desired EVA group A interrupts */
    *EVAIMRB = 0x0000;                  /* disable desired EVA group B interrupts ENABLE TIME2*/
    *EVAIMRC = 0x0000;                  /* disable desired EVA group C interrupts */

    *EVBIFRA = 0xFFFF;                  /* clear all EVB group A interrupts */
    *EVBIFRB = 0xFFFF;                  /* clear all EVB group B interrupts */
    *EVBIFRC = 0xFFFF;                  /* clear all EVB group C interrupts */
    *EVBIMRA = 0x0000;                  /* disable desired EVB group A interrupts */
    *EVBIMRB = 0x0000;                  /* disable desired EVB group B interrupts */
    *EVBIMRC = 0x0000;                  /* disable desired EVB group C interrupts */	
}

void timer1_init()
{
	*GPTCONA = 0x0100;	//ok    // T1递增,T1周期中断启动ADC
	*EVAIFRA|= 0xFFFF; //OK
	*EVAIMRA|= 0x0080;	//ok		// 使能T1周期溢出标志
	
	*T1CON   = 0x1400;//OK			// 连续增,16分频,内部时钟,禁止比较 (@@@@@@@@此处已启动定时器,破坏程序@@@@@@@@)
	
	*T1PR    = 0xfa;//0x1330;;;;0x1400;;;0x1330;;0xFF00;//OK			// 40us   0x9C4=1000us,0xFF=100us,0x96=60us
	   //0x0FA=10K
	*T1CNT = 0x00;//OK				// T1计数器清零
}

void adc_init()
{
	*ADCTRL1 = 0x4000; 				// .14  写1复位ADC
	*ADCTRL2 = 0x4000;				// .14  写1复位排序器
	NOP;
	*ADCTRL1 = 0x2310;				// .14 写0结束复位
									// .13~12  = 10 	仿真悬挂时完成本次转换
									// .11~8   = 0011 
									// .7  CPS = 0     匹配??欧内阻,转换时间=  ???
									// .6      = 0     启停模式
									// .5      = 0     高优先级
									// .4      = 1	   级联模式
									// .3      = 0	   校准禁止
									// .2      = 0
									// .1      = 0
									// .0      = 0     禁止自测试
 
	*MAXCONV = 1;//2*CH_NUM;			// 通道数
	*CHSELSEQ1 = 0x0001;
	*CHSELSEQ2 = 0x0000;
	*CHSELSEQ3 = 0x0000;
	*CHSELSEQ4 = 0x0000;
	*ADCTRL2   = 0x0700;			// .15     = 0	EVB事件无效
									// .14	   = 0	停止复位排序器
									// .13		=0  清除一个悬挂的SOC请求,只读1位
									// .12		=0  只读位
									// .11~10  = 01 允许中断
									// .9       = 1 清除中断标志位
									// .8		= 1 允许EVA事件启动SEQ1
									// .7		= 0 外部信号无效
									// .6		= 0	无效
									// .5		= 0  
									// .4		= 0
									// .3~2		= 00
									// .1		= 0
									// .0		= 0
}

void delay(unsigned int period)
{
    int periodi, periodj;
    
    for(periodi=0; periodi<period; periodi++)
    {
        for(periodj=0; periodj<period>>1; periodj++);
    }
}



void get_sensor()
{
	 result1=(*RESULT1>>6)-257;
	 pid_feb = result1;
}

int get_error()
{
	 long temp_e;
	 temp_e=pid_feb-pid_ref;  //pid_feb 必须控制在Q15格式 也就是传感器进来的数据
		 		          //pid_ref	 此处为0
	 if(temp_e>32768)
	{
	 pid_error =(temp_e>>1);	
	}
else      pid_error = temp_e;
return   pid_error;
}

void pid_p()
{
	 long temp0;
	 temp0= pid_kp * (pid_error- pid_err1);
	 pid_up= (temp0>>11)+uo;
}
void pid_i()
{
	 long temp1;
	 temp1= pid_ki * pid_error;
	 delt_u=temp1>>15;
  	 pid_up+= delt_u ;
}

void pid_d()
{
	 long temp2;
	 temp2=pid_kd*( pid_error-2* pid_err1+ pid_err2);
	 delt_ud= (temp2>>15);
	 pid_up+= delt_ud;
}

/*void pid_i()
{
			temp=(k*result1);
			if(temp<0)
				{
				currentvalue=temp>>15;
				}
			else currentvalue=temp>>15;
			//if(result1>=400)
			 sum+=currentvalue;
			 if(sum>819)
			 	{
			 		sum=819;
			 	}
			 else if(sum<0)
			 	{
			 		sum=0;
			 	}
			 //else sum-=(4*currentvalue);
			delay(10);	
}*/
void pid_calc()
{
	 get_error();
	 pid_p();
	 pid_i();
	 pid_d();
	 if(pid_up >819)
	 {
	 	pid_up =819;
	 }
	 else if(pid_up<0)
	 {
	 	pid_up =0;
	 }
}

void pid_update()
{
	pid_err2=pid_err1;
	pid_err1=pid_error;
	
}
void adc_start()
{
	//*PFDATDIR=0x4040;
	*PFDATDIR=0x4000;
	*SPITXBUF=0x8D00;
	a=*SPIRXBUF;//*SPITXBUF=0x00;	
}
void spi_read()
{
	int RData;
	*SPITXBUF = DUMMY_DATA;
	//while(!(*SPISTS & 0X40));
	//*SPITXBUF = DUMMY_DATA<<8;
	while(!(*SPISTS & 0X40));
	RData=*SPIRXBUF ;//& 0X00FF;
	
}

void spiinitial()
{
	
	*MCRB = 0x3C;
	*SPICCR=0x000f;
	*SPICTL=0x0006;
	*SPIBRR=0x0013;
	*SPICCR=*SPICCR|0x0080;
	//*SPICCR=0xcf;
	*SPIPRI=0x0030;
	//*SPITXBUF=0x8d00;
}

void interrupt c_int1()
{
	switch(*PIVR)
	{
		case 0x0004:					//ADC高优先级中断
			{
			asm("	clrc SXM");
			/*result1 = (*RESULT1>>6)-285450;
			pid_i();*/
			//get_sensor();
			adc_start();
			spi_read();
			new_result=(((long)a<<16)+(long)RData)>>6;
			pid_calc();
			pid_update();
			DA_PORT2 = 5*pid_up;
			//LED = 0xff;
			//delay(10);
			//LED = 0x00;
			//LED = 0x00;
			break;
			}
		default:;	
	}
	*ADCTRL2 |= 0x4200;	
	*IFR|=0x0001;
	EINT;
}

void main(void)
{
	DINT;
	Sys_init();
	spiinitial();
	*PFDATDIR=0x4040;
	timer1_init();
	adc_init();
	EINT;
	*T1CON=*T1CON|0x0040;
	
	while(1)
	{
		;//LED = 0x00;
	}
	
}
void interrupt nothing()
{
	EINT;
}

void interrupt PHANTOM()
{
	EINT;
}

⌨️ 快捷键说明

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