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

📄 fjv14.c

📁 一本关于控制系统仿真的书的程序 1、文件夹1中的程序是书中的一些仿真。 2、文件2中的是最近做的预测控制、PID控制及逻辑控制的对比综合研究。 3、文件夹3中是与maltab通信的数据采集板的设
💻 C
📖 第 1 页 / 共 2 页
字号:
//m8L,4M晶振,波特率2400
 #include "iom8v.h"
 #include"macros.h"
 #include"stdio.h"
//控制DA的cs位
 #define set_cs  PORTB |= (1<<PB2)     
 #define clr_cs  PORTB &= 0b11111011   

 #define IO_PB0  0x00
 #define IO_PB1  0x01
 #define IO_PB4  0x04
 #define IO_PD5  0x05
 #define IO_PD6  0x06
 #define IO_PD7  0x07
        
//定义全局变量-------------------------------
 unsigned int AD_value10;//ad采集值10位。
 
 
 //------------------------------------------
 unsigned int  ADC_filter(void);
 void init_devices(void);
 unsigned char USART_Recive(void);
void USART_Transmit(unsigned char tdata);
void ADC_Start(void);
unsigned int ADC_Value (unsigned char adc_channel);
void DAC_5617_10(unsigned char dac_dataH,unsigned char dac_dataL,unsigned char dac_channel);
void SPI_Transmit(unsigned char dac_data);
unsigned char  SPI_Compare(unsigned char data,unsigned char mark);
void delay_1ms(void);
unsigned char Strcat(unsigned char s1,unsigned char s2);
void IO_out(unsigned char IO_data,unsigned char IO_channel);
unsigned char IO_in (unsigned char IO_channel);

/**************************************************************************/
void port_init(void)
{
      PORTB = 0xFF;//确保复位电平是确定的,输入、上拉
      DDRB  = 0x00;
      PORTC = 0xFF;
      DDRC  = 0x00;
      PORTD = 0xFF;
      DDRD=0x00;
}
/********************************************************************/
//Watchdog initialize
// prescale: 512K 0.52s
void watchdog_init(void)
{
 WDR(); //this prevents a timout on enabling
 WDTCR = 0x0D; //WATCHDOG ENABLED - dont forget to issue WDRs
}
/*********************************************************************/
//关闭看门狗
void WDT_off(void)
{
    _WDR();
	WDTCR |= (1<<WDCE)|(1<<WDE);
	WDTCR = 0x00;
}
/**************************************************************************/
void uart0_init(void)
{
 	 UCSRB=(1<<RXEN)|(1<<TXEN);//发送接收使能
 	 UCSRC=(1<<UMSEL);//选择异步发送模式
 	 UBRRL = 0x33;//设置波特率低位4m4800
	 UBRRH = 0x00; //设置波特率高位
 	 UCSRA = 0x18;  //接收、发送数据
 	 UCSRC =(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位数据+1位STOP位
}

/************************************************************************/
void  spi_init(void)
{	
       //PB2为CS端。PB3为MOSI端。PB5为SCK端。
	 // PORTB=(1<<PB2)|(1<<PB3)|(1<<PB5);//SPI端口初始化.慎用<<置1。将会影响其他位。
 	  DDRB= (1<<DDB2)|(1<<DDB3)|(1<<DDB5);//SPI端口初始化
	  SPSR=0x01;//SPI状态寄存器初始化
   	  SPCR=0x58; //SPI使能 
}
/*************************************************************************/
//ADC initialize
// Conversion time: 52uS

void adc_init(void)
{
   PORTC =(0<<PC0)|(0<<PC1)|(0<<PC2)|(0<<PC3) ;//关闭上拉电阻
   ACSR  = 0x00;//与模拟比较器控制
	//ACSR =(1<<ACD);//关闭模拟比较器
   ADMUX=0x00;//设定AD选择寄存器,片外基准。ch1通道(对应芯片ADC0)。数据右对齐。	
   ADCSRA = 0x00;  //disable adc
   ADCSRA=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(0<<ADPS1) ;//16分频,使能AD,开启中断。还没开始转换。
   
 
 }
/*************************************************************************/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
 //conversion complete, read value (int) using...
     AD_value10 = ADCL;            //Read 8 low bits first (important)
     AD_value10|=(unsigned int)ADCH << 8; //read 2 high bits and shift into top byte
	
}
/*************************************************************************/
void init_devices(void)
{
   CLI(); //关闭所有中断
   port_init();//端口初始化
   watchdog_init();
   uart0_init();//串行通信初始化
   adc_init();//AD初始化
   spi_init();//SPI初始化
   MCUCR = 0x10;//ADC噪声抑制模式。
   GICR  = 0x00;//关外部中断
   SEI();
}
/**************************************************************************/
/**************************************************************************/
void main( )
{
  
  unsigned char charry[5];
  unsigned char y;
  unsigned char temp8;
  unsigned int temp10;//接收10位的数据,如AD等。
  unsigned int i;
  unsigned int m;
  init_devices();//初始化
  while(1)
	{
	 charry[0]=0;//初始化
	 charry[1]=0;
	 charry[2]=0;
	 charry[3]=0;
	 charry[4]=0;
	 y=0;
	 temp8=0;
	 temp10=0;
	 m=0;
	 
	 WDT_off();//等待第一个接收数据。
	 y=USART_Recive();
	 charry[0]=y;//接收数据
	 watchdog_init();//打开看门狗,防止串行数据中断而无限等待。
	 for(i=1;i<5;i++)
	      { 
		    y=USART_Recive();
			charry[i]=y;//接收数据
		  }
     
	  if (charry[0]==0x55)
		 {
	  	
		    //功能选择判断
		      switch (charry[1])
		        {
		           case 0x03:  //如果为00则启动IO输出
				IO_out(charry[3],charry[2]);	//确定输出数据和端口
		                break;
		           case 0x02:  //如果为00则启动IO输入
				temp8=IO_in(charry[2]);//启动IO转换,确定通道数。
                      		USART_Transmit(temp8);//启动串口发送IO数据(第四位)
                      		//USART_Transmit(0x00);//启动串口发送IO数据(第五位) 
		                break;
		           case 0x01://如果为01则启动AD转换
				 temp10=ADC_Value(charry[2]);//启动AD转换,确定通道数。
				 m=temp10;
                                 temp8=(unsigned char)(m>>8);
                    		 USART_Transmit(temp8);//启动串口发送数据(高8位)
                    		 temp8=(unsigned char)temp10;
				 USART_Transmit(temp8);//启动串口发送数据(低8位)
			         break;
		           case  0x10://如果为10则启动DA转换
                                 DAC_5617_10(charry[3],charry[4],charry[2]);	//启动DA5716		
				 break;
			   case 0x11://如果为11则先启动DA再启动AD转换
				     DAC_5617_10(charry[3],charry[4],0x01);	//启动DA5716	
					 asm("NOP");
				     temp10=ADC_Value(0x01);      //启动AD转换,AD/DA使用相同通道1。
		             m=temp10;
                     temp8=(unsigned char)(m>>8);
                     USART_Transmit(temp8);//启动串口发送数据(高8位)
                     temp8=(unsigned char)temp10;
				 	 USART_Transmit(temp8);//启动串口发送数据(低8位)
                      break;
			  default:break;
		        }	 
	       }
          
     } 	  
}
/**************************************************************************/
//串口接收数据
unsigned char USART_Recive(void)
    { 
	unsigned char y;	
	//等待接收数据
	while(!(UCSRA&(1<<RXC)));
		y=getchar();  //接收数据
		
   return y;
   }
/*******************************************************************/
//串口发送数据
void USART_Transmit(unsigned char tdata)
{
//等待数据寄存器空
	UDR=tdata;
	while(!(UCSRA&(1<<UDRE)))
	 ;
	
	
}
/******************************************************************/
/*******************************************************************
 函数功能:AD数据、通道采集,10位精度。
 入口参数:adc_channel通道选择。
 出口参数:AD采集的数据
 说明:此处可以加入中值滤波程序。使用ADC降噪中断方式
*******************************************************/
unsigned int ADC_Value (unsigned char adc_channel)
{
  unsigned int temp;
  temp=0;
  switch (adc_channel)
       {
           case 0x01: //如果为00则启动CH1通道
               ADMUX=0x00;//寄存器后4位对应通道。0代表CH1通道。
               temp=ADC_filter();
               break;   
          case 0x02:  //如果为01则启动CH2通道
               ADMUX=0x01;//寄存器后4位对应通道。1代表CH2通道。
               temp=ADC_filter();  
		       break; 
          case 0x03:  //如果为10则启动CH2通道
               ADMUX=0x02;//寄存器后4位对应通道。2代表CH3通道。
               temp=ADC_filter();  
		       break;  
          case 0x04:  //如果为00则启动CH1通道
               ADMUX=0x03;//寄存器后4位对应通道。3代表CH4通道。
               temp=ADC_filter(); 
		       break;         	
       	   default:break;
       	}
  return temp;
}  
/*******************************************************************
 函数功能:首先采集数据,然后三点中值滤波。同时解决第一次采集不准问题。
 入口参数:无
 出口参数:outdata,滤波后的结果
 说明:
*******************************************************/
unsigned int  ADC_filter(void)
      {
            unsigned int a;
            unsigned int outdata;
            unsigned int temp[2];
            temp[0]=0;
	    temp[1]=0;
	    temp[2]=0;
            ADC_Start();//丢弃第一次结果。
            AD_value10=0;//采集数据前先将变量清零。避免上一次的干扰。
            ADC_Start();
            temp[0]=AD_value10;//AD转换结果
            ADC_Start();
            temp[1]=AD_value10;//AD转换结果
            ADC_Start();
            temp[2]=AD_value10;//AD转换结果
            //下面的程序让数组从小到大排列
            if (temp[0]>temp[1])
               {
               	  a=temp[1];
                  temp[1]=temp[0];
                  temp[0]=a;

⌨️ 快捷键说明

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